1 87 package org.codehaus.loom.components.configuration.merger; 88 89 import java.util.ArrayList ; 90 import java.util.HashSet ; 91 import java.util.List ; 92 import java.util.Set ; 93 import org.codehaus.dna.Configuration; 94 import org.codehaus.dna.ConfigurationException; 95 import org.codehaus.dna.impl.DefaultConfiguration; 96 97 115 public class ConfigurationMerger 116 { 117 125 public static Configuration merge( final Configuration layer, 126 final Configuration base ) 127 throws ConfigurationException 128 { 129 final DefaultConfiguration merged = 130 new DefaultConfiguration( base.getName(), 131 base.getPath(), 132 "Merged [layer: " + 133 layer.getLocation() 134 + ", base: " + base.getLocation() + "]" ); 135 136 copyAttributes( base, merged ); 137 copyAttributes( layer, merged ); 138 139 mergeChildren( layer, base, merged ); 140 141 final String value = getValue( layer, base ); 142 if( null != value ) 143 { 144 merged.setValue( value ); 145 } 146 147 return merged; 148 } 149 150 private static void mergeChildren( final Configuration layer, 151 final Configuration base, 152 final DefaultConfiguration merged ) 153 throws ConfigurationException 154 { 155 final Configuration[] lc = layer.getChildren(); 156 final Configuration[] bc = base.getChildren(); 157 final Set baseUsed = new HashSet (); 158 final List toMergeUsed = new ArrayList (); 159 160 for( int i = 0; i < lc.length; i++ ) 161 { 162 final Configuration mergeWith = 163 getMergePartner( lc[ i ], layer, base ); 164 165 if( null == mergeWith ) 166 { 167 toMergeUsed.add( lc[ i ] ); 168 } 169 else 170 { 171 toMergeUsed.add( merge( lc[ i ], mergeWith ) ); 172 baseUsed.add( mergeWith ); 173 } 174 } 175 176 for( int i = 0; i < bc.length; i++ ) 177 { 178 if( !baseUsed.contains( bc[ i ] ) ) 179 { 180 merged.addChild( bc[ i ] ); 181 } 182 } 183 184 final int count = toMergeUsed.size(); 185 for( int i = 0; i < count; i++ ) 186 { 187 merged.addChild( (Configuration)toMergeUsed.get( i ) ); 188 } 189 } 190 191 private static Configuration getMergePartner( final Configuration toMerge, 192 final Configuration layer, 193 final Configuration base ) 194 throws ConfigurationException 195 { 196 if( toMerge.getAttributeAsBoolean( Constants.MERGE_ATTR, false ) ) 197 { 198 final String keyAttribute = toMerge.getAttribute( 199 Constants.KEY_ATTR, null ); 200 final String keyvalue = 201 keyAttribute == null ? 202 null : 203 toMerge.getAttribute( keyAttribute ); 204 205 final Configuration[] layerKids = match( layer, 206 toMerge.getName(), 207 keyAttribute, 208 keyvalue ); 209 210 final Configuration[] baseKids = match( base, 211 toMerge.getName(), 212 keyAttribute, 213 keyvalue ); 214 215 if( layerKids.length == 1 && baseKids.length == 1 ) 216 { 217 return baseKids[ 0 ]; 218 } 219 else 220 { 221 throw new ConfigurationException( "Unable to merge configuration item, " 222 + 223 "multiple matches on child or base [name: " 224 + toMerge.getName() + "]", 225 toMerge.getPath(), 226 toMerge.getLocation() ); 227 } 228 } 229 230 return null; 231 } 232 233 private static String getValue( final Configuration layer, 234 final Configuration base ) 235 { 236 try 237 { 238 return layer.getValue(); 239 } 240 catch( ConfigurationException e ) 241 { 242 return base.getValue( null ); 243 } 244 } 245 246 private static void copyAttributes( final Configuration source, 247 final DefaultConfiguration dest ) 248 throws ConfigurationException 249 { 250 final String [] names = source.getAttributeNames(); 251 252 for( int i = 0; i < names.length; i++ ) 253 { 254 if( !names[ i ].startsWith( Constants.MERGE_METADATA_PREFIX ) ) 255 { 256 dest.setAttribute( names[ i ], 257 source.getAttribute( names[ i ] ) ); 258 } 259 } 260 } 261 262 273 public static Configuration[] match( final Configuration config, 274 final String element, 275 final String attribute ) 276 { 277 return match( config, element, attribute, null ); 278 } 279 280 293 public static Configuration[] match( final Configuration config, 294 final String element, 295 final String attribute, 296 final String value ) 297 { 298 final ArrayList list = new ArrayList (); 299 final Configuration[] children = config.getChildren( element ); 300 301 for( int i = 0; i < children.length; i++ ) 302 { 303 if( null == attribute ) 304 { 305 list.add( children[ i ] ); 306 } 307 else 308 { 309 final String v = 310 children[ i ].getAttribute( attribute, null ); 311 312 if( v != null ) 313 { 314 if( (value == null) || v.equals( value ) ) 315 { 316 list.add( children[ i ] ); 318 } 319 } 320 } 321 } 322 323 return (Configuration[])list.toArray( new Configuration[ list.size() ] ); 324 } 325 } 326 | Popular Tags |