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 }