KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > repo > dictionary > CompiledModel


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.repo.dictionary;
18
19 import java.util.ArrayList JavaDoc;
20 import java.util.Collection JavaDoc;
21 import java.util.HashMap JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Map JavaDoc;
24 import java.util.TreeMap JavaDoc;
25
26 import org.alfresco.service.cmr.dictionary.AspectDefinition;
27 import org.alfresco.service.cmr.dictionary.AssociationDefinition;
28 import org.alfresco.service.cmr.dictionary.ClassDefinition;
29 import org.alfresco.service.cmr.dictionary.DictionaryException;
30 import org.alfresco.service.cmr.dictionary.ModelDefinition;
31 import org.alfresco.service.cmr.dictionary.PropertyDefinition;
32 import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
33 import org.alfresco.service.cmr.dictionary.TypeDefinition;
34 import org.alfresco.service.namespace.DynamicNamespacePrefixResolver;
35 import org.alfresco.service.namespace.NamespaceException;
36 import org.alfresco.service.namespace.NamespacePrefixResolver;
37 import org.alfresco.service.namespace.QName;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40
41
42 /**
43  * Compiled representation of a model definition.
44  *
45  * In this case, compiled means that
46  * a) all references between model items have been resolved
47  * b) inheritence of class features have been flattened
48  * c) overridden class features have been resolved
49  *
50  * A compiled model also represents a valid model.
51  *
52  * @author David Caruana
53  *
54  */

55 /*package*/ class CompiledModel implements ModelQuery
56 {
57     
58     // Logger
59
private static final Log logger = LogFactory.getLog(DictionaryDAOImpl.class);
60     
61     private M2Model model;
62     private ModelDefinition modelDefinition;
63     private Map JavaDoc<QName, DataTypeDefinition> dataTypes = new HashMap JavaDoc<QName, DataTypeDefinition>();
64     private Map JavaDoc<QName, ClassDefinition> classes = new HashMap JavaDoc<QName, ClassDefinition>();
65     private Map JavaDoc<QName, TypeDefinition> types = new HashMap JavaDoc<QName, TypeDefinition>();
66     private Map JavaDoc<QName, AspectDefinition> aspects = new HashMap JavaDoc<QName, AspectDefinition>();
67     private Map JavaDoc<QName, PropertyDefinition> properties = new HashMap JavaDoc<QName, PropertyDefinition>();
68     private Map JavaDoc<QName, AssociationDefinition> associations = new HashMap JavaDoc<QName, AssociationDefinition>();
69     
70     
71     /**
72      * Construct
73      *
74      * @param model model definition
75      * @param dictionaryDAO dictionary DAO
76      * @param namespaceDAO namespace DAO
77      */

78     /*package*/ CompiledModel(M2Model model, DictionaryDAO dictionaryDAO, NamespaceDAO namespaceDAO)
79     {
80         try
81         {
82             // Phase 1: Construct model definitions from model entries
83
// resolving qualified names
84
this.model = model;
85             constructDefinitions(model, dictionaryDAO, namespaceDAO);
86     
87             // Phase 2: Resolve dependencies between model definitions
88
ModelQuery query = new DelegateModelQuery(this, dictionaryDAO);
89             resolveDependencies(query);
90             
91             // Phase 3: Resolve inheritance of values within class hierachy
92
resolveInheritance(query);
93         }
94         catch(Exception JavaDoc e)
95         {
96             throw new DictionaryException("Failed to compile model " + model.getName(), e);
97         }
98     }
99
100     
101     /**
102      * @return the model definition
103      */

104     /*package*/ M2Model getM2Model()
105     {
106         return model;
107     }
108     
109     
110     /**
111      * Construct compiled definitions
112      *
113      * @param model model definition
114      * @param dictionaryDAO dictionary DAO
115      * @param namespaceDAO namespace DAO
116      */

117     private void constructDefinitions(M2Model model, DictionaryDAO dictionaryDAO, NamespaceDAO namespaceDAO)
118     {
119         NamespacePrefixResolver localPrefixes = createLocalPrefixResolver(model, namespaceDAO);
120     
121         // Construct Model Definition
122
modelDefinition = new M2ModelDefinition(model, localPrefixes);
123         
124         // Construct Property Types
125
for (M2DataType propType : model.getPropertyTypes())
126         {
127             M2DataTypeDefinition def = new M2DataTypeDefinition(modelDefinition, propType, localPrefixes);
128             if (dataTypes.containsKey(def.getName()))
129             {
130                 throw new DictionaryException("Found duplicate property type definition " + propType.getName());
131             }
132             dataTypes.put(def.getName(), def);
133         }
134         
135         // Construct Type Definitions
136
for (M2Type type : model.getTypes())
137         {
138             M2TypeDefinition def = new M2TypeDefinition(modelDefinition, type, localPrefixes, properties, associations);
139             if (classes.containsKey(def.getName()))
140             {
141                 throw new DictionaryException("Found duplicate class definition " + type.getName() + " (a type)");
142             }
143             classes.put(def.getName(), def);
144             types.put(def.getName(), def);
145         }
146         
147         // Construct Aspect Definitions
148
for (M2Aspect aspect : model.getAspects())
149         {
150             M2AspectDefinition def = new M2AspectDefinition(modelDefinition, aspect, localPrefixes, properties, associations);
151             if (classes.containsKey(def.getName()))
152             {
153                 throw new DictionaryException("Found duplicate class definition " + aspect.getName() + " (an aspect)");
154             }
155             classes.put(def.getName(), def);
156             aspects.put(def.getName(), def);
157         }
158     }
159     
160     
161     /**
162      * Create a local namespace prefix resolver containing the namespaces defined and imported
163      * in the model
164      *
165      * @param model model definition
166      * @param namespaceDAO namespace DAO
167      * @return the local namespace prefix resolver
168      */

169     private NamespacePrefixResolver createLocalPrefixResolver(M2Model model, NamespaceDAO namespaceDAO)
170     {
171         // Retrieve set of existing URIs for validation purposes
172
Collection JavaDoc<String JavaDoc> uris = namespaceDAO.getURIs();
173         
174         // Create a namespace prefix resolver based on imported and defined
175
// namespaces within the model
176
DynamicNamespacePrefixResolver prefixResolver = new DynamicNamespacePrefixResolver(null);
177         for (M2Namespace imported : model.getImports())
178         {
179             String JavaDoc uri = imported.getUri();
180             if (!uris.contains(uri))
181             {
182                 throw new NamespaceException("URI " + uri + " cannot be imported as it is not defined (with prefix " + imported.getPrefix());
183             }
184             prefixResolver.registerNamespace(imported.getPrefix(), uri);
185         }
186         for (M2Namespace defined : model.getNamespaces())
187         {
188             prefixResolver.registerNamespace(defined.getPrefix(), defined.getUri());
189         }
190         return prefixResolver;
191     }
192     
193
194     /**
195      * Resolve dependencies between model items
196      *
197      * @param query support for querying other items in model
198      */

199     private void resolveDependencies(ModelQuery query)
200     {
201         for (DataTypeDefinition def : dataTypes.values())
202         {
203             ((M2DataTypeDefinition)def).resolveDependencies(query);
204         }
205         for (ClassDefinition def : classes.values())
206         {
207             ((M2ClassDefinition)def).resolveDependencies(query);
208         }
209     }
210         
211
212     /**
213      * Resolve class feature inheritence
214      *
215      * @param query support for querying other items in model
216      */

217     private void resolveInheritance(ModelQuery query)
218     {
219         // Calculate order of class processing (root to leaf)
220
Map JavaDoc<Integer JavaDoc,List JavaDoc<ClassDefinition>> order = new TreeMap JavaDoc<Integer JavaDoc,List JavaDoc<ClassDefinition>>();
221         for (ClassDefinition def : classes.values())
222         {
223             // Calculate class depth in hierarchy
224
int depth = 0;
225             QName parentName = def.getParentName();
226             while (parentName != null)
227             {
228                 ClassDefinition parentClass = getClass(parentName);
229                 if (parentClass == null)
230                 {
231                     break;
232                 }
233                 depth = depth +1;
234                 parentName = parentClass.getParentName();
235             }
236
237             // Map class to depth
238
List JavaDoc<ClassDefinition> classes = order.get(depth);
239             if (classes == null)
240             {
241                 classes = new ArrayList JavaDoc<ClassDefinition>();
242                 order.put(depth, classes);
243             }
244             classes.add(def);
245             
246             if (logger.isDebugEnabled())
247                 logger.debug("Resolving inheritance: class " + def.getName() + " found at depth " + depth);
248         }
249         
250         // Resolve inheritance of each class
251
for (int depth = 0; depth < order.size(); depth++)
252         {
253             for (ClassDefinition def : order.get(depth))
254             {
255                 ((M2ClassDefinition)def).resolveInheritance(query);
256             }
257         }
258     }
259         
260     
261     /**
262      * @return the compiled model definition
263      */

264     public ModelDefinition getModelDefinition()
265     {
266         return modelDefinition;
267     }
268     
269     
270     /**
271      * @return the compiled property types
272      */

273     public Collection JavaDoc<DataTypeDefinition> getDataTypes()
274     {
275         return dataTypes.values();
276     }
277
278
279     /**
280      * @return the compiled types
281      */

282     public Collection JavaDoc<TypeDefinition> getTypes()
283     {
284         return types.values();
285     }
286     
287
288     /**
289      * @return the compiled aspects
290      */

291     public Collection JavaDoc<AspectDefinition> getAspects()
292     {
293         return aspects.values();
294     }
295
296     
297     /* (non-Javadoc)
298      * @see org.alfresco.repo.dictionary.impl.ModelQuery#getPropertyType(org.alfresco.repo.ref.QName)
299      */

300     public DataTypeDefinition getDataType(QName name)
301     {
302         return dataTypes.get(name);
303     }
304
305     
306     /* (non-Javadoc)
307      * @see org.alfresco.repo.dictionary.ModelQuery#getDataType(java.lang.Class)
308      */

309     public DataTypeDefinition getDataType(Class JavaDoc javaClass)
310     {
311         for (DataTypeDefinition dataTypeDef : dataTypes.values())
312         {
313             if (dataTypeDef.getJavaClassName().equals(javaClass.getName()))
314             {
315                 return dataTypeDef;
316             }
317         }
318         return null;
319     }
320
321
322     /* (non-Javadoc)
323      * @see org.alfresco.repo.dictionary.impl.ModelQuery#getType(org.alfresco.repo.ref.QName)
324      */

325     public TypeDefinition getType(QName name)
326     {
327         return types.get(name);
328     }
329
330
331     /* (non-Javadoc)
332      * @see org.alfresco.repo.dictionary.impl.ModelQuery#getAspect(org.alfresco.repo.ref.QName)
333      */

334     public AspectDefinition getAspect(QName name)
335     {
336         return aspects.get(name);
337     }
338
339
340     /* (non-Javadoc)
341      * @see org.alfresco.repo.dictionary.impl.ModelQuery#getClass(org.alfresco.repo.ref.QName)
342      */

343     public ClassDefinition getClass(QName name)
344     {
345         return classes.get(name);
346     }
347     
348     
349     /* (non-Javadoc)
350      * @see org.alfresco.repo.dictionary.impl.ModelQuery#getProperty(org.alfresco.repo.ref.QName)
351      */

352     public PropertyDefinition getProperty(QName name)
353     {
354         return properties.get(name);
355     }
356
357     
358     /* (non-Javadoc)
359      * @see org.alfresco.repo.dictionary.impl.ModelQuery#getAssociation(org.alfresco.repo.ref.QName)
360      */

361     public AssociationDefinition getAssociation(QName name)
362     {
363         return associations.get(name);
364     }
365
366 }
367
Popular Tags