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    }