View Javadoc
1   /*
2    Licensed to the Apache Software Foundation (ASF) under one
3    or more contributor license agreements.  See the NOTICE file
4    distributed with this work for additional information
5    regarding copyright ownership.  The ASF licenses this file
6    to you under the Apache License, Version 2.0 (the
7    "License"); you may not use this file except in compliance
8    with the License.  You may obtain a copy of the License at
9    
10       http://www.apache.org/licenses/LICENSE-2.0
11   
12   Unless required by applicable law or agreed to in writing,
13   software distributed under the License is distributed on an
14   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   KIND, either express or implied.  See the License for the
16   specific language governing permissions and limitations
17   under the License.
18   =================== DO NOT EDIT THIS FILE ====================
19   Generated by Modello 2.5.1,
20   any modifications will be overwritten.
21   ==============================================================
22   */
23  
24  package org.apache.maven.plugins.pmd.model.io.xpp3;
25  
26    //---------------------------------/
27   //- Imported classes and packages -/
28  //---------------------------------/
29  
30  import java.io.IOException;
31  import java.io.InputStream;
32  import java.io.Reader;
33  import java.text.DateFormat;
34  import org.apache.maven.plugins.pmd.model.CpdErrorDetail;
35  import org.apache.maven.plugins.pmd.model.CpdFile;
36  import org.apache.maven.plugins.pmd.model.Duplication;
37  import org.codehaus.plexus.util.xml.XmlStreamReader;
38  import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
39  import org.codehaus.plexus.util.xml.pull.MXParser;
40  import org.codehaus.plexus.util.xml.pull.XmlPullParser;
41  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
42  
43  /**
44   * Class CpdXpp3Reader.
45   * 
46   * @version $Revision$ $Date$
47   */
48  @SuppressWarnings( "all" )
49  public class CpdXpp3Reader
50  {
51  
52        //--------------------------/
53       //- Class/Member Variables -/
54      //--------------------------/
55  
56      /**
57       * If set the parser will be loaded with all single characters
58       * from the XHTML specification.
59       * The entities used:
60       * <ul>
61       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li>
62       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li>
63       * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li>
64       * </ul>
65       */
66      private boolean addDefaultEntities = true;
67  
68      /**
69       * Field contentTransformer.
70       */
71      public final ContentTransformer contentTransformer;
72  
73  
74        //----------------/
75       //- Constructors -/
76      //----------------/
77  
78      public CpdXpp3Reader()
79      {
80          this( new ContentTransformer()
81          {
82              public String transform( String source, String fieldName )
83              {
84                  return source;
85              }
86          } );
87      } //-- org.apache.maven.plugins.pmd.model.io.xpp3.CpdXpp3Reader()
88  
89      public CpdXpp3Reader(ContentTransformer contentTransformer)
90      {
91          this.contentTransformer = contentTransformer;
92      } //-- org.apache.maven.plugins.pmd.model.io.xpp3.CpdXpp3Reader(ContentTransformer)
93  
94  
95        //-----------/
96       //- Methods -/
97      //-----------/
98  
99      /**
100      * Method checkFieldWithDuplicate.
101      * 
102      * @param parser a parser object.
103      * @param parsed a parsed object.
104      * @param alias a alias object.
105      * @param tagName a tagName object.
106      * @throws XmlPullParserException XmlPullParserException if
107      * any.
108      * @return boolean
109      */
110     private boolean checkFieldWithDuplicate( XmlPullParser parser, String tagName, String alias, java.util.Set<String> parsed )
111         throws XmlPullParserException
112     {
113         if ( !( parser.getName().equals( tagName ) || parser.getName().equals( alias ) ) )
114         {
115             return false;
116         }
117         if ( !parsed.add( tagName ) )
118         {
119             throw new XmlPullParserException( "Duplicated tag: '" + tagName + "'", parser, null );
120         }
121         return true;
122     } //-- boolean checkFieldWithDuplicate( XmlPullParser, String, String, java.util.Set )
123 
124     /**
125      * Method checkUnknownAttribute.
126      * 
127      * @param parser a parser object.
128      * @param strict a strict object.
129      * @param tagName a tagName object.
130      * @param attribute a attribute object.
131      * @throws XmlPullParserException XmlPullParserException if
132      * any.
133      * @throws IOException IOException if any.
134      */
135     private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
136         throws XmlPullParserException, IOException
137     {
138         // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
139         if ( strict )
140         {
141             throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
142         }
143     } //-- void checkUnknownAttribute( XmlPullParser, String, String, boolean )
144 
145     /**
146      * Method checkUnknownElement.
147      * 
148      * @param parser a parser object.
149      * @param strict a strict object.
150      * @throws XmlPullParserException XmlPullParserException if
151      * any.
152      * @throws IOException IOException if any.
153      */
154     private void checkUnknownElement( XmlPullParser parser, boolean strict )
155         throws XmlPullParserException, IOException
156     {
157         if ( strict )
158         {
159             throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
160         }
161 
162         for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
163         {
164             int eventType = parser.next();
165             if ( eventType == XmlPullParser.START_TAG )
166             {
167                 unrecognizedTagCount++;
168             }
169             else if ( eventType == XmlPullParser.END_TAG )
170             {
171                 unrecognizedTagCount--;
172             }
173         }
174     } //-- void checkUnknownElement( XmlPullParser, boolean )
175 
176     /**
177      * Returns the state of the "add default entities" flag.
178      * 
179      * @return boolean
180      */
181     public boolean getAddDefaultEntities()
182     {
183         return addDefaultEntities;
184     } //-- boolean getAddDefaultEntities()
185 
186     /**
187      * Method getBooleanValue.
188      * 
189      * @param s a s object.
190      * @param parser a parser object.
191      * @param attribute a attribute object.
192      * @throws XmlPullParserException XmlPullParserException if
193      * any.
194      * @return boolean
195      */
196     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser )
197         throws XmlPullParserException
198     {
199         return getBooleanValue( s, attribute, parser, null );
200     } //-- boolean getBooleanValue( String, String, XmlPullParser )
201 
202     /**
203      * Method getBooleanValue.
204      * 
205      * @param s a s object.
206      * @param defaultValue a defaultValue object.
207      * @param parser a parser object.
208      * @param attribute a attribute object.
209      * @throws XmlPullParserException XmlPullParserException if
210      * any.
211      * @return boolean
212      */
213     private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, String defaultValue )
214         throws XmlPullParserException
215     {
216         if ( s != null && s.length() != 0 )
217         {
218             return Boolean.valueOf( s ).booleanValue();
219         }
220         if ( defaultValue != null )
221         {
222             return Boolean.valueOf( defaultValue ).booleanValue();
223         }
224         return false;
225     } //-- boolean getBooleanValue( String, String, XmlPullParser, String )
226 
227     /**
228      * Method getByteValue.
229      * 
230      * @param s a s object.
231      * @param strict a strict object.
232      * @param parser a parser object.
233      * @param attribute a attribute object.
234      * @throws XmlPullParserException XmlPullParserException if
235      * any.
236      * @return byte
237      */
238     private byte getByteValue( String s, String attribute, XmlPullParser parser, boolean strict )
239         throws XmlPullParserException
240     {
241         if ( s != null )
242         {
243             try
244             {
245                 return Byte.valueOf( s ).byteValue();
246             }
247             catch ( NumberFormatException nfe )
248             {
249                 if ( strict )
250                 {
251                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a byte", parser, nfe );
252                 }
253             }
254         }
255         return 0;
256     } //-- byte getByteValue( String, String, XmlPullParser, boolean )
257 
258     /**
259      * Method getCharacterValue.
260      * 
261      * @param s a s object.
262      * @param parser a parser object.
263      * @param attribute a attribute object.
264      * @throws XmlPullParserException XmlPullParserException if
265      * any.
266      * @return char
267      */
268     private char getCharacterValue( String s, String attribute, XmlPullParser parser )
269         throws XmlPullParserException
270     {
271         if ( s != null )
272         {
273             return s.charAt( 0 );
274         }
275         return 0;
276     } //-- char getCharacterValue( String, String, XmlPullParser )
277 
278     /**
279      * Method getDateValue.
280      * 
281      * @param s a s object.
282      * @param parser a parser object.
283      * @param attribute a attribute object.
284      * @throws XmlPullParserException XmlPullParserException if
285      * any.
286      * @return Date
287      */
288     private java.util.Date getDateValue( String s, String attribute, XmlPullParser parser )
289         throws XmlPullParserException
290     {
291         return getDateValue( s, attribute, null, parser );
292     } //-- java.util.Date getDateValue( String, String, XmlPullParser )
293 
294     /**
295      * Method getDateValue.
296      * 
297      * @param s a s object.
298      * @param parser a parser object.
299      * @param dateFormat a dateFormat object.
300      * @param attribute a attribute object.
301      * @throws XmlPullParserException XmlPullParserException if
302      * any.
303      * @return Date
304      */
305     private java.util.Date getDateValue( String s, String attribute, String dateFormat, XmlPullParser parser )
306         throws XmlPullParserException
307     {
308         if ( s != null )
309         {
310             String effectiveDateFormat = dateFormat;
311             if ( dateFormat == null )
312             {
313                 effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
314             }
315             if ( "long".equals( effectiveDateFormat ) )
316             {
317                 try
318                 {
319                     return new java.util.Date( Long.parseLong( s ) );
320                 }
321                 catch ( NumberFormatException e )
322                 {
323                     throw new XmlPullParserException( e.getMessage(), parser, e );
324                 }
325             }
326             else
327             {
328                 try
329                 {
330                     DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, java.util.Locale.US );
331                     return dateParser.parse( s );
332                 }
333                 catch ( java.text.ParseException e )
334                 {
335                     throw new XmlPullParserException( e.getMessage(), parser, e );
336                 }
337             }
338         }
339         return null;
340     } //-- java.util.Date getDateValue( String, String, String, XmlPullParser )
341 
342     /**
343      * Method getDoubleValue.
344      * 
345      * @param s a s object.
346      * @param strict a strict object.
347      * @param parser a parser object.
348      * @param attribute a attribute object.
349      * @throws XmlPullParserException XmlPullParserException if
350      * any.
351      * @return double
352      */
353     private double getDoubleValue( String s, String attribute, XmlPullParser parser, boolean strict )
354         throws XmlPullParserException
355     {
356         if ( s != null )
357         {
358             try
359             {
360                 return Double.valueOf( s ).doubleValue();
361             }
362             catch ( NumberFormatException nfe )
363             {
364                 if ( strict )
365                 {
366                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
367                 }
368             }
369         }
370         return 0;
371     } //-- double getDoubleValue( String, String, XmlPullParser, boolean )
372 
373     /**
374      * Method getFloatValue.
375      * 
376      * @param s a s object.
377      * @param strict a strict object.
378      * @param parser a parser object.
379      * @param attribute a attribute object.
380      * @throws XmlPullParserException XmlPullParserException if
381      * any.
382      * @return float
383      */
384     private float getFloatValue( String s, String attribute, XmlPullParser parser, boolean strict )
385         throws XmlPullParserException
386     {
387         if ( s != null )
388         {
389             try
390             {
391                 return Float.valueOf( s ).floatValue();
392             }
393             catch ( NumberFormatException nfe )
394             {
395                 if ( strict )
396                 {
397                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
398                 }
399             }
400         }
401         return 0;
402     } //-- float getFloatValue( String, String, XmlPullParser, boolean )
403 
404     /**
405      * Method getIntegerValue.
406      * 
407      * @param s a s object.
408      * @param strict a strict object.
409      * @param parser a parser object.
410      * @param attribute a attribute object.
411      * @throws XmlPullParserException XmlPullParserException if
412      * any.
413      * @return int
414      */
415     private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict )
416         throws XmlPullParserException
417     {
418         if ( s != null )
419         {
420             try
421             {
422                 return Integer.valueOf( s ).intValue();
423             }
424             catch ( NumberFormatException nfe )
425             {
426                 if ( strict )
427                 {
428                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
429                 }
430             }
431         }
432         return 0;
433     } //-- int getIntegerValue( String, String, XmlPullParser, boolean )
434 
435     /**
436      * Method getLongValue.
437      * 
438      * @param s a s object.
439      * @param strict a strict object.
440      * @param parser a parser object.
441      * @param attribute a attribute object.
442      * @throws XmlPullParserException XmlPullParserException if
443      * any.
444      * @return long
445      */
446     private long getLongValue( String s, String attribute, XmlPullParser parser, boolean strict )
447         throws XmlPullParserException
448     {
449         if ( s != null )
450         {
451             try
452             {
453                 return Long.valueOf( s ).longValue();
454             }
455             catch ( NumberFormatException nfe )
456             {
457                 if ( strict )
458                 {
459                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a long integer", parser, nfe );
460                 }
461             }
462         }
463         return 0;
464     } //-- long getLongValue( String, String, XmlPullParser, boolean )
465 
466     /**
467      * Method getRequiredAttributeValue.
468      * 
469      * @param s a s object.
470      * @param strict a strict object.
471      * @param parser a parser object.
472      * @param attribute a attribute object.
473      * @throws XmlPullParserException XmlPullParserException if
474      * any.
475      * @return String
476      */
477     private String getRequiredAttributeValue( String s, String attribute, XmlPullParser parser, boolean strict )
478         throws XmlPullParserException
479     {
480         if ( s == null )
481         {
482             if ( strict )
483             {
484                 throw new XmlPullParserException( "Missing required value for attribute '" + attribute + "'", parser, null );
485             }
486         }
487         return s;
488     } //-- String getRequiredAttributeValue( String, String, XmlPullParser, boolean )
489 
490     /**
491      * Method getShortValue.
492      * 
493      * @param s a s object.
494      * @param strict a strict object.
495      * @param parser a parser object.
496      * @param attribute a attribute object.
497      * @throws XmlPullParserException XmlPullParserException if
498      * any.
499      * @return short
500      */
501     private short getShortValue( String s, String attribute, XmlPullParser parser, boolean strict )
502         throws XmlPullParserException
503     {
504         if ( s != null )
505         {
506             try
507             {
508                 return Short.valueOf( s ).shortValue();
509             }
510             catch ( NumberFormatException nfe )
511             {
512                 if ( strict )
513                 {
514                     throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a short integer", parser, nfe );
515                 }
516             }
517         }
518         return 0;
519     } //-- short getShortValue( String, String, XmlPullParser, boolean )
520 
521     /**
522      * Method getTrimmedValue.
523      * 
524      * @param s a s object.
525      * @return String
526      */
527     private String getTrimmedValue( String s )
528     {
529         if ( s != null )
530         {
531             s = s.trim();
532         }
533         return s;
534     } //-- String getTrimmedValue( String )
535 
536     /**
537      * Method interpolatedTrimmed.
538      * 
539      * @param value a value object.
540      * @param context a context object.
541      * @return String
542      */
543     private String interpolatedTrimmed( String value, String context )
544     {
545         return getTrimmedValue( contentTransformer.transform( value, context ) );
546     } //-- String interpolatedTrimmed( String, String )
547 
548     /**
549      * Method nextTag.
550      * 
551      * @param parser a parser object.
552      * @throws IOException IOException if any.
553      * @throws XmlPullParserException XmlPullParserException if
554      * any.
555      * @return int
556      */
557     private int nextTag( XmlPullParser parser )
558         throws IOException, XmlPullParserException
559     {
560         int eventType = parser.next();
561         if ( eventType == XmlPullParser.TEXT )
562         {
563             eventType = parser.next();
564         }
565         if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
566         {
567             throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
568         }
569         return eventType;
570     } //-- int nextTag( XmlPullParser )
571 
572     /**
573      * Method read.
574      * 
575      * @param parser a parser object.
576      * @param strict a strict object.
577      * @throws IOException IOException if any.
578      * @throws XmlPullParserException XmlPullParserException if
579      * any.
580      * @return CpdErrorDetail
581      */
582     public CpdErrorDetail read( XmlPullParser parser, boolean strict )
583         throws IOException, XmlPullParserException
584     {
585         CpdErrorDetail cpdErrorDetail = null;
586         int eventType = parser.getEventType();
587         boolean parsed = false;
588         while ( eventType != XmlPullParser.END_DOCUMENT )
589         {
590             if ( eventType == XmlPullParser.START_TAG )
591             {
592                 if ( strict && ! "pmd-cpd".equals( parser.getName() ) )
593                 {
594                     throw new XmlPullParserException( "Expected root element 'pmd-cpd' but found '" + parser.getName() + "'", parser, null );
595                 }
596                 else if ( parsed )
597                 {
598                     // fallback, already expected a XmlPullParserException due to invalid XML
599                     throw new XmlPullParserException( "Duplicated tag: 'pmd-cpd'", parser, null );
600                 }
601                 cpdErrorDetail = parseCpdErrorDetail( parser, strict );
602                 cpdErrorDetail.setModelEncoding( parser.getInputEncoding() );
603                 parsed = true;
604             }
605             eventType = parser.next();
606         }
607         if ( parsed )
608         {
609             return cpdErrorDetail;
610         }
611         throw new XmlPullParserException( "Expected root element 'pmd-cpd' but found no element at all: invalid XML document", parser, null );
612     } //-- CpdErrorDetail read( XmlPullParser, boolean )
613 
614     /**
615      * @see XmlStreamReader
616      * 
617      * @param reader a reader object.
618      * @param strict a strict object.
619      * @throws IOException IOException if any.
620      * @throws XmlPullParserException XmlPullParserException if
621      * any.
622      * @return CpdErrorDetail
623      */
624     public CpdErrorDetail read( Reader reader, boolean strict )
625         throws IOException, XmlPullParserException
626     {
627         XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
628 
629         parser.setInput( reader );
630 
631 
632         return read( parser, strict );
633     } //-- CpdErrorDetail read( Reader, boolean )
634 
635     /**
636      * @see XmlStreamReader
637      * 
638      * @param reader a reader object.
639      * @throws IOException IOException if any.
640      * @throws XmlPullParserException XmlPullParserException if
641      * any.
642      * @return CpdErrorDetail
643      */
644     public CpdErrorDetail read( Reader reader )
645         throws IOException, XmlPullParserException
646     {
647         return read( reader, true );
648     } //-- CpdErrorDetail read( Reader )
649 
650     /**
651      * Method read.
652      * 
653      * @param in a in object.
654      * @param strict a strict object.
655      * @throws IOException IOException if any.
656      * @throws XmlPullParserException XmlPullParserException if
657      * any.
658      * @return CpdErrorDetail
659      */
660     public CpdErrorDetail read( InputStream in, boolean strict )
661         throws IOException, XmlPullParserException
662     {
663         return read( new XmlStreamReader( in ), strict );
664     } //-- CpdErrorDetail read( InputStream, boolean )
665 
666     /**
667      * Method read.
668      * 
669      * @param in a in object.
670      * @throws IOException IOException if any.
671      * @throws XmlPullParserException XmlPullParserException if
672      * any.
673      * @return CpdErrorDetail
674      */
675     public CpdErrorDetail read( InputStream in )
676         throws IOException, XmlPullParserException
677     {
678         return read( new XmlStreamReader( in ) );
679     } //-- CpdErrorDetail read( InputStream )
680 
681     /**
682      * Method parseCpdErrorDetail.
683      * 
684      * @param parser a parser object.
685      * @param strict a strict object.
686      * @throws IOException IOException if any.
687      * @throws XmlPullParserException XmlPullParserException if
688      * any.
689      * @return CpdErrorDetail
690      */
691     private CpdErrorDetail parseCpdErrorDetail( XmlPullParser parser, boolean strict )
692         throws IOException, XmlPullParserException
693     {
694         String tagName = parser.getName();
695         CpdErrorDetail cpdErrorDetail = new CpdErrorDetail();
696         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
697         {
698             String name = parser.getAttributeName( i );
699             String value = parser.getAttributeValue( i );
700 
701             if ( name.indexOf( ':' ) >= 0 )
702             {
703                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
704             }
705             else if ( "xmlns".equals( name ) )
706             {
707                 // ignore xmlns attribute in root class, which is a reserved attribute name
708             }
709             else
710             {
711                 checkUnknownAttribute( parser, name, tagName, strict );
712             }
713         }
714         java.util.Set<String> parsed = new java.util.HashSet<String>();
715         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
716         {
717             if ( "duplication".equals( parser.getName() ) )
718             {
719                 java.util.List<Duplication> duplications = cpdErrorDetail.getDuplications();
720                 if ( duplications == null )
721                 {
722                     duplications = new java.util.ArrayList<Duplication>();
723                 }
724                 duplications.add( parseDuplication( parser, strict ) );
725                 cpdErrorDetail.setDuplications( duplications );
726             }
727             else
728             {
729                 checkUnknownElement( parser, strict );
730             }
731         }
732         return cpdErrorDetail;
733     } //-- CpdErrorDetail parseCpdErrorDetail( XmlPullParser, boolean )
734 
735     /**
736      * Method parseCpdFile.
737      * 
738      * @param parser a parser object.
739      * @param strict a strict object.
740      * @throws IOException IOException if any.
741      * @throws XmlPullParserException XmlPullParserException if
742      * any.
743      * @return CpdFile
744      */
745     private CpdFile parseCpdFile( XmlPullParser parser, boolean strict )
746         throws IOException, XmlPullParserException
747     {
748         String tagName = parser.getName();
749         CpdFile cpdFile = new CpdFile();
750         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
751         {
752             String name = parser.getAttributeName( i );
753             String value = parser.getAttributeValue( i );
754 
755             if ( name.indexOf( ':' ) >= 0 )
756             {
757                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
758             }
759             else if ( "line".equals( name ) )
760             {
761                 cpdFile.setLine( getIntegerValue( interpolatedTrimmed( value, "line" ), "line", parser, strict ) );
762             }
763             else if ( "path".equals( name ) )
764             {
765                 cpdFile.setPath( interpolatedTrimmed( value, "path" ) );
766             }
767             else
768             {
769                 checkUnknownAttribute( parser, name, tagName, strict );
770             }
771         }
772         java.util.Set<String> parsed = new java.util.HashSet<String>();
773         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
774         {
775             checkUnknownElement( parser, strict );
776         }
777         return cpdFile;
778     } //-- CpdFile parseCpdFile( XmlPullParser, boolean )
779 
780     /**
781      * Method parseDuplication.
782      * 
783      * @param parser a parser object.
784      * @param strict a strict object.
785      * @throws IOException IOException if any.
786      * @throws XmlPullParserException XmlPullParserException if
787      * any.
788      * @return Duplication
789      */
790     private Duplication parseDuplication( XmlPullParser parser, boolean strict )
791         throws IOException, XmlPullParserException
792     {
793         String tagName = parser.getName();
794         Duplication duplication = new Duplication();
795         for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
796         {
797             String name = parser.getAttributeName( i );
798             String value = parser.getAttributeValue( i );
799 
800             if ( name.indexOf( ':' ) >= 0 )
801             {
802                 // just ignore attributes with non-default namespace (for example: xmlns:xsi)
803             }
804             else if ( "lines".equals( name ) )
805             {
806                 duplication.setLines( getIntegerValue( interpolatedTrimmed( value, "lines" ), "lines", parser, strict ) );
807             }
808             else if ( "tokens".equals( name ) )
809             {
810                 duplication.setTokens( getIntegerValue( interpolatedTrimmed( value, "tokens" ), "tokens", parser, strict ) );
811             }
812             else
813             {
814                 checkUnknownAttribute( parser, name, tagName, strict );
815             }
816         }
817         java.util.Set<String> parsed = new java.util.HashSet<String>();
818         while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
819         {
820             if ( "file".equals( parser.getName() ) )
821             {
822                 java.util.List<CpdFile> files = duplication.getFiles();
823                 if ( files == null )
824                 {
825                     files = new java.util.ArrayList<CpdFile>();
826                 }
827                 files.add( parseCpdFile( parser, strict ) );
828                 duplication.setFiles( files );
829             }
830             else if ( checkFieldWithDuplicate( parser, "codefragment", null, parsed ) )
831             {
832                 duplication.setCodefragment( interpolatedTrimmed( parser.nextText(), "codefragment" ) );
833             }
834             else
835             {
836                 checkUnknownElement( parser, strict );
837             }
838         }
839         return duplication;
840     } //-- Duplication parseDuplication( XmlPullParser, boolean )
841 
842     /**
843      * Sets the state of the "add default entities" flag.
844      * 
845      * @param addDefaultEntities a addDefaultEntities object.
846      */
847     public void setAddDefaultEntities( boolean addDefaultEntities )
848     {
849         this.addDefaultEntities = addDefaultEntities;
850     } //-- void setAddDefaultEntities( boolean )
851 
852     public static interface ContentTransformer
853 {
854     /**
855      * Interpolate the value read from the xpp3 document
856      * @param source The source value
857      * @param fieldName A description of the field being interpolated. The implementation may use this to
858      *                           log stuff.
859      * @return The interpolated value.
860      */
861     String transform( String source, String fieldName );
862 }
863 
864 }