001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: * Free SoftwareFoundation, Inc.
023: * 59 Temple Place, Suite 330
024: * Boston, MA 02111-1307 USA
025: *
026: * @author Scott Ferguson
027: */
028:
029: package com.caucho.xsl.java;
030:
031: import com.caucho.java.JavaWriter;
032: import com.caucho.xml.QName;
033: import com.caucho.xpath.pattern.AbstractPattern;
034: import com.caucho.xsl.Sort;
035: import com.caucho.xsl.XslParseException;
036:
037: import java.util.ArrayList;
038:
039: /**
040: * Represents the xsl:for-each element.
041: */
042: public class XslForEach extends XslNode {
043: private String _select;
044:
045: private ArrayList<XslSort> _sorts = new ArrayList<XslSort>();
046:
047: /**
048: * Adds an attribute.
049: */
050: public void addAttribute(QName name, String value)
051: throws XslParseException {
052: if (name.getName().equals("select")) {
053: _select = value;
054: } else
055: super .addAttribute(name, value);
056: }
057:
058: /**
059: * Ends the attributes.
060: */
061: public void endAttributes() throws XslParseException {
062: /*
063: if (_select == null)
064: throw error(L.l("<xsl:for-each> requires a 'select' attribute."));
065: */
066: }
067:
068: /**
069: * Adds a child node.
070: */
071: public void addChild(XslNode node) throws XslParseException {
072: if (node instanceof XslSort) {
073: _sorts.add((XslSort) node);
074: } else
075: super .addChild(node);
076: }
077:
078: /**
079: * Generates the code for the tag
080: *
081: * @param out the output writer for the generated java.
082: */
083: public void generate(JavaWriter out) throws Exception {
084: if (_sorts.size() != 0) {
085: printForEachSort(out);
086: return;
087: }
088:
089: out.println("{");
090: out.pushDepth();
091:
092: AbstractPattern select = parseSelect(_select);
093:
094: boolean hasExprEnv = !allowJavaSelect(select);
095:
096: int id = _gen.generateId();
097:
098: String sel = "_xsl_sel" + id;
099: String oldCxt = "_xsl_cxt" + id;
100: String oldCur = "_xsl_cur" + id;
101: String oldSel = "_xsl_old_sel" + id;
102: String oldEnv = "_xsl_env" + id;
103: String oldSize = "_xsl_old_size" + id;
104:
105: out.println("com.caucho.xpath.pattern.AbstractPattern " + sel
106: + ";");
107: out.print(sel + " = _select_patterns[");
108: out.print(_gen.addSelect(select));
109: out.println("];");
110: out.println("Node " + oldCxt + " = env.getContextNode();");
111: out.println("Node " + oldCur + " = env.getCurrentNode();");
112:
113: if (!hasExprEnv) {
114: out.println("AbstractPattern " + oldSel
115: + " = env.setSelect(node, " + sel + ");");
116: out.println("int " + oldSize + " = env.setContextSize(0);");
117: }
118:
119: // String pos = "_xsl_pos" + unique++;
120: String iter = "_xsl_iter" + _gen.generateId();
121:
122: int oldSelectDepth = _gen.getSelectDepth();
123:
124: // println("int " + pos + " = 0;");
125:
126: boolean hasEnv = false;
127:
128: if (allowJavaSelect(select)) {
129: out.println("ExprEnvironment " + oldEnv
130: + " = env.setExprEnv(null);");
131:
132: String ptr = printSelectBegin(out, select, true, null);
133:
134: _gen.pushLoop();
135: out.println("Node " + _gen.getElement() + " = node;");
136: out.println("node = " + ptr + ";");
137: } else {
138: out.print("NodeIterator " + iter + " = " + sel);
139: out.println(".select(node, " + getEnv() + ");");
140: out.println("ExprEnvironment " + oldEnv
141: + " = env.setExprEnv(" + iter + ");");
142: out.println("while (" + iter + ".hasNext()) {");
143: out.pushDepth();
144: _gen.setSelectDepth(_gen.getSelectDepth() + 1);
145:
146: _gen.pushLoop();
147:
148: out.println("Node " + _gen.getElement() + " = node;");
149: out.println("node = " + iter + ".nextNode();");
150:
151: }
152: out.println("env.setCurrentNode(node);");
153:
154: // println(pos + "++;");
155:
156: // String oldPos = currentPos;
157: // currentPos = pos;
158:
159: AbstractPattern oldNodeListContext = _gen.getNodeListContext();
160: _gen.setNodeListContext(parseMatch(_select));
161:
162: generateChildren(out);
163:
164: _gen.setNodeListContext(oldNodeListContext);
165:
166: // currentPos = oldPos;
167:
168: out.println("node = " + _gen.getElement() + ";");
169: out.println("env.setCurrentNode(" + oldCur + ");");
170:
171: int selectDepth = _gen.getSelectDepth();
172:
173: for (; selectDepth > oldSelectDepth; selectDepth--) {
174: out.popDepth();
175: out.println("}");
176: }
177: _gen.setSelectDepth(oldSelectDepth);
178:
179: out.println("env.setExprEnv(" + oldEnv + ");");
180:
181: if (!hasExprEnv) {
182: out.println("env.setSelect(" + oldCxt + ", " + oldSel
183: + ");");
184: out.println("env.setContextSize(" + oldSize + ");");
185: //println("env.setCurrentNode(node);");
186: }
187:
188: out.popDepth();
189: out.println("}");
190:
191: _gen.popLoop();
192: }
193:
194: /*
195: public void generate(JavaWriter out)
196: throws Exception
197: {
198: Sort []sort = new Sort[_sorts.size()];
199:
200: for (int i = 0; i < _sorts.size(); i++)
201: sort[i] = _sorts.get(i).generateSort();
202:
203: out.println("{");
204: out.pushDepth();
205:
206: AbstractPattern select = parseSelect(_select);
207:
208: boolean hasExprEnv = ! allowJavaSelect(select);
209:
210: int id = _gen.generateId();
211:
212: String sel = "_xsl_sel" + id;
213: String oldCxt = "_xsl_cxt" + id;
214: String oldCur = "_xsl_cur" + id;
215: String oldSel = "_xsl_old_sel" + id;
216: String oldEnv = "_xsl_env" + id;
217:
218: out.println("env.setCurrentNode(node);");
219: String pos = "_xsl_pos" + _gen.generateId();
220: String list = "_xsl_list" + _gen.generateId();
221:
222: int sortIndex = _gen.addSort(sort);
223:
224: println("Node " + oldCxt + " = env.getContextNode();");
225: println("Node " + oldCur + " = env.getCurrentNode();");
226:
227: out.println("ArrayList " + list +
228: " = xslSort(node, env" +
229: ", _select_patterns[" + _gen.addSelect(select) + "]" +
230: ", _xsl_sorts[" + sortIndex + "]);");
231: out.println("env.setContextSize(" + list + ".size());");
232: out.println("for (int " + pos + " = 1; " + pos +
233: " <= " + list + ".size(); " + pos + "++) {");
234: _gen.pushLoop();
235: out.pushDepth();
236: out.println("Node " + _gen.getElement() + " = node;");
237: out.println("node = (Node) " + list + ".get(" + pos + " - 1);");
238:
239: String oldPos = _gen.getCurrentPosition();
240: _gen.setCurrentPosition(pos);
241:
242: out.println("env.setPosition(" + pos + ");");
243:
244: AbstractPattern oldNodeListContext = _gen.getNodeListContext();
245: _gen.setNodeListContext(parseMatch(_select));
246:
247: generateChildren(out);
248:
249: _gen.setCurrentPosition(oldPos);
250:
251: _gen.setNodeListContext(oldNodeListContext);
252:
253: out.println("node = " + _gen.getElement() + ";");
254:
255: out.popDepth();
256: out.println("}");
257: _gen.popLoop();
258: out.popDepth();
259: out.println("}");
260: }
261: */
262:
263: public void printForEachSort(JavaWriter out) throws Exception {
264: Sort[] sort = new Sort[_sorts.size()];
265:
266: for (int i = 0; i < _sorts.size(); i++)
267: sort[i] = _sorts.get(i).generateSort();
268:
269: out.println("{");
270: out.pushDepth();
271:
272: AbstractPattern select = parseSelect(_select);
273:
274: boolean hasExprEnv = !allowJavaSelect(select);
275:
276: int id = _gen.generateId();
277:
278: String sel = "_xsl_sel" + id;
279: String oldCxt = "_xsl_cxt" + id;
280: String oldCur = "_xsl_cur" + id;
281: String oldSel = "_xsl_old_sel" + id;
282: String oldEnv = "_xsl_env" + id;
283:
284: out.println("env.setCurrentNode(node);");
285: String pos = "_xsl_pos" + _gen.generateId();
286: String list = "_xsl_list" + _gen.generateId();
287:
288: int sortIndex = _gen.addSort(sort);
289:
290: out.println("Node " + oldCxt + " = env.getContextNode();");
291: out.println("Node " + oldCur + " = env.getCurrentNode();");
292:
293: out.println("ArrayList " + list + " = xslSort(node, env"
294: + ", _select_patterns[" + _gen.addSelect(select) + "]"
295: + ", _xsl_sorts[" + sortIndex + "]);");
296: out.println("env.setContextSize(" + list + ".size());");
297: out.println("for (int " + pos + " = 1; " + pos + " <= " + list
298: + ".size(); " + pos + "++) {");
299: _gen.pushLoop();
300: out.pushDepth();
301: out.println("Node " + _gen.getElement() + " = node;");
302: out.println("node = (Node) " + list + ".get(" + pos + " - 1);");
303:
304: String oldPos = _gen.getCurrentPosition();
305: _gen.setCurrentPosition(pos);
306:
307: out.println("env.setPosition(" + pos + ");");
308:
309: AbstractPattern oldNodeListContext = _gen.getNodeListContext();
310: _gen.setNodeListContext(parseMatch(_select));
311:
312: generateChildren(out);
313:
314: _gen.setCurrentPosition(oldPos);
315:
316: _gen.setNodeListContext(oldNodeListContext);
317:
318: out.println("node = " + _gen.getElement() + ";");
319:
320: out.popDepth();
321: out.println("}");
322: _gen.popLoop();
323: out.popDepth();
324: out.println("}");
325: }
326: }
|