View Javadoc
1   package org.codehaus.modello.model;
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 java.util.ArrayList;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  
30  import org.codehaus.modello.ModelloRuntimeException;
31  import org.codehaus.modello.metadata.ClassMetadata;
32  import org.codehaus.plexus.util.StringUtils;
33  
34  /**
35   * @author <a href="mailto:jason@modello.org">Jason van Zyl</a>
36   * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
37   */
38  public class ModelClass extends ModelType {
39      private String superClass;
40  
41      private boolean isInternalSuperClass;
42  
43      private List<String> interfaces;
44  
45      private List<ModelField> fields;
46  
47      private transient Map<String, List<ModelField>> fieldMap = new HashMap<String, List<ModelField>>();
48  
49      public ModelClass() {
50          super();
51      }
52  
53      public ModelClass(Model model, String name) {
54          super(model, name);
55      }
56  
57      public String getSuperClass() {
58          return superClass;
59      }
60  
61      public void setSuperClass(String superClass) {
62          this.superClass = superClass;
63      }
64  
65      // ----------------------------------------------------------------------
66      // Interfaces
67      // ----------------------------------------------------------------------
68  
69      /**
70       * Returns the list of all interfaces of this class.
71       *
72       * @return Returns the list of all interfaces of this class.
73       */
74      public List<String> getInterfaces() {
75          if (interfaces == null) {
76              interfaces = new ArrayList<String>();
77          }
78  
79          return interfaces;
80      }
81  
82      public void addInterface(String modelInterface) {
83          if (getInterfaces().contains(modelInterface)) {
84              throw new ModelloRuntimeException("Duplicate interface in " + getName() + ": " + modelInterface + ".");
85          }
86  
87          getInterfaces().add(modelInterface);
88      }
89  
90      // ----------------------------------------------------------------------
91      // Field
92      // ----------------------------------------------------------------------
93  
94      /**
95       * {@inheritDoc}
96       */
97      public List<ModelField> getAllFields() {
98          if (fields == null) {
99              fields = new ArrayList<ModelField>();
100         }
101 
102         return fields;
103     }
104 
105     /**
106      * Returns all the fields in this class and all super classes if withInheritedField equals to true.
107      *
108      * @return Returns all the fields in this class and all super classes.
109      */
110     public List<ModelField> getAllFields(boolean withInheritedField) {
111         if (!withInheritedField) {
112             return getAllFields();
113         }
114 
115         List<ModelField> fields = new ArrayList<ModelField>(getAllFields());
116 
117         ModelClass c = this;
118 
119         while (c.hasSuperClass() && c.isInternalSuperClass()) {
120             ModelClass parent = getModel().getClass(c.getSuperClass(), getVersionRange());
121 
122             fields.addAll(parent.getAllFields());
123 
124             c = parent;
125         }
126 
127         return fields;
128     }
129 
130     public ModelField getField(String type, VersionRange versionRange) {
131         List<ModelField> fieldList = fieldMap.get(type);
132 
133         if (fieldList != null) {
134             for (ModelField modelField : fieldList) {
135                 if (versionRange.getFromVersion().inside(modelField.getVersionRange())
136                         && versionRange.getToVersion().inside(modelField.getVersionRange())) {
137                     return modelField;
138                 }
139             }
140         }
141 
142         throw new ModelloRuntimeException(
143                 "There are no field '" + type + "' in version range '" + versionRange.toString() + "'.");
144     }
145 
146     public void addField(ModelField modelField) {
147         if (fieldMap.containsKey(modelField.getName())) {
148             List<ModelField> fieldList = fieldMap.get(modelField.getName());
149 
150             for (ModelField currentField : fieldList) {
151                 if (VersionUtil.isInConflict(modelField.getVersionRange(), currentField.getVersionRange())) {
152                     throw new ModelloRuntimeException(
153                             "Duplicate field in " + getName() + ": " + modelField.getName() + ".");
154                 }
155             }
156         } else {
157             List<ModelField> fieldList = new ArrayList<ModelField>();
158 
159             fieldMap.put(modelField.getName(), fieldList);
160         }
161 
162         getAllFields().add(modelField);
163 
164         fieldMap.get(modelField.getName()).add(modelField);
165     }
166 
167     // ----------------------------------------------------------------------
168     //
169     // ----------------------------------------------------------------------
170 
171     public boolean hasSuperClass() {
172         return StringUtils.isNotEmpty(superClass);
173     }
174 
175     public boolean isInternalSuperClass() {
176         return isInternalSuperClass;
177     }
178 
179     public ClassMetadata getMetadata(String key) {
180         return getMetadata(ClassMetadata.class, key);
181     }
182 
183     public void initialize(Model model) {
184         super.initialize(model);
185 
186         for (ModelField modelField : getAllFields()) {
187             modelField.initialize(this);
188         }
189     }
190 
191     public void validateElement() throws ModelValidationException {
192         // Check if superClass exists
193         if (hasSuperClass()) {
194             try {
195                 getModel().getClass(superClass, getVersionRange());
196                 isInternalSuperClass = true;
197             } catch (ModelloRuntimeException e) {
198                 isInternalSuperClass = false;
199             }
200         }
201 
202         if (getModel().getDefault(ModelDefault.CHECK_DEPRECATION).getBoolean()) {
203             if (!Version.INFINITE.equals(getVersionRange().getToVersion()) && getDeprecatedVersion() == null) {
204                 throw new ModelValidationException(
205                         "You must define the deprecated version of '" + getName() + "' class.");
206             }
207         }
208     }
209 
210     // ----------------------------------------------------------------------
211     // Object Overrides
212     // ----------------------------------------------------------------------
213 
214     public boolean equals(Object o) {
215         if (!super.equals(o)) {
216             return false;
217         }
218 
219         if (!(o instanceof ModelClass)) {
220             return false;
221         }
222 
223         ModelClass other = (ModelClass) o;
224 
225         return getPackageName().equals(other.getPackageName());
226     }
227 
228     public int hashCode() {
229         int hashCode = getName().hashCode();
230 
231         if (!StringUtils.isEmpty(getPackageName())) {
232             hashCode += 37 * getPackageName().hashCode();
233         }
234 
235         return hashCode;
236     }
237 }