View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   //
5   // This file is part of MillScript.
6   //
7   // MillScript is free software; you can redistribute it and/or modify it under
8   // the terms of the GNU General Public License as published by the Free
9   // Software Foundation; either version 2 of the License, or (at your option)
10  // any later version.
11  //
12  // MillScript is distributed in the hope that it will be useful, but WITHOUT
13  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  // more details.
16  //
17  // You should have received a copy of the GNU General Public License along with
18  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
19  // Place, Suite 330, Boston, MA  02111-1307  USA
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              // Compile everything but the leading '?'
76              // arg[ s ]
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              // End this element
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             // ok, we allow these special elements through, just start another
108             // normal element
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 }