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    }