001// =================== DO NOT EDIT THIS FILE ====================
002// Generated by Modello 1.9.1,
003// any modifications will be overwritten.
004// ==============================================================
005
006package org.apache.maven.doxia.document.io.xpp3;
007
008  //---------------------------------/
009 //- Imported classes and packages -/
010//---------------------------------/
011
012import java.io.IOException;
013import java.io.InputStream;
014import java.io.Reader;
015import java.text.DateFormat;
016import org.apache.maven.doxia.document.DocumentAuthor;
017import org.apache.maven.doxia.document.DocumentCover;
018import org.apache.maven.doxia.document.DocumentHyperlinkBehaviour;
019import org.apache.maven.doxia.document.DocumentMeta;
020import org.apache.maven.doxia.document.DocumentModel;
021import org.apache.maven.doxia.document.DocumentStatistic;
022import org.apache.maven.doxia.document.DocumentTOC;
023import org.apache.maven.doxia.document.DocumentTOCItem;
024import org.apache.maven.doxia.document.DocumentTemplate;
025import org.codehaus.plexus.util.ReaderFactory;
026import org.codehaus.plexus.util.xml.pull.EntityReplacementMap;
027import org.codehaus.plexus.util.xml.pull.MXParser;
028import org.codehaus.plexus.util.xml.pull.XmlPullParser;
029import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
030
031/**
032 * Class DocumentXpp3Reader.
033 * 
034 * @version $Revision$ $Date$
035 */
036@SuppressWarnings( "all" )
037public class DocumentXpp3Reader
038{
039
040      //--------------------------/
041     //- Class/Member Variables -/
042    //--------------------------/
043
044    /**
045     * If set the parser will be loaded with all single characters
046     * from the XHTML specification.
047     * The entities used:
048     * <ul>
049     * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li>
050     * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li>
051     * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li>
052     * </ul>
053     */
054    private boolean addDefaultEntities = true;
055
056    /**
057     * Field contentTransformer.
058     */
059    public final ContentTransformer contentTransformer;
060
061
062      //----------------/
063     //- Constructors -/
064    //----------------/
065
066    public DocumentXpp3Reader()
067    {
068        this( new ContentTransformer()
069        {
070            public String transform( String source, String fieldName )
071            {
072                return source;
073            }
074        } );
075    } //-- org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader()
076
077    public DocumentXpp3Reader(ContentTransformer contentTransformer)
078    {
079        this.contentTransformer = contentTransformer;
080    } //-- org.apache.maven.doxia.document.io.xpp3.DocumentXpp3Reader(ContentTransformer)
081
082
083      //-----------/
084     //- Methods -/
085    //-----------/
086
087    /**
088     * Method checkFieldWithDuplicate.
089     * 
090     * @param parser
091     * @param parsed
092     * @param alias
093     * @param tagName
094     * @throws XmlPullParserException
095     * @return boolean
096     */
097    private boolean checkFieldWithDuplicate( XmlPullParser parser, String tagName, String alias, java.util.Set parsed )
098        throws XmlPullParserException
099    {
100        if ( !( parser.getName().equals( tagName ) || parser.getName().equals( alias ) ) )
101        {
102            return false;
103        }
104        if ( !parsed.add( tagName ) )
105        {
106            throw new XmlPullParserException( "Duplicated tag: '" + tagName + "'", parser, null );
107        }
108        return true;
109    } //-- boolean checkFieldWithDuplicate( XmlPullParser, String, String, java.util.Set )
110
111    /**
112     * Method checkUnknownAttribute.
113     * 
114     * @param parser
115     * @param strict
116     * @param tagName
117     * @param attribute
118     * @throws XmlPullParserException
119     * @throws IOException
120     */
121    private void checkUnknownAttribute( XmlPullParser parser, String attribute, String tagName, boolean strict )
122        throws XmlPullParserException, IOException
123    {
124        // strictXmlAttributes = true for model: if strict == true, not only elements are checked but attributes too
125        if ( strict )
126        {
127            throw new XmlPullParserException( "Unknown attribute '" + attribute + "' for tag '" + tagName + "'", parser, null );
128        }
129    } //-- void checkUnknownAttribute( XmlPullParser, String, String, boolean )
130
131    /**
132     * Method checkUnknownElement.
133     * 
134     * @param parser
135     * @param strict
136     * @throws XmlPullParserException
137     * @throws IOException
138     */
139    private void checkUnknownElement( XmlPullParser parser, boolean strict )
140        throws XmlPullParserException, IOException
141    {
142        if ( strict )
143        {
144            throw new XmlPullParserException( "Unrecognised tag: '" + parser.getName() + "'", parser, null );
145        }
146
147        for ( int unrecognizedTagCount = 1; unrecognizedTagCount > 0; )
148        {
149            int eventType = parser.next();
150            if ( eventType == XmlPullParser.START_TAG )
151            {
152                unrecognizedTagCount++;
153            }
154            else if ( eventType == XmlPullParser.END_TAG )
155            {
156                unrecognizedTagCount--;
157            }
158        }
159    } //-- void checkUnknownElement( XmlPullParser, boolean )
160
161    /**
162     * Returns the state of the "add default entities" flag.
163     * 
164     * @return boolean
165     */
166    public boolean getAddDefaultEntities()
167    {
168        return addDefaultEntities;
169    } //-- boolean getAddDefaultEntities()
170
171    /**
172     * Method getBooleanValue.
173     * 
174     * @param s
175     * @param parser
176     * @param attribute
177     * @throws XmlPullParserException
178     * @return boolean
179     */
180    private boolean getBooleanValue( String s, String attribute, XmlPullParser parser )
181        throws XmlPullParserException
182    {
183        return getBooleanValue( s, attribute, parser, null );
184    } //-- boolean getBooleanValue( String, String, XmlPullParser )
185
186    /**
187     * Method getBooleanValue.
188     * 
189     * @param s
190     * @param defaultValue
191     * @param parser
192     * @param attribute
193     * @throws XmlPullParserException
194     * @return boolean
195     */
196    private boolean getBooleanValue( String s, String attribute, XmlPullParser parser, String defaultValue )
197        throws XmlPullParserException
198    {
199        if ( s != null && s.length() != 0 )
200        {
201            return Boolean.valueOf( s ).booleanValue();
202        }
203        if ( defaultValue != null )
204        {
205            return Boolean.valueOf( defaultValue ).booleanValue();
206        }
207        return false;
208    } //-- boolean getBooleanValue( String, String, XmlPullParser, String )
209
210    /**
211     * Method getByteValue.
212     * 
213     * @param s
214     * @param strict
215     * @param parser
216     * @param attribute
217     * @throws XmlPullParserException
218     * @return byte
219     */
220    private byte getByteValue( String s, String attribute, XmlPullParser parser, boolean strict )
221        throws XmlPullParserException
222    {
223        if ( s != null )
224        {
225            try
226            {
227                return Byte.valueOf( s ).byteValue();
228            }
229            catch ( NumberFormatException nfe )
230            {
231                if ( strict )
232                {
233                    throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a byte", parser, nfe );
234                }
235            }
236        }
237        return 0;
238    } //-- byte getByteValue( String, String, XmlPullParser, boolean )
239
240    /**
241     * Method getCharacterValue.
242     * 
243     * @param s
244     * @param parser
245     * @param attribute
246     * @throws XmlPullParserException
247     * @return char
248     */
249    private char getCharacterValue( String s, String attribute, XmlPullParser parser )
250        throws XmlPullParserException
251    {
252        if ( s != null )
253        {
254            return s.charAt( 0 );
255        }
256        return 0;
257    } //-- char getCharacterValue( String, String, XmlPullParser )
258
259    /**
260     * Method getDateValue.
261     * 
262     * @param s
263     * @param parser
264     * @param attribute
265     * @throws XmlPullParserException
266     * @return Date
267     */
268    private java.util.Date getDateValue( String s, String attribute, XmlPullParser parser )
269        throws XmlPullParserException
270    {
271        return getDateValue( s, attribute, null, parser );
272    } //-- java.util.Date getDateValue( String, String, XmlPullParser )
273
274    /**
275     * Method getDateValue.
276     * 
277     * @param s
278     * @param parser
279     * @param dateFormat
280     * @param attribute
281     * @throws XmlPullParserException
282     * @return Date
283     */
284    private java.util.Date getDateValue( String s, String attribute, String dateFormat, XmlPullParser parser )
285        throws XmlPullParserException
286    {
287        if ( s != null )
288        {
289            String effectiveDateFormat = dateFormat;
290            if ( dateFormat == null )
291            {
292                effectiveDateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS";
293            }
294            if ( "long".equals( effectiveDateFormat ) )
295            {
296                try
297                {
298                    return new java.util.Date( Long.parseLong( s ) );
299                }
300                catch ( NumberFormatException e )
301                {
302                    throw new XmlPullParserException( e.getMessage(), parser, e );
303                }
304            }
305            else
306            {
307                try
308                {
309                    DateFormat dateParser = new java.text.SimpleDateFormat( effectiveDateFormat, java.util.Locale.US );
310                    return dateParser.parse( s );
311                }
312                catch ( java.text.ParseException e )
313                {
314                    throw new XmlPullParserException( e.getMessage(), parser, e );
315                }
316            }
317        }
318        return null;
319    } //-- java.util.Date getDateValue( String, String, String, XmlPullParser )
320
321    /**
322     * Method getDoubleValue.
323     * 
324     * @param s
325     * @param strict
326     * @param parser
327     * @param attribute
328     * @throws XmlPullParserException
329     * @return double
330     */
331    private double getDoubleValue( String s, String attribute, XmlPullParser parser, boolean strict )
332        throws XmlPullParserException
333    {
334        if ( s != null )
335        {
336            try
337            {
338                return Double.valueOf( s ).doubleValue();
339            }
340            catch ( NumberFormatException nfe )
341            {
342                if ( strict )
343                {
344                    throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
345                }
346            }
347        }
348        return 0;
349    } //-- double getDoubleValue( String, String, XmlPullParser, boolean )
350
351    /**
352     * Method getFloatValue.
353     * 
354     * @param s
355     * @param strict
356     * @param parser
357     * @param attribute
358     * @throws XmlPullParserException
359     * @return float
360     */
361    private float getFloatValue( String s, String attribute, XmlPullParser parser, boolean strict )
362        throws XmlPullParserException
363    {
364        if ( s != null )
365        {
366            try
367            {
368                return Float.valueOf( s ).floatValue();
369            }
370            catch ( NumberFormatException nfe )
371            {
372                if ( strict )
373                {
374                    throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a floating point number", parser, nfe );
375                }
376            }
377        }
378        return 0;
379    } //-- float getFloatValue( String, String, XmlPullParser, boolean )
380
381    /**
382     * Method getIntegerValue.
383     * 
384     * @param s
385     * @param strict
386     * @param parser
387     * @param attribute
388     * @throws XmlPullParserException
389     * @return int
390     */
391    private int getIntegerValue( String s, String attribute, XmlPullParser parser, boolean strict )
392        throws XmlPullParserException
393    {
394        if ( s != null )
395        {
396            try
397            {
398                return Integer.valueOf( s ).intValue();
399            }
400            catch ( NumberFormatException nfe )
401            {
402                if ( strict )
403                {
404                    throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be an integer", parser, nfe );
405                }
406            }
407        }
408        return 0;
409    } //-- int getIntegerValue( String, String, XmlPullParser, boolean )
410
411    /**
412     * Method getLongValue.
413     * 
414     * @param s
415     * @param strict
416     * @param parser
417     * @param attribute
418     * @throws XmlPullParserException
419     * @return long
420     */
421    private long getLongValue( String s, String attribute, XmlPullParser parser, boolean strict )
422        throws XmlPullParserException
423    {
424        if ( s != null )
425        {
426            try
427            {
428                return Long.valueOf( s ).longValue();
429            }
430            catch ( NumberFormatException nfe )
431            {
432                if ( strict )
433                {
434                    throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a long integer", parser, nfe );
435                }
436            }
437        }
438        return 0;
439    } //-- long getLongValue( String, String, XmlPullParser, boolean )
440
441    /**
442     * Method getRequiredAttributeValue.
443     * 
444     * @param s
445     * @param strict
446     * @param parser
447     * @param attribute
448     * @throws XmlPullParserException
449     * @return String
450     */
451    private String getRequiredAttributeValue( String s, String attribute, XmlPullParser parser, boolean strict )
452        throws XmlPullParserException
453    {
454        if ( s == null )
455        {
456            if ( strict )
457            {
458                throw new XmlPullParserException( "Missing required value for attribute '" + attribute + "'", parser, null );
459            }
460        }
461        return s;
462    } //-- String getRequiredAttributeValue( String, String, XmlPullParser, boolean )
463
464    /**
465     * Method getShortValue.
466     * 
467     * @param s
468     * @param strict
469     * @param parser
470     * @param attribute
471     * @throws XmlPullParserException
472     * @return short
473     */
474    private short getShortValue( String s, String attribute, XmlPullParser parser, boolean strict )
475        throws XmlPullParserException
476    {
477        if ( s != null )
478        {
479            try
480            {
481                return Short.valueOf( s ).shortValue();
482            }
483            catch ( NumberFormatException nfe )
484            {
485                if ( strict )
486                {
487                    throw new XmlPullParserException( "Unable to parse element '" + attribute + "', must be a short integer", parser, nfe );
488                }
489            }
490        }
491        return 0;
492    } //-- short getShortValue( String, String, XmlPullParser, boolean )
493
494    /**
495     * Method getTrimmedValue.
496     * 
497     * @param s
498     * @return String
499     */
500    private String getTrimmedValue( String s )
501    {
502        if ( s != null )
503        {
504            s = s.trim();
505        }
506        return s;
507    } //-- String getTrimmedValue( String )
508
509    /**
510     * Method interpolatedTrimmed.
511     * 
512     * @param value
513     * @param context
514     * @return String
515     */
516    private String interpolatedTrimmed( String value, String context )
517    {
518        return getTrimmedValue( contentTransformer.transform( value, context ) );
519    } //-- String interpolatedTrimmed( String, String )
520
521    /**
522     * Method nextTag.
523     * 
524     * @param parser
525     * @throws IOException
526     * @throws XmlPullParserException
527     * @return int
528     */
529    private int nextTag( XmlPullParser parser )
530        throws IOException, XmlPullParserException
531    {
532        int eventType = parser.next();
533        if ( eventType == XmlPullParser.TEXT )
534        {
535            eventType = parser.next();
536        }
537        if ( eventType != XmlPullParser.START_TAG && eventType != XmlPullParser.END_TAG )
538        {
539            throw new XmlPullParserException( "expected START_TAG or END_TAG not " + XmlPullParser.TYPES[eventType], parser, null );
540        }
541        return eventType;
542    } //-- int nextTag( XmlPullParser )
543
544    /**
545     * @see ReaderFactory#newXmlReader
546     * 
547     * @param reader
548     * @param strict
549     * @throws IOException
550     * @throws XmlPullParserException
551     * @return DocumentModel
552     */
553    public DocumentModel read( Reader reader, boolean strict )
554        throws IOException, XmlPullParserException
555    {
556        XmlPullParser parser = addDefaultEntities ? new MXParser(EntityReplacementMap.defaultEntityReplacementMap) : new MXParser( );
557
558        parser.setInput( reader );
559
560
561        return read( parser, strict );
562    } //-- DocumentModel read( Reader, boolean )
563
564    /**
565     * @see ReaderFactory#newXmlReader
566     * 
567     * @param reader
568     * @throws IOException
569     * @throws XmlPullParserException
570     * @return DocumentModel
571     */
572    public DocumentModel read( Reader reader )
573        throws IOException, XmlPullParserException
574    {
575        return read( reader, true );
576    } //-- DocumentModel read( Reader )
577
578    /**
579     * Method read.
580     * 
581     * @param in
582     * @param strict
583     * @throws IOException
584     * @throws XmlPullParserException
585     * @return DocumentModel
586     */
587    public DocumentModel read( InputStream in, boolean strict )
588        throws IOException, XmlPullParserException
589    {
590        return read( ReaderFactory.newXmlReader( in ), strict );
591    } //-- DocumentModel read( InputStream, boolean )
592
593    /**
594     * Method read.
595     * 
596     * @param in
597     * @throws IOException
598     * @throws XmlPullParserException
599     * @return DocumentModel
600     */
601    public DocumentModel read( InputStream in )
602        throws IOException, XmlPullParserException
603    {
604        return read( ReaderFactory.newXmlReader( in ) );
605    } //-- DocumentModel read( InputStream )
606
607    /**
608     * Method parseDocumentAuthor.
609     * 
610     * @param parser
611     * @param strict
612     * @throws IOException
613     * @throws XmlPullParserException
614     * @return DocumentAuthor
615     */
616    private DocumentAuthor parseDocumentAuthor( XmlPullParser parser, boolean strict )
617        throws IOException, XmlPullParserException
618    {
619        String tagName = parser.getName();
620        DocumentAuthor documentAuthor = new DocumentAuthor();
621        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
622        {
623            String name = parser.getAttributeName( i );
624            String value = parser.getAttributeValue( i );
625
626            if ( name.indexOf( ':' ) >= 0 )
627            {
628                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
629            }
630            else
631            {
632                checkUnknownAttribute( parser, name, tagName, strict );
633            }
634        }
635        java.util.Set parsed = new java.util.HashSet();
636        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
637        {
638            if ( checkFieldWithDuplicate( parser, "firstName", null, parsed ) )
639            {
640                documentAuthor.setFirstName( interpolatedTrimmed( parser.nextText(), "firstName" ) );
641            }
642            else if ( checkFieldWithDuplicate( parser, "lastName", null, parsed ) )
643            {
644                documentAuthor.setLastName( interpolatedTrimmed( parser.nextText(), "lastName" ) );
645            }
646            else if ( checkFieldWithDuplicate( parser, "name", null, parsed ) )
647            {
648                documentAuthor.setName( interpolatedTrimmed( parser.nextText(), "name" ) );
649            }
650            else if ( checkFieldWithDuplicate( parser, "initials", null, parsed ) )
651            {
652                documentAuthor.setInitials( interpolatedTrimmed( parser.nextText(), "initials" ) );
653            }
654            else if ( checkFieldWithDuplicate( parser, "title", null, parsed ) )
655            {
656                documentAuthor.setTitle( interpolatedTrimmed( parser.nextText(), "title" ) );
657            }
658            else if ( checkFieldWithDuplicate( parser, "position", null, parsed ) )
659            {
660                documentAuthor.setPosition( interpolatedTrimmed( parser.nextText(), "position" ) );
661            }
662            else if ( checkFieldWithDuplicate( parser, "email", null, parsed ) )
663            {
664                documentAuthor.setEmail( interpolatedTrimmed( parser.nextText(), "email" ) );
665            }
666            else if ( checkFieldWithDuplicate( parser, "phoneNumber", null, parsed ) )
667            {
668                documentAuthor.setPhoneNumber( interpolatedTrimmed( parser.nextText(), "phoneNumber" ) );
669            }
670            else if ( checkFieldWithDuplicate( parser, "faxNumber", null, parsed ) )
671            {
672                documentAuthor.setFaxNumber( interpolatedTrimmed( parser.nextText(), "faxNumber" ) );
673            }
674            else if ( checkFieldWithDuplicate( parser, "companyName", null, parsed ) )
675            {
676                documentAuthor.setCompanyName( interpolatedTrimmed( parser.nextText(), "companyName" ) );
677            }
678            else if ( checkFieldWithDuplicate( parser, "street", null, parsed ) )
679            {
680                documentAuthor.setStreet( interpolatedTrimmed( parser.nextText(), "street" ) );
681            }
682            else if ( checkFieldWithDuplicate( parser, "city", null, parsed ) )
683            {
684                documentAuthor.setCity( interpolatedTrimmed( parser.nextText(), "city" ) );
685            }
686            else if ( checkFieldWithDuplicate( parser, "postalCode", null, parsed ) )
687            {
688                documentAuthor.setPostalCode( interpolatedTrimmed( parser.nextText(), "postalCode" ) );
689            }
690            else if ( checkFieldWithDuplicate( parser, "country", null, parsed ) )
691            {
692                documentAuthor.setCountry( interpolatedTrimmed( parser.nextText(), "country" ) );
693            }
694            else if ( checkFieldWithDuplicate( parser, "state", null, parsed ) )
695            {
696                documentAuthor.setState( interpolatedTrimmed( parser.nextText(), "state" ) );
697            }
698            else
699            {
700                checkUnknownElement( parser, strict );
701            }
702        }
703        return documentAuthor;
704    } //-- DocumentAuthor parseDocumentAuthor( XmlPullParser, boolean )
705
706    /**
707     * Method parseDocumentCover.
708     * 
709     * @param parser
710     * @param strict
711     * @throws IOException
712     * @throws XmlPullParserException
713     * @return DocumentCover
714     */
715    private DocumentCover parseDocumentCover( XmlPullParser parser, boolean strict )
716        throws IOException, XmlPullParserException
717    {
718        String tagName = parser.getName();
719        DocumentCover documentCover = new DocumentCover();
720        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
721        {
722            String name = parser.getAttributeName( i );
723            String value = parser.getAttributeValue( i );
724
725            if ( name.indexOf( ':' ) >= 0 )
726            {
727                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
728            }
729            else
730            {
731                checkUnknownAttribute( parser, name, tagName, strict );
732            }
733        }
734        java.util.Set parsed = new java.util.HashSet();
735        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
736        {
737            if ( checkFieldWithDuplicate( parser, "coverTitle", null, parsed ) )
738            {
739                documentCover.setCoverTitle( interpolatedTrimmed( parser.nextText(), "coverTitle" ) );
740            }
741            else if ( checkFieldWithDuplicate( parser, "coverSubTitle", null, parsed ) )
742            {
743                documentCover.setCoverSubTitle( interpolatedTrimmed( parser.nextText(), "coverSubTitle" ) );
744            }
745            else if ( checkFieldWithDuplicate( parser, "coverVersion", null, parsed ) )
746            {
747                documentCover.setCoverVersion( interpolatedTrimmed( parser.nextText(), "coverVersion" ) );
748            }
749            else if ( checkFieldWithDuplicate( parser, "coverType", null, parsed ) )
750            {
751                documentCover.setCoverType( interpolatedTrimmed( parser.nextText(), "coverType" ) );
752            }
753            else if ( checkFieldWithDuplicate( parser, "coverDate", null, parsed ) )
754            {
755                String dateFormat = null;
756                documentCover.setCoverDate( getDateValue( interpolatedTrimmed( parser.nextText(), "coverDate" ), "coverDate", dateFormat, parser ) );
757            }
758            else if ( checkFieldWithDuplicate( parser, "coverdate", null, parsed ) )
759            {
760                documentCover.setCoverdate( interpolatedTrimmed( parser.nextText(), "coverdate" ) );
761            }
762            else if ( checkFieldWithDuplicate( parser, "authors", null, parsed ) )
763            {
764                java.util.List<DocumentAuthor> authors = new java.util.ArrayList<DocumentAuthor>();
765                documentCover.setAuthors( authors );
766                while ( parser.nextTag() == XmlPullParser.START_TAG )
767                {
768                    if ( "author".equals( parser.getName() ) )
769                    {
770                        authors.add( parseDocumentAuthor( parser, strict ) );
771                    }
772                    else
773                    {
774                        checkUnknownElement( parser, strict );
775                    }
776                }
777            }
778            else if ( checkFieldWithDuplicate( parser, "author", null, parsed ) )
779            {
780                documentCover.setAuthor( interpolatedTrimmed( parser.nextText(), "author" ) );
781            }
782            else if ( checkFieldWithDuplicate( parser, "projectName", null, parsed ) )
783            {
784                documentCover.setProjectName( interpolatedTrimmed( parser.nextText(), "projectName" ) );
785            }
786            else if ( checkFieldWithDuplicate( parser, "projectLogo", null, parsed ) )
787            {
788                documentCover.setProjectLogo( interpolatedTrimmed( parser.nextText(), "projectLogo" ) );
789            }
790            else if ( checkFieldWithDuplicate( parser, "companyName", null, parsed ) )
791            {
792                documentCover.setCompanyName( interpolatedTrimmed( parser.nextText(), "companyName" ) );
793            }
794            else if ( checkFieldWithDuplicate( parser, "companyLogo", null, parsed ) )
795            {
796                documentCover.setCompanyLogo( interpolatedTrimmed( parser.nextText(), "companyLogo" ) );
797            }
798            else
799            {
800                checkUnknownElement( parser, strict );
801            }
802        }
803        return documentCover;
804    } //-- DocumentCover parseDocumentCover( XmlPullParser, boolean )
805
806    /**
807     * Method parseDocumentHyperlinkBehaviour.
808     * 
809     * @param parser
810     * @param strict
811     * @throws IOException
812     * @throws XmlPullParserException
813     * @return DocumentHyperlinkBehaviour
814     */
815    private DocumentHyperlinkBehaviour parseDocumentHyperlinkBehaviour( XmlPullParser parser, boolean strict )
816        throws IOException, XmlPullParserException
817    {
818        String tagName = parser.getName();
819        DocumentHyperlinkBehaviour documentHyperlinkBehaviour = new DocumentHyperlinkBehaviour();
820        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
821        {
822            String name = parser.getAttributeName( i );
823            String value = parser.getAttributeValue( i );
824
825            if ( name.indexOf( ':' ) >= 0 )
826            {
827                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
828            }
829            else if ( "targetFrame".equals( name ) )
830            {
831                documentHyperlinkBehaviour.setTargetFrame( interpolatedTrimmed( value, "targetFrame" ) );
832            }
833            else
834            {
835                checkUnknownAttribute( parser, name, tagName, strict );
836            }
837        }
838        java.util.Set parsed = new java.util.HashSet();
839        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
840        {
841            checkUnknownElement( parser, strict );
842        }
843        return documentHyperlinkBehaviour;
844    } //-- DocumentHyperlinkBehaviour parseDocumentHyperlinkBehaviour( XmlPullParser, boolean )
845
846    /**
847     * Method parseDocumentMeta.
848     * 
849     * @param parser
850     * @param strict
851     * @throws IOException
852     * @throws XmlPullParserException
853     * @return DocumentMeta
854     */
855    private DocumentMeta parseDocumentMeta( XmlPullParser parser, boolean strict )
856        throws IOException, XmlPullParserException
857    {
858        String tagName = parser.getName();
859        DocumentMeta documentMeta = new DocumentMeta();
860        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
861        {
862            String name = parser.getAttributeName( i );
863            String value = parser.getAttributeValue( i );
864
865            if ( name.indexOf( ':' ) >= 0 )
866            {
867                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
868            }
869            else
870            {
871                checkUnknownAttribute( parser, name, tagName, strict );
872            }
873        }
874        java.util.Set parsed = new java.util.HashSet();
875        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
876        {
877            if ( checkFieldWithDuplicate( parser, "title", null, parsed ) )
878            {
879                documentMeta.setTitle( interpolatedTrimmed( parser.nextText(), "title" ) );
880            }
881            else if ( checkFieldWithDuplicate( parser, "author", null, parsed ) )
882            {
883                documentMeta.setAuthor( interpolatedTrimmed( parser.nextText(), "author" ) );
884            }
885            else if ( checkFieldWithDuplicate( parser, "authors", null, parsed ) )
886            {
887                java.util.List<DocumentAuthor> authors = new java.util.ArrayList<DocumentAuthor>();
888                documentMeta.setAuthors( authors );
889                while ( parser.nextTag() == XmlPullParser.START_TAG )
890                {
891                    if ( "author".equals( parser.getName() ) )
892                    {
893                        authors.add( parseDocumentAuthor( parser, strict ) );
894                    }
895                    else
896                    {
897                        checkUnknownElement( parser, strict );
898                    }
899                }
900            }
901            else if ( checkFieldWithDuplicate( parser, "subject", null, parsed ) )
902            {
903                documentMeta.setSubject( interpolatedTrimmed( parser.nextText(), "subject" ) );
904            }
905            else if ( checkFieldWithDuplicate( parser, "keywords", null, parsed ) )
906            {
907                documentMeta.setKeywords( interpolatedTrimmed( parser.nextText(), "keywords" ) );
908            }
909            else if ( checkFieldWithDuplicate( parser, "keyWords", null, parsed ) )
910            {
911                java.util.List<String> keyWords = new java.util.ArrayList<String>();
912                documentMeta.setKeyWords( keyWords );
913                while ( parser.nextTag() == XmlPullParser.START_TAG )
914                {
915                    if ( "keyWord".equals( parser.getName() ) )
916                    {
917                        keyWords.add( interpolatedTrimmed( parser.nextText(), "keyWords" ) );
918                    }
919                    else
920                    {
921                        checkUnknownElement( parser, strict );
922                    }
923                }
924            }
925            else if ( checkFieldWithDuplicate( parser, "pageSize", null, parsed ) )
926            {
927                documentMeta.setPageSize( interpolatedTrimmed( parser.nextText(), "pageSize" ) );
928            }
929            else if ( checkFieldWithDuplicate( parser, "generator", null, parsed ) )
930            {
931                documentMeta.setGenerator( interpolatedTrimmed( parser.nextText(), "generator" ) );
932            }
933            else if ( checkFieldWithDuplicate( parser, "description", null, parsed ) )
934            {
935                documentMeta.setDescription( interpolatedTrimmed( parser.nextText(), "description" ) );
936            }
937            else if ( checkFieldWithDuplicate( parser, "initialCreator", null, parsed ) )
938            {
939                documentMeta.setInitialCreator( interpolatedTrimmed( parser.nextText(), "initialCreator" ) );
940            }
941            else if ( checkFieldWithDuplicate( parser, "creator", null, parsed ) )
942            {
943                documentMeta.setCreator( interpolatedTrimmed( parser.nextText(), "creator" ) );
944            }
945            else if ( checkFieldWithDuplicate( parser, "printedBy", null, parsed ) )
946            {
947                documentMeta.setPrintedBy( interpolatedTrimmed( parser.nextText(), "printedBy" ) );
948            }
949            else if ( checkFieldWithDuplicate( parser, "creationDate", null, parsed ) )
950            {
951                String dateFormat = null;
952                documentMeta.setCreationDate( getDateValue( interpolatedTrimmed( parser.nextText(), "creationDate" ), "creationDate", dateFormat, parser ) );
953            }
954            else if ( checkFieldWithDuplicate( parser, "creationdate", null, parsed ) )
955            {
956                documentMeta.setCreationdate( interpolatedTrimmed( parser.nextText(), "creationdate" ) );
957            }
958            else if ( checkFieldWithDuplicate( parser, "date", null, parsed ) )
959            {
960                String dateFormat = null;
961                documentMeta.setDate( getDateValue( interpolatedTrimmed( parser.nextText(), "date" ), "date", dateFormat, parser ) );
962            }
963            else if ( checkFieldWithDuplicate( parser, "modifydate", null, parsed ) )
964            {
965                documentMeta.setModifydate( interpolatedTrimmed( parser.nextText(), "modifydate" ) );
966            }
967            else if ( checkFieldWithDuplicate( parser, "printDate", null, parsed ) )
968            {
969                String dateFormat = null;
970                documentMeta.setPrintDate( getDateValue( interpolatedTrimmed( parser.nextText(), "printDate" ), "printDate", dateFormat, parser ) );
971            }
972            else if ( checkFieldWithDuplicate( parser, "printdate", null, parsed ) )
973            {
974                documentMeta.setPrintdate( interpolatedTrimmed( parser.nextText(), "printdate" ) );
975            }
976            else if ( checkFieldWithDuplicate( parser, "template", null, parsed ) )
977            {
978                documentMeta.setTemplate( parseDocumentTemplate( parser, strict ) );
979            }
980            else if ( checkFieldWithDuplicate( parser, "hyperlinkBehaviour", null, parsed ) )
981            {
982                documentMeta.setHyperlinkBehaviour( parseDocumentHyperlinkBehaviour( parser, strict ) );
983            }
984            else if ( checkFieldWithDuplicate( parser, "language", null, parsed ) )
985            {
986                documentMeta.setLanguage( interpolatedTrimmed( parser.nextText(), "language" ) );
987            }
988            else if ( checkFieldWithDuplicate( parser, "editingCycles", null, parsed ) )
989            {
990                documentMeta.setEditingCycles( getLongValue( interpolatedTrimmed( parser.nextText(), "editingCycles" ), "editingCycles", parser, strict ) );
991            }
992            else if ( checkFieldWithDuplicate( parser, "editingDuration", null, parsed ) )
993            {
994                documentMeta.setEditingDuration( getLongValue( interpolatedTrimmed( parser.nextText(), "editingDuration" ), "editingDuration", parser, strict ) );
995            }
996            else if ( checkFieldWithDuplicate( parser, "documentStatistic", null, parsed ) )
997            {
998                documentMeta.setDocumentStatistic( parseDocumentStatistic( parser, strict ) );
999            }
1000            else if ( checkFieldWithDuplicate( parser, "confidential", null, parsed ) )
1001            {
1002                documentMeta.setConfidential( getBooleanValue( interpolatedTrimmed( parser.nextText(), "confidential" ), "confidential", parser, "false" ) );
1003            }
1004            else if ( checkFieldWithDuplicate( parser, "draft", null, parsed ) )
1005            {
1006                documentMeta.setDraft( getBooleanValue( interpolatedTrimmed( parser.nextText(), "draft" ), "draft", parser, "false" ) );
1007            }
1008            else
1009            {
1010                checkUnknownElement( parser, strict );
1011            }
1012        }
1013        return documentMeta;
1014    } //-- DocumentMeta parseDocumentMeta( XmlPullParser, boolean )
1015
1016    /**
1017     * Method parseDocumentModel.
1018     * 
1019     * @param parser
1020     * @param strict
1021     * @throws IOException
1022     * @throws XmlPullParserException
1023     * @return DocumentModel
1024     */
1025    private DocumentModel parseDocumentModel( XmlPullParser parser, boolean strict )
1026        throws IOException, XmlPullParserException
1027    {
1028        String tagName = parser.getName();
1029        DocumentModel documentModel = new DocumentModel();
1030        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1031        {
1032            String name = parser.getAttributeName( i );
1033            String value = parser.getAttributeValue( i );
1034
1035            if ( name.indexOf( ':' ) >= 0 )
1036            {
1037                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1038            }
1039            else if ( "xmlns".equals( name ) )
1040            {
1041                // ignore xmlns attribute in root class, which is a reserved attribute name
1042            }
1043            else if ( "outputName".equals( name ) )
1044            {
1045                documentModel.setOutputName( interpolatedTrimmed( value, "outputName" ) );
1046            }
1047            else
1048            {
1049                checkUnknownAttribute( parser, name, tagName, strict );
1050            }
1051        }
1052        java.util.Set parsed = new java.util.HashSet();
1053        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1054        {
1055            if ( checkFieldWithDuplicate( parser, "meta", null, parsed ) )
1056            {
1057                documentModel.setMeta( parseDocumentMeta( parser, strict ) );
1058            }
1059            else if ( checkFieldWithDuplicate( parser, "toc", null, parsed ) )
1060            {
1061                documentModel.setToc( parseDocumentTOC( parser, strict ) );
1062            }
1063            else if ( checkFieldWithDuplicate( parser, "cover", null, parsed ) )
1064            {
1065                documentModel.setCover( parseDocumentCover( parser, strict ) );
1066            }
1067            else
1068            {
1069                checkUnknownElement( parser, strict );
1070            }
1071        }
1072        return documentModel;
1073    } //-- DocumentModel parseDocumentModel( XmlPullParser, boolean )
1074
1075    /**
1076     * Method parseDocumentStatistic.
1077     * 
1078     * @param parser
1079     * @param strict
1080     * @throws IOException
1081     * @throws XmlPullParserException
1082     * @return DocumentStatistic
1083     */
1084    private DocumentStatistic parseDocumentStatistic( XmlPullParser parser, boolean strict )
1085        throws IOException, XmlPullParserException
1086    {
1087        String tagName = parser.getName();
1088        DocumentStatistic documentStatistic = new DocumentStatistic();
1089        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1090        {
1091            String name = parser.getAttributeName( i );
1092            String value = parser.getAttributeValue( i );
1093
1094            if ( name.indexOf( ':' ) >= 0 )
1095            {
1096                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1097            }
1098            else if ( "pageCount".equals( name ) )
1099            {
1100                documentStatistic.setPageCount( getLongValue( interpolatedTrimmed( value, "pageCount" ), "pageCount", parser, strict ) );
1101            }
1102            else if ( "tableCount".equals( name ) )
1103            {
1104                documentStatistic.setTableCount( getLongValue( interpolatedTrimmed( value, "tableCount" ), "tableCount", parser, strict ) );
1105            }
1106            else if ( "drawCount".equals( name ) )
1107            {
1108                documentStatistic.setDrawCount( getLongValue( interpolatedTrimmed( value, "drawCount" ), "drawCount", parser, strict ) );
1109            }
1110            else if ( "imageCount".equals( name ) )
1111            {
1112                documentStatistic.setImageCount( getLongValue( interpolatedTrimmed( value, "imageCount" ), "imageCount", parser, strict ) );
1113            }
1114            else if ( "objectCount".equals( name ) )
1115            {
1116                documentStatistic.setObjectCount( getLongValue( interpolatedTrimmed( value, "objectCount" ), "objectCount", parser, strict ) );
1117            }
1118            else if ( "oleObjectCount".equals( name ) )
1119            {
1120                documentStatistic.setOleObjectCount( getLongValue( interpolatedTrimmed( value, "oleObjectCount" ), "oleObjectCount", parser, strict ) );
1121            }
1122            else if ( "paragraphCount".equals( name ) )
1123            {
1124                documentStatistic.setParagraphCount( getLongValue( interpolatedTrimmed( value, "paragraphCount" ), "paragraphCount", parser, strict ) );
1125            }
1126            else if ( "wordCount".equals( name ) )
1127            {
1128                documentStatistic.setWordCount( getLongValue( interpolatedTrimmed( value, "wordCount" ), "wordCount", parser, strict ) );
1129            }
1130            else if ( "characterCount".equals( name ) )
1131            {
1132                documentStatistic.setCharacterCount( getLongValue( interpolatedTrimmed( value, "characterCount" ), "characterCount", parser, strict ) );
1133            }
1134            else if ( "rowCount".equals( name ) )
1135            {
1136                documentStatistic.setRowCount( getLongValue( interpolatedTrimmed( value, "rowCount" ), "rowCount", parser, strict ) );
1137            }
1138            else if ( "frameCount".equals( name ) )
1139            {
1140                documentStatistic.setFrameCount( getLongValue( interpolatedTrimmed( value, "frameCount" ), "frameCount", parser, strict ) );
1141            }
1142            else if ( "sentenceCount".equals( name ) )
1143            {
1144                documentStatistic.setSentenceCount( getLongValue( interpolatedTrimmed( value, "sentenceCount" ), "sentenceCount", parser, strict ) );
1145            }
1146            else if ( "syllableCount".equals( name ) )
1147            {
1148                documentStatistic.setSyllableCount( getLongValue( interpolatedTrimmed( value, "syllableCount" ), "syllableCount", parser, strict ) );
1149            }
1150            else if ( "nonWhitespaceCharacterCount".equals( name ) )
1151            {
1152                documentStatistic.setNonWhitespaceCharacterCount( getLongValue( interpolatedTrimmed( value, "nonWhitespaceCharacterCount" ), "nonWhitespaceCharacterCount", parser, strict ) );
1153            }
1154            else
1155            {
1156                checkUnknownAttribute( parser, name, tagName, strict );
1157            }
1158        }
1159        java.util.Set parsed = new java.util.HashSet();
1160        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1161        {
1162            checkUnknownElement( parser, strict );
1163        }
1164        return documentStatistic;
1165    } //-- DocumentStatistic parseDocumentStatistic( XmlPullParser, boolean )
1166
1167    /**
1168     * Method parseDocumentTOC.
1169     * 
1170     * @param parser
1171     * @param strict
1172     * @throws IOException
1173     * @throws XmlPullParserException
1174     * @return DocumentTOC
1175     */
1176    private DocumentTOC parseDocumentTOC( XmlPullParser parser, boolean strict )
1177        throws IOException, XmlPullParserException
1178    {
1179        String tagName = parser.getName();
1180        DocumentTOC documentTOC = new DocumentTOC();
1181        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1182        {
1183            String name = parser.getAttributeName( i );
1184            String value = parser.getAttributeValue( i );
1185
1186            if ( name.indexOf( ':' ) >= 0 )
1187            {
1188                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1189            }
1190            else if ( "name".equals( name ) )
1191            {
1192                documentTOC.setName( interpolatedTrimmed( value, "name" ) );
1193            }
1194            else if ( "depth".equals( name ) )
1195            {
1196                documentTOC.setDepth( getIntegerValue( interpolatedTrimmed( value, "depth" ), "depth", parser, strict ) );
1197            }
1198            else
1199            {
1200                checkUnknownAttribute( parser, name, tagName, strict );
1201            }
1202        }
1203        java.util.Set parsed = new java.util.HashSet();
1204        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1205        {
1206            if ( "item".equals( parser.getName() ) )
1207            {
1208                java.util.List<DocumentTOCItem> items = documentTOC.getItems();
1209                if ( items == null )
1210                {
1211                    items = new java.util.ArrayList<DocumentTOCItem>();
1212                    documentTOC.setItems( items );
1213                }
1214                items.add( parseDocumentTOCItem( parser, strict ) );
1215            }
1216            else
1217            {
1218                checkUnknownElement( parser, strict );
1219            }
1220        }
1221        return documentTOC;
1222    } //-- DocumentTOC parseDocumentTOC( XmlPullParser, boolean )
1223
1224    /**
1225     * Method parseDocumentTOCItem.
1226     * 
1227     * @param parser
1228     * @param strict
1229     * @throws IOException
1230     * @throws XmlPullParserException
1231     * @return DocumentTOCItem
1232     */
1233    private DocumentTOCItem parseDocumentTOCItem( XmlPullParser parser, boolean strict )
1234        throws IOException, XmlPullParserException
1235    {
1236        String tagName = parser.getName();
1237        DocumentTOCItem documentTOCItem = new DocumentTOCItem();
1238        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1239        {
1240            String name = parser.getAttributeName( i );
1241            String value = parser.getAttributeValue( i );
1242
1243            if ( name.indexOf( ':' ) >= 0 )
1244            {
1245                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1246            }
1247            else if ( "name".equals( name ) )
1248            {
1249                documentTOCItem.setName( interpolatedTrimmed( value, "name" ) );
1250            }
1251            else if ( "ref".equals( name ) )
1252            {
1253                documentTOCItem.setRef( interpolatedTrimmed( value, "ref" ) );
1254            }
1255            else if ( "collapse".equals( name ) )
1256            {
1257                documentTOCItem.setCollapse( getBooleanValue( interpolatedTrimmed( value, "collapse" ), "collapse", parser, "false" ) );
1258            }
1259            else
1260            {
1261                checkUnknownAttribute( parser, name, tagName, strict );
1262            }
1263        }
1264        java.util.Set parsed = new java.util.HashSet();
1265        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1266        {
1267            if ( "item".equals( parser.getName() ) )
1268            {
1269                java.util.List<DocumentTOCItem> items = documentTOCItem.getItems();
1270                if ( items == null )
1271                {
1272                    items = new java.util.ArrayList<DocumentTOCItem>();
1273                    documentTOCItem.setItems( items );
1274                }
1275                items.add( parseDocumentTOCItem( parser, strict ) );
1276            }
1277            else
1278            {
1279                checkUnknownElement( parser, strict );
1280            }
1281        }
1282        return documentTOCItem;
1283    } //-- DocumentTOCItem parseDocumentTOCItem( XmlPullParser, boolean )
1284
1285    /**
1286     * Method parseDocumentTemplate.
1287     * 
1288     * @param parser
1289     * @param strict
1290     * @throws IOException
1291     * @throws XmlPullParserException
1292     * @return DocumentTemplate
1293     */
1294    private DocumentTemplate parseDocumentTemplate( XmlPullParser parser, boolean strict )
1295        throws IOException, XmlPullParserException
1296    {
1297        String tagName = parser.getName();
1298        DocumentTemplate documentTemplate = new DocumentTemplate();
1299        for ( int i = parser.getAttributeCount() - 1; i >= 0; i-- )
1300        {
1301            String name = parser.getAttributeName( i );
1302            String value = parser.getAttributeValue( i );
1303
1304            if ( name.indexOf( ':' ) >= 0 )
1305            {
1306                // just ignore attributes with non-default namespace (for example: xmlns:xsi)
1307            }
1308            else if ( "href".equals( name ) )
1309            {
1310                documentTemplate.setHref( interpolatedTrimmed( value, "href" ) );
1311            }
1312            else if ( "title".equals( name ) )
1313            {
1314                documentTemplate.setTitle( interpolatedTrimmed( value, "title" ) );
1315            }
1316            else if ( "date".equals( name ) )
1317            {
1318                String dateFormat = null;
1319                documentTemplate.setDate( getDateValue( interpolatedTrimmed( value, "date" ), "date", dateFormat, parser ) );
1320            }
1321            else if ( "modifydate".equals( name ) )
1322            {
1323                documentTemplate.setModifydate( interpolatedTrimmed( value, "modifydate" ) );
1324            }
1325            else
1326            {
1327                checkUnknownAttribute( parser, name, tagName, strict );
1328            }
1329        }
1330        java.util.Set parsed = new java.util.HashSet();
1331        while ( ( strict ? parser.nextTag() : nextTag( parser ) ) == XmlPullParser.START_TAG )
1332        {
1333            checkUnknownElement( parser, strict );
1334        }
1335        return documentTemplate;
1336    } //-- DocumentTemplate parseDocumentTemplate( XmlPullParser, boolean )
1337
1338    /**
1339     * Method read.
1340     * 
1341     * @param parser
1342     * @param strict
1343     * @throws IOException
1344     * @throws XmlPullParserException
1345     * @return DocumentModel
1346     */
1347    private DocumentModel read( XmlPullParser parser, boolean strict )
1348        throws IOException, XmlPullParserException
1349    {
1350        DocumentModel documentModel = null;
1351        int eventType = parser.getEventType();
1352        boolean parsed = false;
1353        while ( eventType != XmlPullParser.END_DOCUMENT )
1354        {
1355            if ( eventType == XmlPullParser.START_TAG )
1356            {
1357                if ( strict && ! "document".equals( parser.getName() ) )
1358                {
1359                    throw new XmlPullParserException( "Expected root element 'document' but found '" + parser.getName() + "'", parser, null );
1360                }
1361                else if ( parsed )
1362                {
1363                    // fallback, already expected a XmlPullParserException due to invalid XML
1364                    throw new XmlPullParserException( "Duplicated tag: 'document'", parser, null );
1365                }
1366                documentModel = parseDocumentModel( parser, strict );
1367                documentModel.setModelEncoding( parser.getInputEncoding() );
1368                parsed = true;
1369            }
1370            eventType = parser.next();
1371        }
1372        if ( parsed )
1373        {
1374            return documentModel;
1375        }
1376        throw new XmlPullParserException( "Expected root element 'document' but found no element at all: invalid XML document", parser, null );
1377    } //-- DocumentModel read( XmlPullParser, boolean )
1378
1379    /**
1380     * Sets the state of the "add default entities" flag.
1381     * 
1382     * @param addDefaultEntities
1383     */
1384    public void setAddDefaultEntities( boolean addDefaultEntities )
1385    {
1386        this.addDefaultEntities = addDefaultEntities;
1387    } //-- void setAddDefaultEntities( boolean )
1388
1389    public static interface ContentTransformer
1390{
1391    /**
1392     * Interpolate the value read from the xpp3 document
1393     * @param source The source value
1394     * @param fieldName A description of the field being interpolated. The implementation may use this to
1395     *                           log stuff.
1396     * @return The interpolated value.
1397     */
1398    String transform( String source, String fieldName );
1399}
1400
1401}