001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 018 package org.apache.commons.configuration; 019 020 import java.util.ArrayList; 021 import java.util.Iterator; 022 import java.util.List; 023 import java.util.Map; 024 025 import org.apache.commons.collections.map.LinkedMap; 026 027 /** 028 * Basic configuration classe. Stores the configuration data but does not 029 * provide any load or save functions. If you want to load your Configuration 030 * from a file use PropertiesConfiguration or XmlConfiguration. 031 * 032 * This class extends normal Java properties by adding the possibility 033 * to use the same key many times concatenating the value strings 034 * instead of overwriting them. 035 * 036 * @author <a href="mailto:stefano@apache.org">Stefano Mazzocchi</a> 037 * @author <a href="mailto:jon@latchkey.com">Jon S. Stevens</a> 038 * @author <a href="mailto:daveb@miceda-data">Dave Bryson</a> 039 * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a> 040 * @author <a href="mailto:leon@opticode.co.za">Leon Messerschmidt</a> 041 * @author <a href="mailto:kjohnson@transparent.com">Kent Johnson</a> 042 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a> 043 * @author <a href="mailto:ipriha@surfeu.fi">Ilkka Priha</a> 044 * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a> 045 * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a> 046 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 047 * @author <a href="mailto:ksh@scand.com">Konstantin Shaposhnikov</a> 048 * @author <a href="mailto:oliver.heger@t-online.de">Oliver Heger</a> 049 * @version $Id: BaseConfiguration.java 529531 2007-04-17 08:52:41Z ebourg $ 050 */ 051 public class BaseConfiguration extends AbstractConfiguration implements Cloneable 052 { 053 /** stores the configuration key-value pairs */ 054 private Map store = new LinkedMap(); 055 056 /** 057 * Adds a key/value pair to the map. This routine does no magic morphing. 058 * It ensures the keylist is maintained 059 * 060 * @param key key to use for mapping 061 * @param value object to store 062 */ 063 protected void addPropertyDirect(String key, Object value) 064 { 065 Object previousValue = getProperty(key); 066 067 if (previousValue == null) 068 { 069 store.put(key, value); 070 } 071 else if (previousValue instanceof List) 072 { 073 // the value is added to the existing list 074 ((List) previousValue).add(value); 075 } 076 else 077 { 078 // the previous value is replaced by a list containing the previous value and the new value 079 List list = new ArrayList(); 080 list.add(previousValue); 081 list.add(value); 082 083 store.put(key, list); 084 } 085 } 086 087 /** 088 * Read property from underlying map. 089 * 090 * @param key key to use for mapping 091 * 092 * @return object associated with the given configuration key. 093 */ 094 public Object getProperty(String key) 095 { 096 return store.get(key); 097 } 098 099 /** 100 * Check if the configuration is empty 101 * 102 * @return <code>true</code> if Configuration is empty, 103 * <code>false</code> otherwise. 104 */ 105 public boolean isEmpty() 106 { 107 return store.isEmpty(); 108 } 109 110 /** 111 * check if the configuration contains the key 112 * 113 * @param key the configuration key 114 * 115 * @return <code>true</code> if Configuration contain given key, 116 * <code>false</code> otherwise. 117 */ 118 public boolean containsKey(String key) 119 { 120 return store.containsKey(key); 121 } 122 123 /** 124 * Clear a property in the configuration. 125 * 126 * @param key the key to remove along with corresponding value. 127 */ 128 protected void clearPropertyDirect(String key) 129 { 130 if (containsKey(key)) 131 { 132 store.remove(key); 133 } 134 } 135 136 public void clear() 137 { 138 fireEvent(EVENT_CLEAR, null, null, true); 139 store.clear(); 140 fireEvent(EVENT_CLEAR, null, null, false); 141 } 142 143 /** 144 * Get the list of the keys contained in the configuration 145 * repository. 146 * 147 * @return An Iterator. 148 */ 149 public Iterator getKeys() 150 { 151 return store.keySet().iterator(); 152 } 153 154 /** 155 * Creates a copy of this object. This implementation will create a deep 156 * clone, i.e. the map that stores the properties is cloned, too. So changes 157 * performed at the copy won't affect the original and vice versa. 158 * 159 * @return the copy 160 * @since 1.3 161 */ 162 public Object clone() 163 { 164 try 165 { 166 BaseConfiguration copy = (BaseConfiguration) super.clone(); 167 copy.store = (Map) ConfigurationUtils.clone(store); 168 return copy; 169 } 170 catch (CloneNotSupportedException cex) 171 { 172 // should not happen 173 throw new ConfigurationRuntimeException(cex); 174 } 175 } 176 }