View Javadoc
1   package org.codehaus.modello.core;
2   
3   /*
4    * Copyright (c) 2004, Codehaus.org
5    *
6    * Permission is hereby granted, free of charge, to any person obtaining a copy of
7    * this software and associated documentation files (the "Software"), to deal in
8    * the Software without restriction, including without limitation the rights to
9    * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
10   * of the Software, and to permit persons to whom the Software is furnished to do
11   * so, subject to the following conditions:
12   *
13   * The above copyright notice and this permission notice shall be included in all
14   * copies or substantial portions of the Software.
15   *
16   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22   * SOFTWARE.
23   */
24  
25  import javax.inject.Inject;
26  import javax.inject.Named;
27  
28  import java.io.File;
29  import java.io.IOException;
30  import java.io.Reader;
31  import java.io.Writer;
32  import java.util.Collection;
33  import java.util.Collections;
34  import java.util.Map;
35  import java.util.Properties;
36  
37  import org.codehaus.modello.ModelloException;
38  import org.codehaus.modello.ModelloRuntimeException;
39  import org.codehaus.modello.core.io.ModelReader;
40  import org.codehaus.modello.metadata.AssociationMetadata;
41  import org.codehaus.modello.metadata.ClassMetadata;
42  import org.codehaus.modello.metadata.FieldMetadata;
43  import org.codehaus.modello.metadata.InterfaceMetadata;
44  import org.codehaus.modello.metadata.MetadataPlugin;
45  import org.codehaus.modello.metadata.ModelMetadata;
46  import org.codehaus.modello.model.CodeSegment;
47  import org.codehaus.modello.model.Model;
48  import org.codehaus.modello.model.ModelAssociation;
49  import org.codehaus.modello.model.ModelClass;
50  import org.codehaus.modello.model.ModelDefault;
51  import org.codehaus.modello.model.ModelField;
52  import org.codehaus.modello.model.ModelInterface;
53  import org.codehaus.modello.model.ModelValidationException;
54  import org.codehaus.modello.plugin.ModelloGenerator;
55  import org.codehaus.plexus.util.xml.XmlStreamReader;
56  
57  /**
58   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
59   * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
60   */
61  @Named
62  public class DefaultModelloCore extends AbstractModelloCore {
63  
64      @Inject
65      private MetadataPluginManager metadataPluginManager;
66  
67      @Inject
68      private GeneratorPluginManager generatorPluginManager;
69  
70      public MetadataPluginManager getMetadataPluginManager() {
71          return metadataPluginManager;
72      }
73  
74      public Model loadModel(File file) throws IOException, ModelloException, ModelValidationException {
75          try (Reader reader = new XmlStreamReader(file)) {
76              return loadModel(reader);
77          }
78      }
79  
80      private void upgradeModifiedAttribute(
81              String name, Map<String, String> from, String newName, Map<String, String> to, String warn) {
82          String value = from.remove(name);
83  
84          if (value != null) {
85              getLogger().warn(warn);
86  
87              to.put(newName, value);
88          }
89      }
90  
91      @SuppressWarnings("unused")
92      private void upgradeModifiedAttribute(String name, Map<String, String> from, Map<String, String> to, String warn) {
93          upgradeModifiedAttribute(name, from, name, to, warn);
94      }
95  
96      /**
97       * Rename or move entities and provide a deprecation message
98       *
99       * @param modelReader
100      * @param model
101      */
102     private void upgradeModelloModel(ModelReader modelReader, Model model) {}
103 
104     public Model loadModel(Reader reader) throws ModelloException, ModelValidationException {
105         ModelReader modelReader = new ModelReader();
106         Model model = modelReader.loadModel(reader);
107 
108         model.initialize();
109 
110         // keep backward compatibility with Modello attributes model changes
111         upgradeModelloModel(modelReader, model);
112 
113         handlePluginsMetadata(modelReader, model);
114 
115         validate(model);
116 
117         return model;
118     }
119 
120     /**
121      * Handle Plugins Metadata.
122      *
123      * @throws ModelloException
124      */
125     private void handlePluginsMetadata(ModelReader modelReader, Model model) throws ModelloException {
126         Collection<MetadataPlugin> plugins = metadataPluginManager.getPlugins().values();
127 
128         for (MetadataPlugin plugin : plugins) {
129             Map<String, String> attributes = modelReader.getAttributesForModel();
130 
131             attributes = Collections.unmodifiableMap(attributes);
132 
133             ModelMetadata metadata = plugin.getModelMetadata(model, attributes);
134 
135             if (metadata == null) {
136                 throw new ModelloException("A meta data plugin must not return null.");
137             }
138 
139             model.addMetadata(metadata);
140         }
141 
142         for (ModelClass clazz : model.getAllClasses()) {
143             Map<String, String> attributes = modelReader.getAttributesForClass(clazz);
144 
145             attributes = Collections.unmodifiableMap(attributes);
146 
147             for (MetadataPlugin plugin : plugins) {
148                 ClassMetadata metadata = plugin.getClassMetadata(clazz, attributes);
149 
150                 if (metadata == null) {
151                     throw new ModelloException("A meta data plugin must not return null.");
152                 }
153 
154                 clazz.addMetadata(metadata);
155             }
156 
157             for (ModelField field : clazz.getAllFields()) {
158                 if (field instanceof ModelAssociation) {
159                     ModelAssociation modelAssociation = (ModelAssociation) field;
160 
161                     Map<String, String> fieldAttributes = modelReader.getAttributesForField(modelAssociation);
162 
163                     fieldAttributes = Collections.unmodifiableMap(fieldAttributes);
164 
165                     Map<String, String> associationAttributes =
166                             modelReader.getAttributesForAssociation(modelAssociation);
167 
168                     associationAttributes = Collections.unmodifiableMap(associationAttributes);
169 
170                     for (MetadataPlugin plugin : plugins) {
171                         FieldMetadata fieldMetadata = plugin.getFieldMetadata(modelAssociation, fieldAttributes);
172 
173                         if (fieldMetadata == null) {
174                             throw new ModelloException("A meta data plugin must not return null.");
175                         }
176 
177                         modelAssociation.addMetadata(fieldMetadata);
178 
179                         AssociationMetadata associationMetadata =
180                                 plugin.getAssociationMetadata(modelAssociation, associationAttributes);
181 
182                         if (associationMetadata == null) {
183                             throw new ModelloException("A meta data plugin must not return null.");
184                         }
185 
186                         modelAssociation.addMetadata(associationMetadata);
187                     }
188                 } else {
189                     attributes = modelReader.getAttributesForField(field);
190 
191                     attributes = Collections.unmodifiableMap(attributes);
192 
193                     for (MetadataPlugin plugin : plugins) {
194                         FieldMetadata metadata = plugin.getFieldMetadata(field, attributes);
195 
196                         if (metadata == null) {
197                             throw new ModelloException("A meta data plugin must not return null.");
198                         }
199 
200                         field.addMetadata(metadata);
201                     }
202                 }
203             }
204         }
205 
206         for (ModelInterface iface : model.getAllInterfaces()) {
207             Map<String, String> attributes = modelReader.getAttributesForInterface(iface);
208 
209             attributes = Collections.unmodifiableMap(attributes);
210 
211             for (MetadataPlugin plugin : plugins) {
212                 InterfaceMetadata metadata = plugin.getInterfaceMetadata(iface, attributes);
213 
214                 if (metadata == null) {
215                     throw new ModelloException("A meta data plugin must not return null.");
216                 }
217 
218                 iface.addMetadata(metadata);
219             }
220         }
221     }
222 
223     /**
224      * Validate the entire model.
225      *
226      * @throws ModelValidationException
227      */
228     private void validate(Model model) throws ModelValidationException {
229         model.validate();
230 
231         for (ModelDefault modelDefault : model.getDefaults()) {
232             modelDefault.validateElement();
233         }
234 
235         for (ModelClass modelClass : model.getAllClasses()) {
236             modelClass.validate();
237         }
238 
239         for (ModelClass modelClass : model.getAllClasses()) {
240             for (ModelField field : modelClass.getAllFields()) {
241                 field.validate();
242             }
243 
244             for (CodeSegment codeSegment : modelClass.getAllCodeSegments()) {
245                 codeSegment.validate();
246             }
247         }
248     }
249 
250     public void saveModel(Model model, Writer writer) throws ModelloException {
251         throw new ModelloRuntimeException("Not implemented.");
252     }
253 
254     public Model translate(Reader reader, String inputType, Properties parameters) throws ModelloException {
255         throw new ModelloRuntimeException("Not implemented.");
256     }
257 
258     public void generate(Model model, String outputType, Properties parameters) throws ModelloException {
259         if (model == null) {
260             throw new ModelloRuntimeException("Illegal argument: model == null.");
261         }
262 
263         if (outputType == null) {
264             throw new ModelloRuntimeException("Illegal argument: outputType == null.");
265         }
266 
267         if (parameters == null) {
268             parameters = new Properties();
269         }
270 
271         ModelloGenerator generator = generatorPluginManager.getGeneratorPlugin(outputType);
272 
273         generator.generate(model, parameters);
274     }
275 }