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.spring.generator; 018 019 import java.io.File; 020 import java.io.FileWriter; 021 import java.io.IOException; 022 import java.io.PrintWriter; 023 import java.io.FileInputStream; 024 import java.io.InputStream; 025 import java.io.FileOutputStream; 026 import java.io.OutputStream; 027 import java.util.Iterator; 028 import java.util.List; 029 import java.util.Map; 030 import java.util.Set; 031 import java.util.Properties; 032 033 import org.apache.xbean.spring.context.impl.NamespaceHelper; 034 035 036 /** 037 * @author Dain Sundstrom 038 * @version $Id$ 039 * @since 1.0 040 */ 041 public class XmlMetadataGenerator implements GeneratorPlugin { 042 private final String metaInfDir; 043 private LogFacade log; 044 private final File schema; 045 046 public static final String NAMESPACE_HANDLER = "org.apache.xbean.spring.context.v2.XBeanNamespaceHandler"; 047 private final boolean generateSpringSchemasFile; 048 private final boolean generateSpringHandlersFile; 049 050 public XmlMetadataGenerator(String metaInfDir, File schema) { 051 this(metaInfDir, schema, true, true); 052 } 053 054 public XmlMetadataGenerator(String metaInfDir, File schema, boolean generateSpringSchemasFile, boolean generateSpringHandlersFile) { 055 this.metaInfDir = metaInfDir; 056 this.schema = schema; 057 this.generateSpringSchemasFile = generateSpringSchemasFile; 058 this.generateSpringHandlersFile = generateSpringHandlersFile; 059 } 060 061 public void generate(NamespaceMapping namespaceMapping) throws IOException { 062 String namespace = namespaceMapping.getNamespace(); 063 if (namespace == null) { 064 return; 065 } 066 067 File file = new File(metaInfDir, NamespaceHelper.createDiscoveryPathName(namespace)); 068 file.getParentFile().mkdirs(); 069 log.log("Generating META-INF properties file: " + file + " for namespace: " + namespace); 070 PrintWriter out = new PrintWriter(new FileWriter(file)); 071 try { 072 generatePropertiesFile(out, namespaceMapping.getElements()); 073 } finally { 074 out.close(); 075 } 076 077 if( generateSpringHandlersFile ) { 078 079 // Generate spring 2.0 mapping 080 file = new File(metaInfDir, "META-INF/spring.handlers"); 081 082 Properties properties = new Properties(); 083 if (!file.exists()) { 084 log.log("Generating Spring 2.0 handler mapping: " + file + " for namespace: " + namespace); 085 } else { 086 log.log("Updating Spring 2.0 handler mapping: " + file + " for namespace: " + namespace); 087 088 // read in current file 089 InputStream in = new FileInputStream(file); 090 try { 091 properties.load(in); 092 } catch (IOException e) { 093 in.close(); 094 } 095 } 096 097 // add property 098 properties.put(namespace, NAMESPACE_HANDLER); 099 100 // write properties 101 OutputStream fout = new FileOutputStream(file); 102 try { 103 properties.store(fout, "Generated by xbean-spring"); 104 } finally { 105 fout.close(); 106 } 107 } 108 109 if (schema != null && generateSpringSchemasFile ) { 110 String cp = new File(metaInfDir).toURI().relativize(schema.toURI()).toString(); 111 file = new File(metaInfDir, "META-INF/spring.schemas"); 112 113 Properties properties = new Properties(); 114 if (!file.exists()) { 115 log.log("Generating Spring 2.0 schema mapping: " + file + " for namespace: " + namespace); 116 } else { 117 log.log("Updating Spring 2.0 schema mapping: " + file + " for namespace: " + namespace); 118 119 // read in current file 120 InputStream in = new FileInputStream(file); 121 try { 122 properties.load(in); 123 } catch (IOException e) { 124 in.close(); 125 } 126 } 127 128 // add property 129 String uri = namespace; 130 if (!uri.endsWith("/")) { 131 uri += "/"; 132 } 133 properties.put(uri + cp, cp); 134 135 // write properties 136 OutputStream fout = new FileOutputStream(file); 137 try { 138 properties.store(fout, "Generated by xbean-spring"); 139 } finally { 140 fout.close(); 141 } 142 } 143 } 144 145 private void generatePropertiesFile(PrintWriter out, Set elements) { 146 out.println("# NOTE: this file is autogenerated by Apache XBean"); 147 out.println(); 148 out.println("# beans"); 149 150 for (Iterator iter = elements.iterator(); iter.hasNext();) { 151 ElementMapping element = (ElementMapping) iter.next(); 152 out.println(element.getElementName() + " = " + element.getClassName()); 153 154 generatePropertiesFileContent(out, element); 155 generatePropertiesFilePropertyAliases(out, element); 156 generatePropertiesFileConstructors(out, element); 157 out.println(); 158 } 159 } 160 161 private void generatePropertiesFileContent(PrintWriter out, ElementMapping element) { 162 String contentProperty = element.getContentProperty(); 163 if (contentProperty != null) { 164 out.println(element.getElementName() + ".contentProperty = " + contentProperty); 165 } 166 String initMethod = element.getInitMethod(); 167 if (initMethod != null) { 168 out.println(element.getElementName() + ".initMethod = " + initMethod); 169 } 170 171 String destroyMethod = element.getDestroyMethod(); 172 if (destroyMethod != null) { 173 out.println(element.getElementName() + ".destroyMethod = " + destroyMethod); 174 } 175 176 String factoryMethod = element.getFactoryMethod(); 177 if (factoryMethod != null) { 178 out.println(element.getElementName() + ".factoryMethod = " + factoryMethod); 179 } 180 181 for (Iterator iter = element.getAttributes().iterator(); iter.hasNext();) { 182 AttributeMapping attribute = (AttributeMapping) iter.next(); 183 if( attribute.getPropertyEditor() !=null ) { 184 out.println(element.getElementName() + "."+attribute.getPropertyName()+ ".propertyEditor = " + attribute.getPropertyEditor()); 185 } 186 } 187 188 List flatProperties = element.getFlatProperties(); 189 for (Iterator itr = flatProperties.iterator(); itr.hasNext();) { 190 out.println(element.getElementName() + "." + itr.next() + ".flat"); 191 } 192 193 Map maps = element.getMapMappings(); 194 for (Iterator itr = maps.entrySet().iterator(); itr.hasNext();) { 195 Map.Entry entry = (Map.Entry) itr.next(); 196 MapMapping mm = (MapMapping) entry.getValue(); 197 if (mm.getEntryName() != null) { 198 out.println(element.getElementName() + "." + entry.getKey() + ".map.entryName = " + mm.getEntryName()); 199 } 200 if (mm.getKeyName() != null) { 201 out.println(element.getElementName() + "." + entry.getKey() + ".map.keyName = " + mm.getKeyName()); 202 } 203 if (mm.isFlat()) { 204 out.println(element.getElementName() + "." + entry.getKey() + ".map.flat = " + Boolean.toString(mm.isFlat())); 205 } 206 if (mm.getDupsMode() != null) { 207 out.println(element.getElementName() + "." + entry.getKey() + ".map.dups = " + mm.getDupsMode()); 208 } 209 if (mm.getDefaultKey() != null) { 210 out.println(element.getElementName() + "." + entry.getKey() + ".map.defaultKey = " + mm.getDefaultKey()); 211 } 212 } 213 214 Map flatCollections = element.getFlatCollections(); 215 for (Iterator itr = flatCollections.entrySet().iterator(); itr.hasNext();) { 216 Map.Entry entry = (Map.Entry) itr.next(); 217 String child = (String) entry.getValue(); 218 out.println(element.getElementName() + "." + child + ".flatCollection = " + entry.getKey()); 219 } 220 } 221 222 private void generatePropertiesFileConstructors(PrintWriter out, ElementMapping element) { 223 List constructors = element.getConstructors(); 224 for (Iterator iterator = constructors.iterator(); iterator.hasNext();) { 225 List args = (List) iterator.next(); 226 generatePropertiesFileConstructor(out, element, args); 227 } 228 } 229 230 private void generatePropertiesFileConstructor(PrintWriter out, ElementMapping element, List args) { 231 out.print(element.getClassName()); 232 if (element.getFactoryMethod() != null) { 233 out.print("." + element.getFactoryMethod()); 234 } 235 out.print("("); 236 for (Iterator iterator = args.iterator(); iterator.hasNext();) { 237 ParameterMapping parameterMapping = (ParameterMapping) iterator.next(); 238 out.print(parameterMapping.getType().getName()); 239 if (iterator.hasNext()) { 240 out.print(","); 241 } 242 } 243 out.print(").parameterNames ="); 244 for (Iterator iterator = args.iterator(); iterator.hasNext();) { 245 ParameterMapping parameterMapping = (ParameterMapping) iterator.next(); 246 out.print(" "); 247 out.print(parameterMapping.getName()); 248 } 249 out.println(); 250 } 251 252 private void generatePropertiesFilePropertyAliases(PrintWriter out, ElementMapping element) { 253 for (Iterator iterator = element.getAttributes().iterator(); iterator.hasNext();) { 254 AttributeMapping attributeMapping = (AttributeMapping) iterator.next(); 255 String propertyName = attributeMapping.getPropertyName(); 256 String attributeName = attributeMapping.getAttributeName(); 257 if (!propertyName.equals(attributeName)) { 258 if (List.class.getName().equals(attributeMapping.getType().getName())) { 259 out.println(element.getElementName() + ".list." + attributeName + " = " + propertyName); 260 } else { 261 out.println(element.getElementName() + ".alias." + attributeName + " = " + propertyName); 262 } 263 } 264 } 265 } 266 267 public LogFacade getLog() { 268 return log; 269 } 270 271 public void setLog(LogFacade log) { 272 this.log = log; 273 } 274 }