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