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