View Javadoc

1   ////////////////////////////////////////////////////////////////////////////////
2   // MillScript: an Open Spice interpreter and batch website creation tool
3   // Copyright (C) 2001-2004 Open World Ltd
4   // Copyright (C) 2005 Kevin Rogers
5   //
6   // This file is part of MillScript.
7   //
8   // MillScript is free software; you can redistribute it and/or modify it under
9   // the terms of the GNU General Public License as published by the Free
10  // Software Foundation; either version 2 of the License, or (at your option)
11  // any later version.
12  //
13  // MillScript is distributed in the hope that it will be useful, but WITHOUT
14  // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15  // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
16  // more details.
17  //
18  // You should have received a copy of the GNU General Public License along with
19  // MillScript; if not, write to the Free Software Foundation, Inc., 59 Temple
20  // Place, Suite 330, Boston, MA  02111-1307  USA
21  ////////////////////////////////////////////////////////////////////////////////
22  package org.millscript.millscript.action;
23  
24  import org.millscript.commons.xml.api.Name;
25  import org.millscript.commons.xml.tokenizer.AttributesImpl;
26  import org.millscript.millscript.alert.Alerts;
27  import org.millscript.millscript.datatypes.XmlElement;
28  import org.millscript.millscript.vm.Machine;
29  
30  /**
31   * This class implements the action for an XML element expression.
32   *
33   * @see org.millscript.millscript.expr.XMLExpr
34   * @see org.millscript.millscript.syntax.XMLElementSyntax
35   */
36  public final class XMLAction extends Action {
37  
38      /**
39       * The action which generates the XML element name.
40       */
41      private Action tagNameAct;
42  
43      /**
44       * An array of actions which generate the XML elements attribute names.
45       * Each element in this array is paired with a matching element in the
46       * attrValueActs array.
47       */
48      private Action[] attrNameActs;
49  
50      /**
51       * An array of actions which generate the XML elements attribute values.
52       * Each element in this array is paired with a matching element in the
53       * attrNameActs array.
54       */
55      private Action[] attrValueActs;
56  
57      /**
58       * The action for the body of this XML element.
59       */
60      private Action bodyAct;
61  
62      /**
63       * The number of attributes this XML element has.
64       */
65      private int nattrs;
66  
67      /**
68       * Constructs a new XML element action, with the specified element name,
69       * attribute names, attribute values and body actions
70       *
71       * @param a the XML element name action
72       * @param b the array of XML element attribute name actions
73       * @param c the array of XML element attribute value actions
74       * @param d the XML element body action
75       */
76      public XMLAction( final Action a, final Action[] b, final Action[] c, final Action d ) {
77          this.tagNameAct = a;
78          this.attrNameActs = b;
79          this.attrValueActs = c;
80          this.nattrs = attrNameActs.length;
81          if ( nattrs != attrValueActs.length ) {
82              throw(
83                  Alerts.fault( "Trying to build XMLAction with duff args" ).mishap()
84              );
85          }
86          this.bodyAct = d;
87      }
88  
89      /**
90       * @see org.millscript.millscript.action.Action#action(org.millscript.millscript.vm.Machine)
91       */
92      @Override
93      public void action( final Machine mc ) {
94          // Get the XML element name
95          Name tagName = (Name)tagNameAct.act1( mc );
96          // Make an array for the elements attributes in name-value sequence
97          final Name[] attributeNames = new Name[ nattrs ];
98          final String[] attributeValues = new String[ nattrs ];
99          for ( int i = 0; i < nattrs; i++ ) {
100         	// This MUST be a Name and it would be an internal error if it
101         	// is not, i.e. if this generates a class cast exception look at
102         	// XMLElementSyntax...
103             attributeNames[ i ] = (Name) attrNameActs[ i ].act1( mc );
104             // The value is always an Object, so we have to convert to a String
105             // TODO - Is this the right thing to do?
106             attributeValues[ i ] = String.valueOf(
107         		attrValueActs[ i ].act1( mc )
108     		);
109         }
110         // Store the number of results on the stack at the moment
111         int n = mc.getCount();
112         // Perform the body action
113         bodyAct.act( mc );
114         // Make an array of the results generated by the body action
115         Object[] kids = mc.popArgsArray( mc.getCount() - n );
116         // Push a new XML element onto the stack
117         mc.pushObject(
118             new XmlElement(
119                 tagName,
120                 new AttributesImpl( attributeNames, attributeValues, true ),
121                 kids
122             )
123         );
124     }
125 
126 }