KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > xalan > xsltc > compiler > AttributeValueTemplate


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 /*
17  * $Id: AttributeValueTemplate.java,v 1.10 2004/02/16 22:24:29 minchau Exp $
18  */

19
20 package org.apache.xalan.xsltc.compiler;
21
22 import java.util.Enumeration JavaDoc;
23 import java.util.Vector JavaDoc;
24
25 import org.apache.bcel.generic.ConstantPoolGen;
26 import org.apache.bcel.generic.INVOKESPECIAL;
27 import org.apache.bcel.generic.INVOKEVIRTUAL;
28 import org.apache.bcel.generic.Instruction;
29 import org.apache.bcel.generic.InstructionList;
30 import org.apache.bcel.generic.NEW;
31 import org.apache.xalan.xsltc.compiler.util.ClassGenerator;
32 import org.apache.xalan.xsltc.compiler.util.ErrorMsg;
33 import org.apache.xalan.xsltc.compiler.util.MethodGenerator;
34 import org.apache.xalan.xsltc.compiler.util.Type;
35 import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
36
37 /**
38  * @author Jacek Ambroziak
39  * @author Santiago Pericas-Geertsen
40  */

41 final class AttributeValueTemplate extends AttributeValue {
42
43     public AttributeValueTemplate(String JavaDoc value, Parser parser,
44     SyntaxTreeNode parent)
45     {
46     setParent(parent);
47     setParser(parser);
48     if (check(value, parser)) {
49         parseAVTemplate(0, value, parser);
50     }
51     }
52
53     private void parseAVTemplate(final int start, String JavaDoc text, Parser parser) {
54     String JavaDoc str;
55
56     if (text == null) return;
57
58     // Get first single opening braces
59
int open = start - 2;
60     do {
61         open = text.indexOf('{', open+2);
62     } while ((open != -1) &&
63          (open < (text.length()-1)) &&
64          (text.charAt(open+1) == '{'));
65
66     if (open != -1) {
67         // Get first single closing braces
68
int close = open - 2;
69         do {
70         close = text.indexOf('}', close+2);
71         } while ((close != -1) &&
72              (close < (text.length()-1)) &&
73              (text.charAt(close+1) == '}'));
74         
75         // Add literal expressiong before AVT
76
if (open > start) {
77         str = removeDuplicateBraces(text.substring(start, open));
78         addElement(new LiteralExpr(str));
79         }
80         // Add the AVT itself
81
if (close > open + 1) {
82         str = text.substring(open + 1, close);
83         str = removeDuplicateBraces(text.substring(open+1,close));
84         addElement(parser.parseExpression(this, str));
85         }
86         // Parse rest of string
87
parseAVTemplate(close + 1, text, parser);
88         
89     }
90     else if (start < text.length()) {
91         // Add literal expression following AVT
92
str = removeDuplicateBraces(text.substring(start));
93         addElement(new LiteralExpr(str));
94     }
95     }
96
97     public String JavaDoc removeDuplicateBraces(String JavaDoc orig) {
98     String JavaDoc result = orig;
99     int index;
100
101     while ((index = result.indexOf("{{")) != -1) {
102         result = result.substring(0,index) +
103         result.substring(index+1,result.length());
104     }
105
106     while ((index = result.indexOf("}}")) != -1) {
107         result = result.substring(0,index) +
108         result.substring(index+1,result.length());
109     }
110
111     return(result);
112     }
113
114     public Type typeCheck(SymbolTable stable) throws TypeCheckError {
115     final Vector JavaDoc contents = getContents();
116     final int n = contents.size();
117     for (int i = 0; i < n; i++) {
118         final Expression exp = (Expression)contents.elementAt(i);
119         if (!exp.typeCheck(stable).identicalTo(Type.String)) {
120         contents.setElementAt(new CastExpr(exp, Type.String), i);
121         }
122     }
123     return _type = Type.String;
124     }
125
126     public String JavaDoc toString() {
127     final StringBuffer JavaDoc buffer = new StringBuffer JavaDoc("AVT:[");
128     final int count = elementCount();
129     for (int i = 0; i < count; i++) {
130         buffer.append(elementAt(i).toString());
131         if (i < count - 1)
132         buffer.append(' ');
133     }
134     return buffer.append(']').toString();
135     }
136         
137     public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
138     if (elementCount() == 1) {
139         final Expression exp = (Expression)elementAt(0);
140         exp.translate(classGen, methodGen);
141     }
142     else {
143         final ConstantPoolGen cpg = classGen.getConstantPool();
144         final InstructionList il = methodGen.getInstructionList();
145         final int initBuffer = cpg.addMethodref(STRING_BUFFER_CLASS,
146                             "<init>", "()V");
147         final Instruction append =
148         new INVOKEVIRTUAL(cpg.addMethodref(STRING_BUFFER_CLASS,
149                            "append",
150                            "(" + STRING_SIG + ")"
151                            + STRING_BUFFER_SIG));
152         
153         final int toString = cpg.addMethodref(STRING_BUFFER_CLASS,
154                           "toString",
155                           "()"+STRING_SIG);
156         il.append(new NEW(cpg.addClass(STRING_BUFFER_CLASS)));
157         il.append(DUP);
158         il.append(new INVOKESPECIAL(initBuffer));
159         // StringBuffer is on the stack
160
final Enumeration JavaDoc elements = elements();
161         while (elements.hasMoreElements()) {
162         final Expression exp = (Expression)elements.nextElement();
163         exp.translate(classGen, methodGen);
164         il.append(append);
165         }
166         il.append(new INVOKEVIRTUAL(toString));
167     }
168     }
169
170     private boolean check(String JavaDoc value, Parser parser) {
171     // !!! how about quoted/escaped braces?
172
if (value == null) return true;
173
174     final char[] chars = value.toCharArray();
175     int level = 0;
176     for (int i = 0; i < chars.length; i++) {
177         switch (chars[i]) {
178         case '{':
179         if (((i+1) == (chars.length)) || (chars[i+1] != '{'))
180             ++level;
181         else
182             i++;
183         break;
184         case '}':
185         if (((i+1) == (chars.length)) || (chars[i+1] != '}'))
186             --level;
187         else
188             i++;
189         break;
190         default:
191         continue;
192         }
193         switch (level) {
194         case 0:
195         case 1:
196         continue;
197         default:
198         reportError(getParent(), parser,
199                 ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value);
200         return false;
201         }
202     }
203     if (level != 0) {
204         reportError(getParent(), parser,
205             ErrorMsg.ATTR_VAL_TEMPLATE_ERR, value);
206         return false;
207     }
208     return true;
209     }
210 }
211
Popular Tags