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.beanutils; 019 020 import java.lang.reflect.Array; 021 import java.util.Collection; 022 import java.util.Iterator; 023 import java.util.List; 024 025 import org.apache.commons.beanutils.DynaBean; 026 import org.apache.commons.beanutils.DynaClass; 027 import org.apache.commons.configuration.Configuration; 028 import org.apache.commons.configuration.ConfigurationMap; 029 import org.apache.commons.configuration.ConversionException; 030 import org.apache.commons.configuration.SubsetConfiguration; 031 import org.apache.commons.logging.Log; 032 import org.apache.commons.logging.LogFactory; 033 034 /** 035 * The <tt>ConfigurationDynaBean</tt> dynamically reads and writes 036 * configurations properties from a wrapped configuration-collection 037 * {@link org.apache.commons.configuration.Configuration} instance. It also 038 * implements a {@link java.util.Map} interface so that it can be used in 039 * JSP 2.0 Expression Language expressions. 040 * 041 * <p>The <code>ConfigurationDynaBean</code> maps nested and mapped properties 042 * to the appropriate <code>Configuration</code> subset using the 043 * {@link org.apache.commons.configuration.Configuration#subset} 044 * method. Similarly, indexed properties reference lists of configuration 045 * properties using the 046 * {@link org.apache.commons.configuration.Configuration#getList(String)} 047 * method. Setting an indexed property always throws an exception.</p> 048 * 049 * <p>Note: Some of the methods expect that a dot (".") is used as 050 * property delimitor for the wrapped configuration. This is true for most of 051 * the default configurations. Hierarchical configurations, for which a specific 052 * expression engine is set, may cause problems.</p> 053 * 054 * @author <a href="mailto:ricardo.gladwell@btinternet.com">Ricardo Gladwell</a> 055 * @version $Revision: 681804 $, $Date: 2008-08-01 21:58:59 +0200 (Fr, 01 Aug 2008) $ 056 * @since 1.0-rc1 057 */ 058 public class ConfigurationDynaBean extends ConfigurationMap implements DynaBean 059 { 060 /** Constant for the property delimiter.*/ 061 private static final String PROPERTY_DELIMITER = "."; 062 063 /** The logger.*/ 064 private static Log log = LogFactory.getLog(ConfigurationDynaBean.class); 065 066 /** 067 * Creates a new instance of <code>ConfigurationDynaBean</code> and sets 068 * the configuration this bean is associated with. 069 * 070 * @param configuration the configuration 071 */ 072 public ConfigurationDynaBean(Configuration configuration) 073 { 074 super(configuration); 075 if (log.isTraceEnabled()) 076 { 077 log.trace("ConfigurationDynaBean(" + configuration + ")"); 078 } 079 } 080 081 public void set(String name, Object value) 082 { 083 if (log.isTraceEnabled()) 084 { 085 log.trace("set(" + name + "," + value + ")"); 086 } 087 088 if (value == null) 089 { 090 throw new NullPointerException("Error trying to set property to null."); 091 } 092 093 if (value instanceof Collection) 094 { 095 Collection collection = (Collection) value; 096 Iterator iterator = collection.iterator(); 097 while (iterator.hasNext()) 098 { 099 getConfiguration().addProperty(name, iterator.next()); 100 } 101 } 102 else if (value.getClass().isArray()) 103 { 104 int length = Array.getLength(value); 105 for (int i = 0; i < length; i++) 106 { 107 getConfiguration().addProperty(name, Array.get(value, i)); 108 } 109 } 110 else 111 { 112 getConfiguration().setProperty(name, value); 113 } 114 } 115 116 public Object get(String name) 117 { 118 if (log.isTraceEnabled()) 119 { 120 log.trace("get(" + name + ")"); 121 } 122 123 // get configuration property 124 Object result = getConfiguration().getProperty(name); 125 if (result == null) 126 { 127 // otherwise attempt to create bean from configuration subset 128 Configuration subset = new SubsetConfiguration(getConfiguration(), name, PROPERTY_DELIMITER); 129 if (!subset.isEmpty()) 130 { 131 result = new ConfigurationDynaBean(subset); 132 } 133 } 134 135 if (log.isDebugEnabled()) 136 { 137 log.debug(name + "=[" + result + "]"); 138 } 139 140 if (result == null) 141 { 142 throw new IllegalArgumentException("Property '" + name + "' does not exist."); 143 } 144 return result; 145 } 146 147 public boolean contains(String name, String key) 148 { 149 Configuration subset = getConfiguration().subset(name); 150 if (subset == null) 151 { 152 throw new IllegalArgumentException("Mapped property '" + name + "' does not exist."); 153 } 154 155 return subset.containsKey(key); 156 } 157 158 public Object get(String name, int index) 159 { 160 try 161 { 162 List list = getConfiguration().getList(name); 163 if (list.isEmpty()) 164 { 165 throw new IllegalArgumentException("Indexed property '" + name + "' does not exist."); 166 } 167 168 return list.get(index); 169 } 170 catch (ConversionException e) 171 { 172 throw new IllegalArgumentException("Property '" + name + "' is not indexed."); 173 } 174 } 175 176 public Object get(String name, String key) 177 { 178 Configuration subset = getConfiguration().subset(name); 179 if (subset == null) 180 { 181 throw new IllegalArgumentException("Mapped property '" + name + "' does not exist."); 182 } 183 184 return subset.getProperty(key); 185 } 186 187 public DynaClass getDynaClass() 188 { 189 return new ConfigurationDynaClass(getConfiguration()); 190 } 191 192 public void remove(String name, String key) 193 { 194 Configuration subset = new SubsetConfiguration(getConfiguration(), name, PROPERTY_DELIMITER); 195 subset.setProperty(key, null); 196 } 197 198 public void set(String name, int index, Object value) 199 { 200 try 201 { 202 Object property = getConfiguration().getProperty(name); 203 204 if (property == null) 205 { 206 throw new IllegalArgumentException("Property '" + name + "' does not exist."); 207 } 208 else if (property instanceof List) 209 { 210 List list = (List) property; 211 list.set(index, value); 212 getConfiguration().setProperty(name, list); 213 } 214 else if (property.getClass().isArray()) 215 { 216 Array.set(property, index, value); 217 } 218 else if (index == 0) 219 { 220 getConfiguration().setProperty(name, value); 221 } 222 else 223 { 224 throw new IllegalArgumentException("Property '" + name + "' is not indexed."); 225 } 226 } 227 catch (ConversionException e) 228 { 229 throw new IllegalArgumentException("Property '" + name + "' is not indexed."); 230 } 231 } 232 233 public void set(String name, String key, Object value) 234 { 235 getConfiguration().setProperty(name + "." + key, value); 236 } 237 }