1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.millscript.millscript.loaders;
23
24 import org.millscript.commons.alert.Alert;
25 import org.millscript.commons.util.IList;
26 import org.millscript.commons.vfs.VFile;
27 import org.millscript.commons.xml.api.tokenizer.XmlTokenizer;
28 import org.millscript.commons.xml.tokenizer.XmlTokenizerFactory;
29 import org.millscript.commons.xml.tokenizer.wellformed.WellFormedXmlTokenizer;
30 import org.millscript.millscript.alert.Alerts;
31
32 /**
33 * This class implements the MillScript XML loader. The specified file is
34 * loaded as an XML file and transformed into a MillScript fragment.
35 */
36 public final class XMLLoader extends ValueLoader {
37
38 /**
39 * The XML tokenizer factory we can use to get an XML tokenizer for the
40 * XML.
41 */
42 XmlTokenizerFactory factory = new XmlTokenizerFactory();
43
44 /**
45 * The current token visitor we can use to construct our internal
46 * representations.
47 */
48 XMLLoaderTokenVisitor tokenVisitor;
49
50 /**
51 * Constructs a new XML loader.
52 */
53 public XMLLoader() {
54 this.factory.setNamespaceAware( true );
55 }
56
57 /**
58 * @see org.millscript.millscript.loaders.Loader#loadValue()
59 */
60 @Override
61 public Object loadValue() {
62 if ( this.entry instanceof VFile && this.entry.exists() ) {
63
64 final XmlTokenizer xmlTokenizer = new WellFormedXmlTokenizer(
65 this.factory.getTokenizer(
66 ((VFile) this.entry).getInputStream()
67 )
68 );
69 try {
70
71 this.tokenVisitor = new XMLLoaderTokenVisitor( this, null, null );
72 while ( xmlTokenizer.hasNextToken() ) {
73 xmlTokenizer.nextToken().visit( this.tokenVisitor );
74 }
75 } catch ( Alert a ) {
76 this.setLineNumber( xmlTokenizer.getLineNumber() );
77 throw a.remishap();
78 }
79
80 final IList bodyExpr = this.tokenVisitor.getBody();
81 if ( bodyExpr.size() != 1 ) {
82
83 throw Alerts.fault(
84 "XML files can only have a single root entity"
85 ).mishap();
86 } else {
87
88 return bodyExpr.first();
89 }
90 } else {
91
92 throw(
93 Alerts.compile(
94 "Inventory entry is not a file",
95 "Template loader can only be used to load files"
96 ).mishap()
97 );
98 }
99 }
100
101 }