View Javadoc

1   package org.codehaus.modello.core.io;
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.ModelloException;
26  import org.codehaus.modello.model.BaseElement;
27  import org.codehaus.modello.model.CodeSegment;
28  import org.codehaus.modello.model.Model;
29  import org.codehaus.modello.model.ModelAssociation;
30  import org.codehaus.modello.model.ModelClass;
31  import org.codehaus.modello.model.ModelDefault;
32  import org.codehaus.modello.model.ModelField;
33  import org.codehaus.modello.model.ModelInterface;
34  import org.codehaus.modello.model.VersionDefinition;
35  import org.codehaus.modello.model.VersionRange;
36  import org.codehaus.plexus.util.xml.pull.MXParser;
37  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
38  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39  
40  import java.io.IOException;
41  import java.io.Reader;
42  import java.util.HashMap;
43  import java.util.Map;
44  import java.util.ArrayList;
45  import java.util.List;
46  
47  /**
48   * @author <a href="mailto:trygvis@inamo.no">Trygve Laugst&oslash;l</a>
49   * @author <a href="mailto:evenisse@codehaus.org">Emmanuel Venisse</a>
50   */
51  public class ModelReader
52  {
53      private Map<String, String> modelAttributes = new HashMap<String, String>();
54  
55      private Map<String, Map<String, String>> classAttributes = new HashMap<String, Map<String, String>>();
56  
57      private Map<String, Map<String, String>> interfaceAttributes = new HashMap<String, Map<String, String>>();
58  
59      private Map<String, Map<String, String>> fieldAttributes = new HashMap<String, Map<String, String>>();
60  
61      private Map<String, Map<String, String>> associationAttributes = new HashMap<String, Map<String, String>>();
62  
63      public Map<String, String> getAttributesForModel()
64      {
65          return modelAttributes;
66      }
67  
68      public Map<String, String> getAttributesForClass( ModelClass modelClass )
69      {
70          return classAttributes.get( modelClass.getName() );
71      }
72  
73      public Map<String, String> getAttributesForInterface( ModelInterface modelInterface )
74      {
75          return interfaceAttributes.get( modelInterface.getName() );
76      }
77  
78      public Map<String, String> getAttributesForField( ModelField modelField )
79      {
80          return fieldAttributes.get( modelField.getModelClass().getName() + ':' + modelField.getName() + ':'
81              + modelField.getVersionRange() );
82      }
83  
84      public Map<String, String> getAttributesForAssociation( ModelAssociation modelAssociation )
85      {
86          return associationAttributes.get( modelAssociation.getModelClass().getName() + ':' + modelAssociation.getName()
87              + ':' + modelAssociation.getVersionRange() );
88      }
89  
90      public Model loadModel( Reader reader )
91          throws ModelloException
92      {
93          try
94          {
95              Model model = new Model();
96  
97              XmlPullParser parser = new MXParser();
98  
99              parser.setInput( reader );
100 
101             parseModel( model, parser );
102 
103             return model;
104         }
105         catch ( IOException ex )
106         {
107             throw new ModelloException( "Error parsing the model.", ex );
108         }
109         catch ( XmlPullParserException ex )
110         {
111             throw new ModelloException( "Error parsing the model.", ex );
112         }
113     }
114 
115     public void parseModel( Model model, XmlPullParser parser )
116         throws XmlPullParserException, IOException
117     {
118         int eventType = parser.getEventType();
119 
120         while ( eventType != XmlPullParser.END_DOCUMENT )
121         {
122             if ( eventType == XmlPullParser.START_TAG )
123             {
124                 if ( parseBaseElement( model, parser ) )
125                 {
126                 }
127                 else if ( "id".equals( parser.getName() ) )
128                 {
129                     model.setId( parser.nextText() );
130                 }
131                 else if ( "defaults".equals( parser.getName() ) )
132                 {
133                     parseDefaults( model, parser );
134                 }
135                 else if ( "versionDefinition".equals( parser.getName() ) )
136                 {
137                     parseVersionDefinition( model, parser );
138                 }
139                 else if ( "interfaces".equals( parser.getName() ) )
140                 {
141                     parseInterfaces( model, parser );
142                 }
143                 else if ( "classes".equals( parser.getName() ) )
144                 {
145                     parseClasses( model, parser );
146                 }
147                 else if ( "model".equals( parser.getName() ) )
148                 {
149                     modelAttributes = getAttributes( parser );
150                 }
151                 else
152                 {
153 //                    parser.nextText();
154                 }
155             }
156             eventType = parser.next();
157         }
158     }
159 
160     private void parseDefaults( Model model, XmlPullParser parser )
161         throws XmlPullParserException, IOException
162     {
163         while ( parser.nextTag() == XmlPullParser.START_TAG )
164         {
165             if ( "default".equals( parser.getName() ) )
166             {
167                 ModelDefault modelDefault = new ModelDefault();
168 
169                 while ( parser.nextTag() == XmlPullParser.START_TAG )
170                 {
171                     if ( "key".equals( parser.getName() ) )
172                     {
173                         modelDefault.setKey( parser.nextText() );
174                     }
175                     else if ( "value".equals( parser.getName() ) )
176                     {
177                         modelDefault.setValue( parser.nextText() );
178                     }
179                     else
180                     {
181                         parser.nextText();
182                     }
183                 }
184 
185                 model.addDefault( modelDefault );
186             }
187             else
188             {
189                 parser.next();
190             }
191         }
192     }
193 
194     private void parseVersionDefinition( Model model, XmlPullParser parser )
195         throws XmlPullParserException, IOException
196     {
197         if ( "versionDefinition".equals( parser.getName() ) )
198         {
199             VersionDefinition versionDefinition = new VersionDefinition();
200 
201             while ( parser.nextTag() == XmlPullParser.START_TAG )
202             {
203                 if ( "type".equals( parser.getName() ) )
204                 {
205                     versionDefinition.setType( parser.nextText() );
206                 }
207                 else if ( "value".equals( parser.getName() ) )
208                 {
209                     versionDefinition.setValue( parser.nextText() );
210                 }
211                 else
212                 {
213                     parser.nextText();
214                 }
215             }
216 
217             model.setVersionDefinition( versionDefinition );
218         }
219     }
220 
221     private void parseInterfaces( Model model, XmlPullParser parser )
222         throws XmlPullParserException, IOException
223     {
224         while ( parser.nextTag() == XmlPullParser.START_TAG )
225         {
226             if ( "interface".equals( parser.getName() ) )
227             {
228                 ModelInterface modelInterface = new ModelInterface();
229 
230                 Map<String, String> attributes = getAttributes( parser );
231 
232                 while ( parser.nextTag() == XmlPullParser.START_TAG )
233                 {
234                     if ( parseBaseElement( modelInterface, parser ) )
235                     {
236                     }
237                     else if ( "superInterface".equals( parser.getName() ) )
238                     {
239                         modelInterface.setSuperInterface( parser.nextText() );
240                     }
241                     else if ( "packageName".equals( parser.getName() ) )
242                     {
243                         modelInterface.setPackageName( parser.nextText() );
244                     }
245                     else if ( "codeSegments".equals( parser.getName() ) )
246                     {
247                         parseCodeSegment( modelInterface, parser );
248                     }
249                     else
250                     {
251                         parser.nextText();
252                     }
253                 }
254 
255                 model.addInterface( modelInterface );
256                 interfaceAttributes.put( modelInterface.getName(), attributes );
257             }
258             else
259             {
260                 parser.next();
261             }
262         }
263     }
264 
265     private void parseClasses( Model model, XmlPullParser parser )
266         throws XmlPullParserException, IOException
267     {
268         while ( parser.nextTag() == XmlPullParser.START_TAG )
269         {
270             if ( "class".equals( parser.getName() ) )
271             {
272                 ModelClass modelClass = new ModelClass();
273 
274                 Map<String, String> attributes = getAttributes( parser );
275 
276                 while ( parser.nextTag() == XmlPullParser.START_TAG )
277                 {
278                     if ( parseBaseElement( modelClass, parser ) )
279                     {
280                     }
281                     else if ( "interfaces".equals( parser.getName() ) )
282                     {
283                         parseClassInterfaces( modelClass, parser );
284                     }
285                     else if ( "superClass".equals( parser.getName() ) )
286                     {
287                         modelClass.setSuperClass( parser.nextText() );
288                     }
289                     else if ( "packageName".equals( parser.getName() ) )
290                     {
291                         modelClass.setPackageName( parser.nextText() );
292                     }
293                     else if ( "fields".equals( parser.getName() ) )
294                     {
295                         parseFields( modelClass, parser );
296                     }
297                     else if ( "codeSegments".equals( parser.getName() ) )
298                     {
299                         parseCodeSegment( modelClass, parser );
300                     }
301                     else
302                     {
303                         parser.nextText();
304                     }
305                 }
306 
307                 model.addClass( modelClass );
308                 classAttributes.put( modelClass.getName(), attributes );
309             }
310             else
311             {
312                 parser.next();
313             }
314         }
315     }
316 
317     private void parseClassInterfaces( ModelClass modelClass, XmlPullParser parser )
318         throws IOException, XmlPullParserException
319     {
320         while ( parser.nextTag() == XmlPullParser.START_TAG )
321         {
322             if ( "interface".equals( parser.getName() ) )
323             {
324                 modelClass.addInterface( parser.nextText() );
325             }
326             else
327             {
328                 parser.nextText();
329             }
330         }
331     }
332 
333     private void parseFields( ModelClass modelClass, XmlPullParser parser )
334         throws XmlPullParserException, IOException
335     {
336         while ( parser.nextTag() == XmlPullParser.START_TAG )
337         {
338             if ( "field".equals( parser.getName() ) )
339             {
340                 ModelField modelField = new ModelField();
341 
342                 ModelAssociation modelAssociation = null;
343 
344                 Map<String, String> fAttributes = getAttributes( parser );
345 
346                 Map<String, String> aAttributes = new HashMap<String, String>();
347 
348                 while ( parser.nextTag() == XmlPullParser.START_TAG )
349                 {
350                     if ( parseBaseElement( modelField, parser ) )
351                     {
352                     }
353                     else if ( "association".equals( parser.getName() ) )
354                     {
355                         aAttributes = getAttributes( parser );
356 
357                         modelAssociation = parseAssociation( parser );
358                     }
359                     else if ( "alias".equals( parser.getName() ) )
360                     {
361                         modelField.setAlias( parser.nextText() );
362                     }
363                     else if ( "type".equals( parser.getName() ) )
364                     {
365                         modelField.setType( parser.nextText() );
366                     }
367                     else if ( "defaultValue".equals( parser.getName() ) )
368                     {
369                         modelField.setDefaultValue( parser.nextText() );
370                     }
371                     else if ( "typeValidator".equals( parser.getName() ) )
372                     {
373                         modelField.setTypeValidator( parser.nextText() );
374                     }
375                     else if ( "required".equals( parser.getName() ) )
376                     {
377                         modelField.setRequired( Boolean.valueOf( parser.nextText() ) );
378                     }
379                     else if ( "identifier".equals( parser.getName() ) )
380                     {
381                         modelField.setIdentifier( Boolean.valueOf( parser.nextText() ).booleanValue() );
382                     }
383                     else
384                     {
385                         parser.nextText();
386                     }
387                 }
388 
389                 if ( modelField.getName() != null )
390                 {
391                     fieldAttributes.put(
392                         modelClass.getName() + ":" + modelField.getName() + ":" + modelField.getVersionRange(),
393                         fAttributes );
394                 }
395 
396                 if ( modelAssociation != null )
397                 {
398                     // Base element
399                     modelAssociation.setName( modelField.getName() );
400 
401                     modelAssociation.setDescription( modelField.getDescription() );
402 
403                     modelAssociation.setVersionRange( modelField.getVersionRange() );
404 
405                     modelAssociation.setComment( modelField.getComment() );
406 
407                     modelAssociation.setAnnotations( modelField.getAnnotations() );
408 
409                     // model field fields
410                     modelAssociation.setType( modelField.getType() );
411 
412                     modelAssociation.setAlias( modelField.getAlias() );
413 
414                     modelAssociation.setDefaultValue( modelField.getDefaultValue() );
415 
416                     modelAssociation.setTypeValidator( modelField.getTypeValidator() );
417 
418                     modelAssociation.setRequired( modelField.isRequired() );
419 
420                     modelAssociation.setIdentifier( modelField.isIdentifier() );
421 
422                     if ( modelAssociation.getName() != null )
423                     {
424                         associationAttributes.put( modelClass.getName() + ":" + modelAssociation.getName() + ":"
425                                                    + modelAssociation.getVersionRange(), aAttributes );
426                     }
427 
428                     modelClass.addField( modelAssociation );
429                 }
430                 else
431                 {
432                     modelClass.addField( modelField );
433                 }
434             }
435             else
436             {
437                 parser.next();
438             }
439         }
440     }
441 
442     private ModelAssociation parseAssociation( XmlPullParser parser )
443         throws XmlPullParserException, IOException
444     {
445         ModelAssociation modelAssociation = new ModelAssociation();
446 
447         while ( parser.nextTag() == XmlPullParser.START_TAG )
448         {
449             if ( parseBaseElement( modelAssociation, parser ) )
450             {
451             }
452             else if ( "type".equals( parser.getName() ) )
453             {
454                 modelAssociation.setTo( parser.nextText() );
455             }
456             else if ( "multiplicity".equals( parser.getName() ) )
457             {
458                 modelAssociation.setMultiplicity( parser.nextText() );
459             }
460             else
461             {
462                 parser.nextText();
463             }
464         }
465 
466         return modelAssociation;
467     }
468 
469     private void parseCodeSegment( ModelClass modelClass, XmlPullParser parser )
470         throws XmlPullParserException, IOException
471     {
472         while ( parser.nextTag() == XmlPullParser.START_TAG )
473         {
474             if ( "codeSegment".equals( parser.getName() ) )
475             {
476                 CodeSegment codeSegment = new CodeSegment();
477 
478                 while ( parser.nextTag() == XmlPullParser.START_TAG )
479                 {
480                     if ( parseBaseElement( codeSegment, parser ) )
481                     {
482                     }
483                     else if ( "code".equals( parser.getName() ) )
484                     {
485                         codeSegment.setCode( parser.nextText() );
486                     }
487                     else
488                     {
489                         parser.nextText();
490                     }
491                 }
492 
493                 modelClass.addCodeSegment( codeSegment );
494             }
495             else
496             {
497                 parser.next();
498             }
499         }
500     }
501 
502     private void parseCodeSegment( ModelInterface modelInterface, XmlPullParser parser )
503         throws XmlPullParserException, IOException
504     {
505         while ( parser.nextTag() == XmlPullParser.START_TAG )
506         {
507             if ( "codeSegment".equals( parser.getName() ) )
508             {
509                 CodeSegment codeSegment = new CodeSegment();
510 
511                 while ( parser.nextTag() == XmlPullParser.START_TAG )
512                 {
513                     if ( parseBaseElement( codeSegment, parser ) )
514                     {
515                     }
516                     else if ( "code".equals( parser.getName() ) )
517                     {
518                         codeSegment.setCode( parser.nextText() );
519                     }
520                     else
521                     {
522                         parser.nextText();
523                     }
524                 }
525 
526                 modelInterface.addCodeSegment( codeSegment );
527             }
528             else
529             {
530                 parser.next();
531             }
532         }
533     }
534 
535     private boolean parseBaseElement( BaseElement element, XmlPullParser parser )
536         throws XmlPullParserException, IOException
537     {
538         if ( "name".equals( parser.getName() ) )
539         {
540             element.setName( parser.nextText() );
541         }
542         else if ( "description".equals( parser.getName() ) )
543         {
544             element.setDescription( parser.nextText() );
545         }
546         else if ( "version".equals( parser.getName() ) )
547         {
548             element.setVersionRange( new VersionRange( parser.nextText() ) );
549         }
550         else if ( "comment".equals( parser.getName() ) )
551         {
552             element.setComment( parser.nextText() );
553         }
554         else if ( "annotations".equals( parser.getName() ) )
555         {
556             List<String> annotationsList = new ArrayList<String>();
557             while ( parser.nextTag() == XmlPullParser.START_TAG )
558             {
559                 if ( "annotation".equals( parser.getName() ) )
560                 {
561                     annotationsList.add( parser.nextText() );
562                 }
563             }
564             element.setAnnotations( annotationsList );
565         }
566         else
567         {
568             return false;
569         }
570 
571         return true;
572     }
573 
574     private Map<String, String> getAttributes( XmlPullParser parser )
575     {
576         Map<String, String> attributes = new HashMap<String, String>();
577 
578         for ( int i = 0; i < parser.getAttributeCount(); i++ )
579         {
580             String name = parser.getAttributeName( i );
581 
582             String value = parser.getAttributeValue( i );
583 
584             attributes.put( name, value );
585         }
586 
587         return attributes;
588     }
589 }