1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.millscript.loaders;
22
23 import org.millscript.commons.util.IMap;
24 import org.millscript.commons.util.list.ISingletonList;
25 import org.millscript.commons.util.map.ITwoArrayMap;
26 import org.millscript.commons.xml.api.Name;
27 import org.millscript.commons.xml.api.token.EndTagToken;
28 import org.millscript.commons.xml.api.token.StartTagToken;
29 import org.millscript.commons.xml.tokenizer.NoNamespacesName;
30 import org.millscript.millscript.expr.ConstantExpr;
31 import org.millscript.millscript.expr.Expr;
32 import org.millscript.millscript.expr.FnCompExpr;
33 import org.millscript.millscript.expr.IndexExpr;
34 import org.millscript.millscript.expr.LambdaExpr;
35 import org.millscript.millscript.expr.NameExpr;
36
37 /**
38 * This class implements the MillScript skeleton loader. The specified file is
39 * loaded as an XHTML file, but the additional elements <code>field</code> and
40 * <code>item</code> and attribute values starting with <code>?</code> take on
41 * special meaning.
42 */
43 public final class SkeletonLoader extends BasicXHTMLTemplateLoader {
44
45 /**
46 * A mapping from special element names to their handler.
47 */
48 private final IMap< Name, SpecialTemplateName > specialSkeletonElements;
49
50 /**
51 * Constructs a new XHTML skeleton loader which does not support XML
52 * namespaces, with the default set of special elements.
53 */
54 public SkeletonLoader() {
55 super( false );
56 this.specialSkeletonElements = new ITwoArrayMap< Name, SpecialTemplateName >(
57 new Name[] {
58 new NoNamespacesName( "item" ),
59 new NoNamespacesName( "field" )
60 },
61 new SpecialTemplateName[] {
62 new ItemName( this ),
63 new FieldName( this )
64 },
65 true
66 );
67 }
68
69 /**
70 * @see org.millscript.millscript.loaders.BasicTemplateLoader#compAttributeValue(java.lang.String)
71 */
72 @Override
73 public Expr compAttributeValue( final String value ) {
74 if ( value.length() > 0 && value.charAt( 0 ) == '?' ) {
75
76
77 return IndexExpr.make(
78 new NameExpr( "arg" ),
79 new ConstantExpr( value.substring( 1, value.length() ) )
80 );
81 } else {
82 return new ConstantExpr( value );
83 }
84 }
85
86 /**
87 * @see org.millscript.millscript.loaders.BasicTemplateLoader#compileEndTag(org.millscript.commons.xml.api.token.EndTagToken)
88 */
89 @Override
90 public void compileEndTag( final EndTagToken token ) {
91 final SpecialTemplateName specialName = this.specialSkeletonElements.get( token.getName() );
92 if ( specialName == null ) {
93 super.compileEndTag( token );
94 } else {
95 specialName.handle();
96
97 tokenVisitor = tokenVisitor.parentTokenVisitor;
98 }
99 }
100
101 /**
102 * @see org.millscript.millscript.loaders.BasicTemplateLoader#compileStartTag(org.millscript.commons.xml.api.token.StartTagToken)
103 */
104 @Override
105 public void compileStartTag( final StartTagToken token ) {
106 if ( this.specialSkeletonElements.containsKey( token.getName() ) ) {
107
108
109 this.tokenVisitor = new BasicTemplateLoaderElementTokenVisitor( this, this.tokenVisitor, token );
110 } else {
111 super.compileStartTag( token );
112 }
113 }
114
115 /**
116 * @see org.millscript.millscript.loaders.BasicTemplateLoader#makeLambda(java.lang.String, org.millscript.millscript.expr.Expr)
117 */
118 @Override
119 public Expr makeLambda( final String theName, final Expr body ) {
120 return (
121 new FnCompExpr(
122 theName,
123 new NameExpr( "newTreeMap" ),
124 new LambdaExpr(
125 theName,
126 new ISingletonList< NameExpr >( new NameExpr( "arg" ) ),
127 null,
128 body
129 )
130 )
131 );
132 }
133
134 }