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 package org.apache.xbean.blueprint.context.impl; 018 019 import java.lang.reflect.Constructor; 020 import java.lang.reflect.Method; 021 import java.util.ArrayList; 022 import java.util.Collections; 023 import java.util.Properties; 024 import java.util.StringTokenizer; 025 026 /** 027 * A helper class which understands how to map an XML namespaced element to 028 * Spring bean configurations 029 * 030 * @author James Strachan 031 * @version $Id$ 032 * @since 2.0 033 */ 034 public class MappingMetaData { 035 private Properties properties; 036 private String packageName; 037 038 /** 039 * Creates an empty MappingMetaData for the specified Java package. 040 * @param packageName the Java package to map 041 */ 042 public MappingMetaData(String packageName) { 043 this.packageName = packageName; 044 this.properties = new Properties(); 045 } 046 047 /** 048 * Creates MappingMetaData using the specified properties which contan the package name. 049 * @param properties 050 */ 051 public MappingMetaData(Properties properties) { 052 this.properties = properties; 053 } 054 055 /** 056 * Returns the Java class name for the given XML element name 057 */ 058 public String getClassName(String localName) { 059 String className = properties.getProperty(localName); 060 if (className == null && packageName != null) { 061 if (packageName.length() > 0) { 062 className = packageName + "." + localName; 063 } 064 else { 065 className = localName; 066 } 067 } 068 return className; 069 } 070 071 /** 072 * Returns the property name for the given element and attribute name 073 * 074 * @param elementName the XML local name of the element 075 * @param attributeName the XML local name of the attribute 076 * @return the property name to use or null if the attribute is not a valid property 077 */ 078 public String getPropertyName(String elementName, String attributeName) { 079 return properties.getProperty(elementName + ".alias." + attributeName, attributeName); 080 } 081 082 /** 083 * Returns a valid property name if the childElementName maps to a nested list property 084 * 085 * @param elementName the owner element 086 * @param childElementName is the child element name which maps to the nested list property 087 * @return the property name if available or null if it is not applicable 088 */ 089 public String getNestedListProperty(String elementName, String childElementName) { 090 return properties.getProperty(elementName + ".list." + childElementName); 091 } 092 093 /** 094 * Returns a valid property name if the childElementName maps to a nested bean property 095 * 096 * @param elementName the owner element 097 * @param childElementName is the child element name which maps to the nested bean property 098 * @return the property name if available or null if it is not applicable 099 */ 100 public String getNestedProperty(String elementName, String childElementName) { 101 return properties.getProperty(elementName + ".alias." + childElementName); 102 } 103 104 public boolean isDefaultConstructor(Constructor constructor) { 105 String property = properties.getProperty(constructorToPropertyName(constructor) + ".default"); 106 if (property != null) { 107 return Boolean.valueOf(property).booleanValue(); 108 } 109 return false; 110 } 111 112 public boolean isDefaultFactoryMethod(Class beanClass, Method factoryMethod) { 113 String property = properties.getProperty(methodToPropertyName(beanClass, factoryMethod) + ".default"); 114 if (property != null) { 115 return Boolean.valueOf(property).booleanValue(); 116 } 117 return false; 118 } 119 120 public String[] getParameterNames(Constructor constructor) { 121 String property = properties.getProperty(constructorToPropertyName(constructor) + ".parameterNames"); 122 if (property != null) { 123 ArrayList names = Collections.list(new StringTokenizer(property, ", ")); 124 return (String[]) names.toArray(new String[0]); 125 } 126 return null; 127 } 128 129 public String[] getParameterNames(Class beanClass, Method factoryMethod) { 130 String property = properties.getProperty(methodToPropertyName(beanClass, factoryMethod) + ".parameterNames"); 131 if (property != null) { 132 ArrayList names = Collections.list(new StringTokenizer(property, ", ")); 133 return (String[]) names.toArray(new String[0]); 134 } 135 return null; 136 } 137 138 public static String constructorToPropertyName(Constructor constructor) { 139 StringBuffer buf = new StringBuffer(); 140 buf.append(constructor.getName()).append("("); 141 Class[] parameterTypes = constructor.getParameterTypes(); 142 for (int i = 0; i < parameterTypes.length; i++) { 143 Class parameterType = parameterTypes[i]; 144 buf.append(parameterType.getName()); 145 if (i < parameterTypes.length - 1) { 146 buf.append(","); 147 } 148 } 149 buf.append(")"); 150 return buf.toString(); 151 } 152 153 public static String methodToPropertyName(Class beanClass, Method method) { 154 StringBuffer buf = new StringBuffer(); 155 buf.append(beanClass.getName()).append("."); 156 buf.append(method.getName()).append("("); 157 Class[] parameterTypes = method.getParameterTypes(); 158 for (int i = 0; i < parameterTypes.length; i++) { 159 Class parameterType = parameterTypes[i]; 160 buf.append(parameterType.getName()); 161 if (i < parameterTypes.length - 1) { 162 buf.append(","); 163 } 164 } 165 buf.append(")"); 166 return buf.toString(); 167 } 168 169 public String getInitMethodName(String elementName) { 170 return properties.getProperty(elementName + ".initMethod"); 171 } 172 173 public String getDestroyMethodName(String elementName) { 174 return properties.getProperty(elementName + ".destroyMethod"); 175 } 176 177 public String getFactoryMethodName(String elementName) { 178 return properties.getProperty(elementName + ".factoryMethod"); 179 } 180 181 public String getContentProperty(String elementName) { 182 return properties.getProperty(elementName + ".contentProperty"); 183 } 184 185 public String getMapEntryName(String elementName, String property) { 186 return properties.getProperty(elementName + "." + property + ".map.entryName"); 187 } 188 189 public String getMapKeyName(String elementName, String property) { 190 return properties.getProperty(elementName + "." + property + ".map.keyName"); 191 } 192 193 public boolean isFlatMap(String elementName, String property) { 194 return properties.getProperty(elementName + "." + property + ".map.flat") != null; 195 } 196 197 public String getMapDupsMode(String elementName, String property) { 198 return properties.getProperty(elementName + "." + property + ".map.dups"); 199 } 200 201 public String getMapDefaultKey(String elementName, String property) { 202 return properties.getProperty(elementName + "." + property + ".map.defaultKey"); 203 } 204 205 public String getFlatCollectionProperty(String elementName, String property) 206 { 207 return properties.getProperty(elementName + "." + property + ".flatCollection"); 208 } 209 210 public boolean isFlatProperty(String elementName, String property) { 211 return properties.getProperty(elementName + "." + property + ".flat") != null; 212 } 213 214 public String getPropertyEditor(String elementName, String property) 215 { 216 return properties.getProperty(elementName + "." + property + ".propertyEditor"); 217 } 218 219 }