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