View Javadoc
1   /*
2    * #%L
3    * EUGene :: EUGene
4    * %%
5    * Copyright (C) 2004 - 2010 CodeLutin
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as 
9    * published by the Free Software Foundation, either version 3 of the 
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public 
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
20   * #L%
21   */
22  
23  package org.nuiton.eugene.models.object.xml;
24  
25  import com.google.common.collect.ImmutableSet;
26  import com.google.common.collect.Sets;
27  import org.apache.commons.logging.Log;
28  import org.apache.commons.logging.LogFactory;
29  import org.nuiton.eugene.models.object.ObjectModelAttribute;
30  import org.nuiton.eugene.models.object.ObjectModelClass;
31  import org.nuiton.eugene.models.object.ObjectModelClassifier;
32  import org.nuiton.eugene.models.object.ObjectModelJavaModifier;
33  import org.nuiton.eugene.models.object.ObjectModelModifier;
34  import org.nuiton.eugene.models.object.ObjectModelOperation;
35  
36  import java.util.ArrayList;
37  import java.util.Collection;
38  import java.util.HashMap;
39  import java.util.HashSet;
40  import java.util.Iterator;
41  import java.util.LinkedList;
42  import java.util.List;
43  import java.util.Map;
44  import java.util.Set;
45  
46  /**
47   * ObjectModelClassImpl.
48   *
49   * Created: 14 janv. 2004
50   *
51   * @author Cédric Pineau - pineau@codelutin.com
52   * @author Florian Desbois - desbois@codelutin.com
53   */
54  public class ObjectModelClassImpl extends ObjectModelClassifierImpl implements ObjectModelClass {
55  
56      private static final Log log = LogFactory.getLog(ObjectModelClassImpl.class);
57  
58      protected List<ObjectModelClass> superclasses;
59  
60      protected Map<ObjectModelClass, String> superclassesDiscriminators = new HashMap<>();
61  
62      protected List<ObjectModelImplRef> superclassesRefs = new ArrayList<>();
63  
64      protected List<ObjectModelClass> specialisations;
65  
66      protected List<ObjectModelClassifier> innerClasses;
67  
68      private static Set<ObjectModelModifier> authorizedModifiers;
69  
70      public ObjectModelClassImpl() {
71      }
72  
73      @Override
74      protected Set<ObjectModelModifier> getAuthorizedModifiers() {
75          if (authorizedModifiers == null) {
76              // http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.1.1
77              // public protected private abstract static final strictfp
78              Set<ObjectModelModifier> modifiers = Sets.newHashSet(
79                      (ObjectModelModifier) ObjectModelJavaModifier.ABSTRACT,  // Force cast because of generics limitation
80                      ObjectModelJavaModifier.STATIC,
81                      ObjectModelJavaModifier.FINAL,
82                      ObjectModelJavaModifier.STRICTFP);
83              modifiers.addAll(ObjectModelJavaModifier.visibilityModifiers);
84              authorizedModifiers = ImmutableSet.copyOf(modifiers);
85          }
86          return authorizedModifiers;
87      }
88  
89      public void clearSuperclasses() {
90          superclasses = null;
91          superclassesRefs.clear();
92      }
93  
94      public void addSuperclass(ObjectModelImplRef ref) {
95          superclassesRefs.add(ref);
96          // superclassesRefs is modified, superclasses must be reset
97          superclasses = null;
98      }
99  
100     /**
101      * Digester method to add innerClass to this ObjectModelClass.
102      *
103      * @param innerClass the ObjectModelClass to add
104      */
105     public void addInnerClassifier(ObjectModelClassifierImpl innerClass) {
106         innerClass.setDeclaringElement(this);
107         innerClass.setInner(true);
108         if (innerClasses == null) {
109             innerClasses = new ArrayList<>();
110         }
111         innerClasses.add(innerClass);
112     }
113 
114 
115     public void setAbstract(boolean abstractz) {
116         addOrRemoveModifier(ObjectModelJavaModifier.ABSTRACT, abstractz);
117     }
118 
119     @Override
120     public Collection<ObjectModelClass> getSuperclasses() {
121         if (superclasses == null) {
122             superclasses = new ArrayList<>();
123             for (ObjectModelImplRef superclassesRef : superclassesRefs) {
124                 ObjectModelImplSuperClassRef ref = (ObjectModelImplSuperClassRef) superclassesRef;
125 
126                 if (log.isDebugEnabled()) {
127                     log.debug("Superclass ref for " + getQualifiedName() + " : " + ref.getName());
128                 }
129 
130                 ObjectModelClass superclass = objectModelImpl.getClass(ref.getName());
131                 if (superclass == null) {
132                     ExternalCacheExtension cache = objectModelImpl.getExtension(
133                             ExternalCacheExtension.OBJECTMODEL_EXTENSION, ExternalCacheExtension.class);
134 
135                     superclass = cache.getCache(ref, ObjectModelClassImpl.class);
136                 }
137 
138                 if (log.isDebugEnabled()) {
139                     log.debug("Superclass for " + getQualifiedName() + " : " + superclass.getQualifiedName());
140                 }
141 
142                 superclasses.add(superclass);
143                 superclassesDiscriminators.put(superclass, ref.getDiscriminator());
144             }
145         }
146         return superclasses;
147     }
148 
149     @Override
150     public Collection<ObjectModelClassifier> getInnerClassifiers() {
151         return innerClasses;
152     }
153 
154     /**
155      * Returns the discriminator for the given superclass.
156      *
157      * @return the discriminator for the given superclass as a String if it exists, null otherwise.
158      */
159     @Override
160     public String getDiscriminator(ObjectModelClass superclass) {
161         return superclassesDiscriminators.get(superclass);
162     }
163 
164     /**
165      * Returns all known direct specialized classes for this class.
166      *
167      * @return a Collection containing all known direct specialized ObjectModelClass for this class.
168      * @see ObjectModelClass
169      */
170     @Override
171     public Collection<ObjectModelClass> getSpecialisations() {
172         if (specialisations == null) {
173             specialisations = new ArrayList<>();
174             for (Object o : objectModelImpl.getClasses()) {
175                 ObjectModelClass candidateClass = (ObjectModelClass) o;
176                 if (candidateClass.getSuperclasses().contains(this)) {
177                     specialisations.add(candidateClass);
178                 }
179             }
180         }
181         return specialisations;
182     }
183 
184     /**
185      * Returns all known specialized classes for this class for the specified discriminator.
186      *
187      * @return a Collection containing all known specialized ObjectModelClass
188      * for this class for the specified discriminator.
189      * @see ObjectModelClass
190      */
191     @Override
192     public Collection<ObjectModelClass> getSpecialisations(String discriminator) {
193         List<ObjectModelClass> discriminatedSpecialisations = new ArrayList<>();
194         for (ObjectModelClass candidateClass : getSpecialisations()) {
195             if (discriminator.equals(candidateClass.getDiscriminator(this))) {
196                 discriminatedSpecialisations.add(candidateClass);
197             }
198         }
199         return discriminatedSpecialisations;
200     }
201 
202     /**
203      * Returns whether this class is abstract or not.
204      *
205      * @return a boolean indicating whether this class is abstract or not.
206      */
207     @Override
208     public boolean isAbstract() {
209         return modifiers.contains(ObjectModelJavaModifier.ABSTRACT);
210     }
211 
212     @Override
213     public Collection<ObjectModelOperation> getAllOtherOperations(
214             boolean distinct) {
215         Collection<ObjectModelOperation> result = getAllInterfaceOperations(distinct);
216         getAllSuperclassOperations(result);
217         return result;
218     }
219 
220     @Override
221     public Collection<ObjectModelOperation> getAllSuperclassOperations(
222             boolean distinct) {
223         Collection<ObjectModelOperation> result;
224         if (distinct) {
225             result = new HashSet<>();
226         } else {
227             result = new LinkedList<>();
228         }
229         getAllSuperclassOperations(result);
230         return result;
231     }
232 
233     protected Collection<ObjectModelOperation> getAllSuperclassOperations(
234             Collection<ObjectModelOperation> result) {
235         for (Object o : getSuperclasses()) {
236             ObjectModelClassImpl clazz = (ObjectModelClassImpl) o;
237             result.addAll(clazz.getOperations());
238             clazz.getAllSuperclassOperations(result);
239             clazz.getAllInterfaceOperations(result);
240         }
241         return result;
242     }
243 
244     @Override
245     public Collection<ObjectModelAttribute> getAllOtherAttributes() {
246         Collection<ObjectModelAttribute> result = getAllInterfaceAttributes();
247         getAllOtherAttributes(result);
248         return result;
249     }
250 
251     protected Collection<ObjectModelAttribute> getAllOtherAttributes(
252             Collection<ObjectModelAttribute> result) {
253         for (Object o : getSuperclasses()) {
254             ObjectModelClassImpl clazz = (ObjectModelClassImpl) o;
255             result.addAll(clazz.getAttributes());
256             clazz.getAllOtherAttributes(result);
257         }
258         return result;
259     }
260 
261     @Override
262     public String toString() {
263         StringBuffer result = new StringBuffer();
264         result.append("class ").append(getQualifiedName()).append("<<").append(getStereotypes()).append(">> tagvalue: ").append(getTagValues()).append(" ");
265         result.append("extends ");
266         for (Iterator<?> i = getSuperclasses().iterator(); i.hasNext(); ) {
267             result.append(((ObjectModelClassifier) i.next()).getName());
268             if (i.hasNext()) {
269                 result.append(", ");
270             }
271         }
272         result.append("implements ");
273         for (Iterator<?> i = getInterfaces().iterator(); i.hasNext(); ) {
274             result.append(((ObjectModelClassifier) i.next()).getName());
275             if (i.hasNext()) {
276                 result.append(", ");
277             }
278         }
279         return result.toString();
280     }
281 
282 }