author | joehw |
Wed, 18 Oct 2017 13:25:49 -0700 | |
changeset 47359 | e1a6c0168741 |
parent 47216 | 71c04702a3d5 |
child 48409 | 5ab69533994b |
permissions | -rw-r--r-- |
6 | 1 |
/* |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
2 |
* Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved. |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
3 |
* @LastModified: Oct 2017 |
6 | 4 |
*/ |
5 |
/* |
|
33349 | 6 |
* Licensed to the Apache Software Foundation (ASF) under one or more |
7 |
* contributor license agreements. See the NOTICE file distributed with |
|
8 |
* this work for additional information regarding copyright ownership. |
|
9 |
* The ASF licenses this file to You under the Apache License, Version 2.0 |
|
10 |
* (the "License"); you may not use this file except in compliance with |
|
11 |
* the License. You may obtain a copy of the License at |
|
6 | 12 |
* |
33349 | 13 |
* http://www.apache.org/licenses/LICENSE-2.0 |
6 | 14 |
* |
15 |
* Unless required by applicable law or agreed to in writing, software |
|
16 |
* distributed under the License is distributed on an "AS IS" BASIS, |
|
17 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
18 |
* See the License for the specific language governing permissions and |
|
19 |
* limitations under the License. |
|
20 |
*/ |
|
21 |
/* |
|
22 |
* $Id: Stylesheet.java,v 1.5 2005/09/28 13:48:16 pvedula Exp $ |
|
23 |
*/ |
|
24 |
||
25 |
package com.sun.org.apache.xalan.internal.xsltc.compiler; |
|
26 |
||
27 |
import com.sun.org.apache.bcel.internal.generic.ANEWARRAY; |
|
28 |
import com.sun.org.apache.bcel.internal.generic.BasicType; |
|
29 |
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen; |
|
30 |
import com.sun.org.apache.bcel.internal.generic.FieldGen; |
|
31 |
import com.sun.org.apache.bcel.internal.generic.GETFIELD; |
|
32 |
import com.sun.org.apache.bcel.internal.generic.GETSTATIC; |
|
33 |
import com.sun.org.apache.bcel.internal.generic.INVOKEINTERFACE; |
|
34 |
import com.sun.org.apache.bcel.internal.generic.INVOKESPECIAL; |
|
41623
d32a755d06d1
8167179: Make XSL generated namespace prefixes local to transformation process
aefimov
parents:
33349
diff
changeset
|
35 |
import com.sun.org.apache.bcel.internal.generic.INVOKESTATIC; |
6 | 36 |
import com.sun.org.apache.bcel.internal.generic.INVOKEVIRTUAL; |
37 |
import com.sun.org.apache.bcel.internal.generic.ISTORE; |
|
38 |
import com.sun.org.apache.bcel.internal.generic.InstructionHandle; |
|
39 |
import com.sun.org.apache.bcel.internal.generic.InstructionList; |
|
40 |
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen; |
|
41 |
import com.sun.org.apache.bcel.internal.generic.NEW; |
|
42 |
import com.sun.org.apache.bcel.internal.generic.NEWARRAY; |
|
43 |
import com.sun.org.apache.bcel.internal.generic.PUSH; |
|
44 |
import com.sun.org.apache.bcel.internal.generic.PUTFIELD; |
|
45 |
import com.sun.org.apache.bcel.internal.generic.PUTSTATIC; |
|
46 |
import com.sun.org.apache.bcel.internal.generic.TargetLostException; |
|
47 |
import com.sun.org.apache.bcel.internal.util.InstructionFinder; |
|
48 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ClassGenerator; |
|
49 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.ErrorMsg; |
|
50 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodGenerator; |
|
51 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; |
|
52 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; |
|
53 |
import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Util; |
|
54 |
import com.sun.org.apache.xalan.internal.xsltc.runtime.AbstractTranslet; |
|
55 |
import com.sun.org.apache.xml.internal.dtm.DTM; |
|
33349 | 56 |
import com.sun.org.apache.xml.internal.utils.SystemIDResolver; |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
57 |
import java.util.ArrayList; |
33349 | 58 |
import java.util.HashMap; |
59 |
import java.util.Iterator; |
|
60 |
import java.util.List; |
|
61 |
import java.util.Map; |
|
62 |
import java.util.Properties; |
|
63 |
import java.util.StringTokenizer; |
|
6 | 64 |
|
65 |
/** |
|
66 |
* @author Jacek Ambroziak |
|
67 |
* @author Santiago Pericas-Geertsen |
|
68 |
* @author Morten Jorgensen |
|
69 |
*/ |
|
70 |
public final class Stylesheet extends SyntaxTreeNode { |
|
71 |
||
72 |
/** |
|
73 |
* XSLT version defined in the stylesheet. |
|
74 |
*/ |
|
75 |
private String _version; |
|
76 |
||
77 |
/** |
|
78 |
* Internal name of this stylesheet used as a key into the symbol table. |
|
79 |
*/ |
|
80 |
private QName _name; |
|
81 |
||
82 |
/** |
|
83 |
* A URI that represents the system ID for this stylesheet. |
|
84 |
*/ |
|
85 |
private String _systemId; |
|
86 |
||
87 |
/** |
|
88 |
* A reference to the parent stylesheet or null if topmost. |
|
89 |
*/ |
|
90 |
private Stylesheet _parentStylesheet; |
|
91 |
||
92 |
/** |
|
93 |
* Contains global variables and parameters defined in the stylesheet. |
|
94 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
95 |
private List<VariableBase> _globals = new ArrayList<>(); |
6 | 96 |
|
97 |
/** |
|
98 |
* Used to cache the result returned by <code>hasLocalParams()</code>. |
|
99 |
*/ |
|
100 |
private Boolean _hasLocalParams = null; |
|
101 |
||
102 |
/** |
|
103 |
* The name of the class being generated. |
|
104 |
*/ |
|
105 |
private String _className; |
|
106 |
||
107 |
/** |
|
108 |
* Contains all templates defined in this stylesheet |
|
109 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
110 |
private final List<Template> _templates = new ArrayList<>(); |
6 | 111 |
|
112 |
/** |
|
113 |
* Used to cache result of <code>getAllValidTemplates()</code>. Only |
|
114 |
* set in top-level stylesheets that include/import other stylesheets. |
|
115 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
116 |
private List<Template> _allValidTemplates = null; |
6 | 117 |
|
118 |
/** |
|
119 |
* Counter to generate unique mode suffixes. |
|
120 |
*/ |
|
121 |
private int _nextModeSerial = 1; |
|
122 |
||
123 |
/** |
|
124 |
* Mapping between mode names and Mode instances. |
|
125 |
*/ |
|
33349 | 126 |
private final Map<String, Mode> _modes = new HashMap<>(); |
6 | 127 |
|
128 |
/** |
|
129 |
* A reference to the default Mode object. |
|
130 |
*/ |
|
131 |
private Mode _defaultMode; |
|
132 |
||
133 |
/** |
|
134 |
* Mapping between extension URIs and their prefixes. |
|
135 |
*/ |
|
33349 | 136 |
private final Map<String, String> _extensions = new HashMap<>(); |
6 | 137 |
|
138 |
/** |
|
139 |
* Reference to the stylesheet from which this stylesheet was |
|
140 |
* imported (if any). |
|
141 |
*/ |
|
142 |
public Stylesheet _importedFrom = null; |
|
143 |
||
144 |
/** |
|
145 |
* Reference to the stylesheet from which this stylesheet was |
|
146 |
* included (if any). |
|
147 |
*/ |
|
148 |
public Stylesheet _includedFrom = null; |
|
149 |
||
150 |
/** |
|
151 |
* Array of all the stylesheets imported or included from this one. |
|
152 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
153 |
private List<Stylesheet> _includedStylesheets = null; |
6 | 154 |
|
155 |
/** |
|
156 |
* Import precendence for this stylesheet. |
|
157 |
*/ |
|
158 |
private int _importPrecedence = 1; |
|
159 |
||
160 |
/** |
|
161 |
* Minimum precendence of any descendant stylesheet by inclusion or |
|
162 |
* importation. |
|
163 |
*/ |
|
164 |
private int _minimumDescendantPrecedence = -1; |
|
165 |
||
166 |
/** |
|
167 |
* Mapping between key names and Key objects (needed by Key/IdPattern). |
|
168 |
*/ |
|
33349 | 169 |
private Map<String, Key> _keys = new HashMap<>(); |
6 | 170 |
|
171 |
/** |
|
172 |
* A reference to the SourceLoader set by the user (a URIResolver |
|
173 |
* if the JAXP API is being used). |
|
174 |
*/ |
|
175 |
private SourceLoader _loader = null; |
|
176 |
||
177 |
/** |
|
178 |
* Flag indicating if format-number() is called. |
|
179 |
*/ |
|
180 |
private boolean _numberFormattingUsed = false; |
|
181 |
||
182 |
/** |
|
183 |
* Flag indicating if this is a simplified stylesheets. A template |
|
184 |
* matching on "/" must be added in this case. |
|
185 |
*/ |
|
186 |
private boolean _simplified = false; |
|
187 |
||
188 |
/** |
|
189 |
* Flag indicating if multi-document support is needed. |
|
190 |
*/ |
|
191 |
private boolean _multiDocument = false; |
|
192 |
||
193 |
/** |
|
194 |
* Flag indicating if nodset() is called. |
|
195 |
*/ |
|
196 |
private boolean _callsNodeset = false; |
|
197 |
||
198 |
/** |
|
199 |
* Flag indicating if id() is called. |
|
200 |
*/ |
|
201 |
private boolean _hasIdCall = false; |
|
202 |
||
203 |
/** |
|
204 |
* Set to true to enable template inlining optimization. |
|
12458 | 205 |
* @see XSLTC#_templateInlining |
6 | 206 |
*/ |
12458 | 207 |
private boolean _templateInlining = false; |
6 | 208 |
|
209 |
/** |
|
210 |
* A reference to the last xsl:output object found in the styleshet. |
|
211 |
*/ |
|
212 |
private Output _lastOutputElement = null; |
|
213 |
||
214 |
/** |
|
215 |
* Output properties for this stylesheet. |
|
216 |
*/ |
|
217 |
private Properties _outputProperties = null; |
|
218 |
||
219 |
/** |
|
220 |
* Output method for this stylesheet (must be set to one of |
|
221 |
* the constants defined below). |
|
222 |
*/ |
|
223 |
private int _outputMethod = UNKNOWN_OUTPUT; |
|
224 |
||
225 |
// Output method constants |
|
226 |
public static final int UNKNOWN_OUTPUT = 0; |
|
227 |
public static final int XML_OUTPUT = 1; |
|
228 |
public static final int HTML_OUTPUT = 2; |
|
229 |
public static final int TEXT_OUTPUT = 3; |
|
230 |
||
231 |
/** |
|
232 |
* Return the output method |
|
233 |
*/ |
|
234 |
public int getOutputMethod() { |
|
235 |
return _outputMethod; |
|
236 |
} |
|
237 |
||
238 |
/** |
|
239 |
* Check and set the output method |
|
240 |
*/ |
|
241 |
private void checkOutputMethod() { |
|
242 |
if (_lastOutputElement != null) { |
|
243 |
String method = _lastOutputElement.getOutputMethod(); |
|
244 |
if (method != null) { |
|
245 |
if (method.equals("xml")) |
|
246 |
_outputMethod = XML_OUTPUT; |
|
247 |
else if (method.equals("html")) |
|
248 |
_outputMethod = HTML_OUTPUT; |
|
249 |
else if (method.equals("text")) |
|
250 |
_outputMethod = TEXT_OUTPUT; |
|
251 |
} |
|
252 |
} |
|
253 |
} |
|
254 |
||
255 |
public boolean getTemplateInlining() { |
|
256 |
return _templateInlining; |
|
257 |
} |
|
258 |
||
259 |
public void setTemplateInlining(boolean flag) { |
|
260 |
_templateInlining = flag; |
|
261 |
} |
|
262 |
||
263 |
public boolean isSimplified() { |
|
264 |
return(_simplified); |
|
265 |
} |
|
266 |
||
267 |
public void setSimplified() { |
|
268 |
_simplified = true; |
|
269 |
} |
|
270 |
||
271 |
public void setHasIdCall(boolean flag) { |
|
272 |
_hasIdCall = flag; |
|
273 |
} |
|
274 |
||
275 |
public void setOutputProperty(String key, String value) { |
|
276 |
if (_outputProperties == null) { |
|
277 |
_outputProperties = new Properties(); |
|
278 |
} |
|
279 |
_outputProperties.setProperty(key, value); |
|
280 |
} |
|
281 |
||
282 |
public void setOutputProperties(Properties props) { |
|
283 |
_outputProperties = props; |
|
284 |
} |
|
285 |
||
286 |
public Properties getOutputProperties() { |
|
287 |
return _outputProperties; |
|
288 |
} |
|
289 |
||
290 |
public Output getLastOutputElement() { |
|
291 |
return _lastOutputElement; |
|
292 |
} |
|
293 |
||
294 |
public void setMultiDocument(boolean flag) { |
|
295 |
_multiDocument = flag; |
|
296 |
} |
|
297 |
||
298 |
public boolean isMultiDocument() { |
|
299 |
return _multiDocument; |
|
300 |
} |
|
301 |
||
302 |
public void setCallsNodeset(boolean flag) { |
|
303 |
if (flag) setMultiDocument(flag); |
|
304 |
_callsNodeset = flag; |
|
305 |
} |
|
306 |
||
307 |
public boolean callsNodeset() { |
|
308 |
return _callsNodeset; |
|
309 |
} |
|
310 |
||
311 |
public void numberFormattingUsed() { |
|
312 |
_numberFormattingUsed = true; |
|
313 |
/* |
|
314 |
* Fix for bug 23046, if the stylesheet is included, set the |
|
315 |
* numberFormattingUsed flag to the parent stylesheet too. |
|
316 |
* AbstractTranslet.addDecimalFormat() will be inlined once for the |
|
317 |
* outer most stylesheet. |
|
318 |
*/ |
|
319 |
Stylesheet parent = getParentStylesheet(); |
|
320 |
if (null != parent) parent.numberFormattingUsed(); |
|
321 |
} |
|
322 |
||
323 |
public void setImportPrecedence(final int precedence) { |
|
324 |
// Set import precedence for this stylesheet |
|
325 |
_importPrecedence = precedence; |
|
326 |
||
327 |
// Set import precedence for all included stylesheets |
|
33349 | 328 |
final Iterator<SyntaxTreeNode> elements = elements(); |
329 |
while (elements.hasNext()) { |
|
330 |
SyntaxTreeNode child = elements.next(); |
|
6 | 331 |
if (child instanceof Include) { |
332 |
Stylesheet included = ((Include)child).getIncludedStylesheet(); |
|
333 |
if (included != null && included._includedFrom == this) { |
|
334 |
included.setImportPrecedence(precedence); |
|
335 |
} |
|
336 |
} |
|
337 |
} |
|
338 |
||
339 |
// Set import precedence for the stylesheet that imported this one |
|
340 |
if (_importedFrom != null) { |
|
341 |
if (_importedFrom.getImportPrecedence() < precedence) { |
|
342 |
final Parser parser = getParser(); |
|
343 |
final int nextPrecedence = parser.getNextImportPrecedence(); |
|
344 |
_importedFrom.setImportPrecedence(nextPrecedence); |
|
345 |
} |
|
346 |
} |
|
347 |
// Set import precedence for the stylesheet that included this one |
|
348 |
else if (_includedFrom != null) { |
|
349 |
if (_includedFrom.getImportPrecedence() != precedence) |
|
350 |
_includedFrom.setImportPrecedence(precedence); |
|
351 |
} |
|
352 |
} |
|
353 |
||
354 |
public int getImportPrecedence() { |
|
355 |
return _importPrecedence; |
|
356 |
} |
|
357 |
||
358 |
/** |
|
359 |
* Get the minimum of the precedence of this stylesheet, any stylesheet |
|
360 |
* imported by this stylesheet and any include/import descendant of this |
|
361 |
* stylesheet. |
|
362 |
*/ |
|
363 |
public int getMinimumDescendantPrecedence() { |
|
364 |
if (_minimumDescendantPrecedence == -1) { |
|
365 |
// Start with precedence of current stylesheet as a basis. |
|
366 |
int min = getImportPrecedence(); |
|
367 |
||
368 |
// Recursively examine all imported/included stylesheets. |
|
369 |
final int inclImpCount = (_includedStylesheets != null) |
|
370 |
? _includedStylesheets.size() |
|
371 |
: 0; |
|
372 |
||
373 |
for (int i = 0; i < inclImpCount; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
374 |
int prec = (_includedStylesheets.get(i)).getMinimumDescendantPrecedence(); |
6 | 375 |
|
376 |
if (prec < min) { |
|
377 |
min = prec; |
|
378 |
} |
|
379 |
} |
|
380 |
||
381 |
_minimumDescendantPrecedence = min; |
|
382 |
} |
|
383 |
return _minimumDescendantPrecedence; |
|
384 |
} |
|
385 |
||
386 |
public boolean checkForLoop(String systemId) { |
|
387 |
// Return true if this stylesheet includes/imports itself |
|
388 |
if (_systemId != null && _systemId.equals(systemId)) { |
|
389 |
return true; |
|
390 |
} |
|
391 |
// Then check with any stylesheets that included/imported this one |
|
392 |
if (_parentStylesheet != null) |
|
393 |
return _parentStylesheet.checkForLoop(systemId); |
|
394 |
// Otherwise OK |
|
395 |
return false; |
|
396 |
} |
|
397 |
||
398 |
public void setParser(Parser parser) { |
|
399 |
super.setParser(parser); |
|
400 |
_name = makeStylesheetName("__stylesheet_"); |
|
401 |
} |
|
402 |
||
403 |
public void setParentStylesheet(Stylesheet parent) { |
|
404 |
_parentStylesheet = parent; |
|
405 |
} |
|
406 |
||
407 |
public Stylesheet getParentStylesheet() { |
|
408 |
return _parentStylesheet; |
|
409 |
} |
|
410 |
||
411 |
public void setImportingStylesheet(Stylesheet parent) { |
|
412 |
_importedFrom = parent; |
|
413 |
parent.addIncludedStylesheet(this); |
|
414 |
} |
|
415 |
||
416 |
public void setIncludingStylesheet(Stylesheet parent) { |
|
417 |
_includedFrom = parent; |
|
418 |
parent.addIncludedStylesheet(this); |
|
419 |
} |
|
420 |
||
421 |
public void addIncludedStylesheet(Stylesheet child) { |
|
422 |
if (_includedStylesheets == null) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
423 |
_includedStylesheets = new ArrayList<>(); |
6 | 424 |
} |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
425 |
_includedStylesheets.add(child); |
6 | 426 |
} |
427 |
||
428 |
public void setSystemId(String systemId) { |
|
429 |
if (systemId != null) { |
|
430 |
_systemId = SystemIDResolver.getAbsoluteURI(systemId); |
|
431 |
} |
|
432 |
} |
|
433 |
||
434 |
public String getSystemId() { |
|
435 |
return _systemId; |
|
436 |
} |
|
437 |
||
438 |
public void setSourceLoader(SourceLoader loader) { |
|
439 |
_loader = loader; |
|
440 |
} |
|
441 |
||
442 |
public SourceLoader getSourceLoader() { |
|
443 |
return _loader; |
|
444 |
} |
|
445 |
||
446 |
private QName makeStylesheetName(String prefix) { |
|
447 |
return getParser().getQName(prefix+getXSLTC().nextStylesheetSerial()); |
|
448 |
} |
|
449 |
||
450 |
/** |
|
451 |
* Returns true if this stylesheet has global vars or params. |
|
452 |
*/ |
|
453 |
public boolean hasGlobals() { |
|
454 |
return _globals.size() > 0; |
|
455 |
} |
|
456 |
||
457 |
/** |
|
458 |
* Returns true if at least one template in the stylesheet has params |
|
459 |
* defined. Uses the variable <code>_hasLocalParams</code> to cache the |
|
460 |
* result. |
|
461 |
*/ |
|
462 |
public boolean hasLocalParams() { |
|
463 |
if (_hasLocalParams == null) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
464 |
List<Template> templates = getAllValidTemplates(); |
6 | 465 |
final int n = templates.size(); |
466 |
for (int i = 0; i < n; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
467 |
final Template template = templates.get(i); |
6 | 468 |
if (template.hasParams()) { |
12458 | 469 |
_hasLocalParams = Boolean.TRUE; |
6 | 470 |
return true; |
471 |
} |
|
472 |
} |
|
12458 | 473 |
_hasLocalParams = Boolean.FALSE; |
6 | 474 |
return false; |
475 |
} |
|
476 |
else { |
|
477 |
return _hasLocalParams.booleanValue(); |
|
478 |
} |
|
479 |
} |
|
480 |
||
481 |
/** |
|
482 |
* Adds a single prefix mapping to this syntax tree node. |
|
483 |
* @param prefix Namespace prefix. |
|
484 |
* @param uri Namespace URI. |
|
485 |
*/ |
|
486 |
protected void addPrefixMapping(String prefix, String uri) { |
|
487 |
if (prefix.equals(EMPTYSTRING) && uri.equals(XHTML_URI)) return; |
|
488 |
super.addPrefixMapping(prefix, uri); |
|
489 |
} |
|
490 |
||
491 |
/** |
|
492 |
* Store extension URIs |
|
493 |
*/ |
|
494 |
private void extensionURI(String prefixes, SymbolTable stable) { |
|
495 |
if (prefixes != null) { |
|
496 |
StringTokenizer tokens = new StringTokenizer(prefixes); |
|
497 |
while (tokens.hasMoreTokens()) { |
|
498 |
final String prefix = tokens.nextToken(); |
|
499 |
final String uri = lookupNamespace(prefix); |
|
500 |
if (uri != null) { |
|
501 |
_extensions.put(uri, prefix); |
|
502 |
} |
|
503 |
} |
|
504 |
} |
|
505 |
} |
|
506 |
||
507 |
public boolean isExtension(String uri) { |
|
508 |
return (_extensions.get(uri) != null); |
|
509 |
} |
|
510 |
||
12458 | 511 |
public void declareExtensionPrefixes(Parser parser) { |
6 | 512 |
final SymbolTable stable = parser.getSymbolTable(); |
513 |
final String extensionPrefixes = getAttribute("extension-element-prefixes"); |
|
514 |
extensionURI(extensionPrefixes, stable); |
|
515 |
} |
|
516 |
||
517 |
/** |
|
518 |
* Parse the version and uri fields of the stylesheet and add an |
|
519 |
* entry to the symbol table mapping the name <tt>__stylesheet_</tt> |
|
520 |
* to an instance of this class. |
|
521 |
*/ |
|
522 |
public void parseContents(Parser parser) { |
|
523 |
final SymbolTable stable = parser.getSymbolTable(); |
|
524 |
||
525 |
/* |
|
526 |
// Make sure the XSL version set in this stylesheet |
|
527 |
if ((_version == null) || (_version.equals(EMPTYSTRING))) { |
|
528 |
reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR,"version"); |
|
529 |
} |
|
530 |
// Verify that the version is 1.0 and nothing else |
|
531 |
else if (!_version.equals("1.0")) { |
|
532 |
reportError(this, parser, ErrorMsg.XSL_VERSION_ERR, _version); |
|
533 |
} |
|
534 |
*/ |
|
535 |
||
536 |
// Add the implicit mapping of 'xml' to the XML namespace URI |
|
537 |
addPrefixMapping("xml", "http://www.w3.org/XML/1998/namespace"); |
|
538 |
||
539 |
// Report and error if more than one stylesheet defined |
|
540 |
final Stylesheet sheet = stable.addStylesheet(_name, this); |
|
541 |
if (sheet != null) { |
|
542 |
// Error: more that one stylesheet defined |
|
543 |
ErrorMsg err = new ErrorMsg(ErrorMsg.MULTIPLE_STYLESHEET_ERR,this); |
|
544 |
parser.reportError(Constants.ERROR, err); |
|
545 |
} |
|
546 |
||
547 |
// If this is a simplified stylesheet we must create a template that |
|
548 |
// grabs the root node of the input doc ( <xsl:template match="/"/> ). |
|
549 |
// This template needs the current element (the one passed to this |
|
550 |
// method) as its only child, so the Template class has a special |
|
551 |
// method that handles this (parseSimplified()). |
|
552 |
if (_simplified) { |
|
553 |
stable.excludeURI(XSLT_URI); |
|
554 |
Template template = new Template(); |
|
555 |
template.parseSimplified(this, parser); |
|
556 |
} |
|
557 |
// Parse the children of this node |
|
558 |
else { |
|
559 |
parseOwnChildren(parser); |
|
560 |
} |
|
561 |
} |
|
562 |
||
563 |
/** |
|
564 |
* Parse all direct children of the <xsl:stylesheet/> element. |
|
565 |
*/ |
|
566 |
public final void parseOwnChildren(Parser parser) { |
|
12458 | 567 |
final SymbolTable stable = parser.getSymbolTable(); |
568 |
final String excludePrefixes = getAttribute("exclude-result-prefixes"); |
|
569 |
final String extensionPrefixes = getAttribute("extension-element-prefixes"); |
|
570 |
||
571 |
// Exclude XSLT uri |
|
572 |
stable.pushExcludedNamespacesContext(); |
|
573 |
stable.excludeURI(Constants.XSLT_URI); |
|
574 |
stable.excludeNamespaces(excludePrefixes); |
|
575 |
stable.excludeNamespaces(extensionPrefixes); |
|
576 |
||
33349 | 577 |
final List<SyntaxTreeNode> contents = getContents(); |
6 | 578 |
final int count = contents.size(); |
579 |
||
580 |
// We have to scan the stylesheet element's top-level elements for |
|
581 |
// variables and/or parameters before we parse the other elements |
|
582 |
for (int i = 0; i < count; i++) { |
|
33349 | 583 |
SyntaxTreeNode child = contents.get(i); |
6 | 584 |
if ((child instanceof VariableBase) || |
585 |
(child instanceof NamespaceAlias)) { |
|
586 |
parser.getSymbolTable().setCurrentNode(child); |
|
587 |
child.parseContents(parser); |
|
588 |
} |
|
589 |
} |
|
590 |
||
591 |
// Now go through all the other top-level elements... |
|
592 |
for (int i = 0; i < count; i++) { |
|
33349 | 593 |
SyntaxTreeNode child = contents.get(i); |
6 | 594 |
if (!(child instanceof VariableBase) && |
595 |
!(child instanceof NamespaceAlias)) { |
|
596 |
parser.getSymbolTable().setCurrentNode(child); |
|
597 |
child.parseContents(parser); |
|
598 |
} |
|
599 |
||
600 |
// All template code should be compiled as methods if the |
|
601 |
// <xsl:apply-imports/> element was ever used in this stylesheet |
|
602 |
if (!_templateInlining && (child instanceof Template)) { |
|
603 |
Template template = (Template)child; |
|
604 |
String name = "template$dot$" + template.getPosition(); |
|
605 |
template.setName(parser.getQName(name)); |
|
606 |
} |
|
607 |
} |
|
12458 | 608 |
|
609 |
stable.popExcludedNamespacesContext(); |
|
6 | 610 |
} |
611 |
||
612 |
public void processModes() { |
|
613 |
if (_defaultMode == null) |
|
614 |
_defaultMode = new Mode(null, this, Constants.EMPTYSTRING); |
|
615 |
_defaultMode.processPatterns(_keys); |
|
33349 | 616 |
_modes.values().stream().forEach((mode) -> { |
6 | 617 |
mode.processPatterns(_keys); |
33349 | 618 |
}); |
6 | 619 |
} |
620 |
||
621 |
private void compileModes(ClassGenerator classGen) { |
|
622 |
_defaultMode.compileApplyTemplates(classGen); |
|
33349 | 623 |
_modes.values().stream().forEach((mode) -> { |
6 | 624 |
mode.compileApplyTemplates(classGen); |
33349 | 625 |
}); |
6 | 626 |
} |
627 |
||
628 |
public Mode getMode(QName modeName) { |
|
629 |
if (modeName == null) { |
|
630 |
if (_defaultMode == null) { |
|
631 |
_defaultMode = new Mode(null, this, Constants.EMPTYSTRING); |
|
632 |
} |
|
633 |
return _defaultMode; |
|
634 |
} |
|
635 |
else { |
|
33349 | 636 |
Mode mode = _modes.get(modeName.getStringRep()); |
6 | 637 |
if (mode == null) { |
638 |
final String suffix = Integer.toString(_nextModeSerial++); |
|
33349 | 639 |
_modes.put(modeName.getStringRep(), mode = new Mode(modeName, this, suffix)); |
6 | 640 |
} |
641 |
return mode; |
|
642 |
} |
|
643 |
} |
|
644 |
||
645 |
/** |
|
646 |
* Type check all the children of this node. |
|
647 |
*/ |
|
648 |
public Type typeCheck(SymbolTable stable) throws TypeCheckError { |
|
649 |
final int count = _globals.size(); |
|
650 |
for (int i = 0; i < count; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
651 |
final VariableBase var = _globals.get(i); |
6 | 652 |
var.typeCheck(stable); |
653 |
} |
|
654 |
return typeCheckContents(stable); |
|
655 |
} |
|
656 |
||
657 |
/** |
|
658 |
* Translate the stylesheet into JVM bytecodes. |
|
659 |
*/ |
|
660 |
public void translate(ClassGenerator classGen, MethodGenerator methodGen) { |
|
661 |
translate(); |
|
662 |
} |
|
663 |
||
664 |
private void addDOMField(ClassGenerator classGen) { |
|
665 |
final FieldGen fgen = new FieldGen(ACC_PUBLIC, |
|
666 |
Util.getJCRefType(DOM_INTF_SIG), |
|
667 |
DOM_FIELD, |
|
668 |
classGen.getConstantPool()); |
|
669 |
classGen.addField(fgen.getField()); |
|
670 |
} |
|
671 |
||
672 |
/** |
|
673 |
* Add a static field |
|
674 |
*/ |
|
675 |
private void addStaticField(ClassGenerator classGen, String type, |
|
676 |
String name) |
|
677 |
{ |
|
678 |
final FieldGen fgen = new FieldGen(ACC_PROTECTED|ACC_STATIC, |
|
679 |
Util.getJCRefType(type), |
|
680 |
name, |
|
681 |
classGen.getConstantPool()); |
|
682 |
classGen.addField(fgen.getField()); |
|
683 |
||
684 |
} |
|
685 |
||
686 |
/** |
|
687 |
* Translate the stylesheet into JVM bytecodes. |
|
688 |
*/ |
|
689 |
public void translate() { |
|
690 |
_className = getXSLTC().getClassName(); |
|
691 |
||
692 |
// Define a new class by extending TRANSLET_CLASS |
|
693 |
final ClassGenerator classGen = |
|
694 |
new ClassGenerator(_className, |
|
695 |
TRANSLET_CLASS, |
|
696 |
Constants.EMPTYSTRING, |
|
697 |
ACC_PUBLIC | ACC_SUPER, |
|
698 |
null, this); |
|
699 |
||
700 |
addDOMField(classGen); |
|
701 |
||
702 |
// Compile transform() to initialize parameters, globals & output |
|
703 |
// and run the transformation |
|
704 |
compileTransform(classGen); |
|
705 |
||
706 |
// Translate all non-template elements and filter out all templates |
|
33349 | 707 |
final Iterator<SyntaxTreeNode> elements = elements(); |
708 |
while (elements.hasNext()) { |
|
709 |
SyntaxTreeNode element = elements.next(); |
|
6 | 710 |
// xsl:template |
711 |
if (element instanceof Template) { |
|
712 |
// Separate templates by modes |
|
713 |
final Template template = (Template)element; |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
714 |
//_templates.add(template); |
6 | 715 |
getMode(template.getModeName()).addTemplate(template); |
716 |
} |
|
717 |
// xsl:attribute-set |
|
718 |
else if (element instanceof AttributeSet) { |
|
719 |
((AttributeSet)element).translate(classGen, null); |
|
720 |
} |
|
721 |
else if (element instanceof Output) { |
|
722 |
// save the element for later to pass to compileConstructor |
|
723 |
Output output = (Output)element; |
|
724 |
if (output.enabled()) _lastOutputElement = output; |
|
725 |
} |
|
726 |
else { |
|
727 |
// Global variables and parameters are handled elsewhere. |
|
728 |
// Other top-level non-template elements are ignored. Literal |
|
729 |
// elements outside of templates will never be output. |
|
730 |
} |
|
731 |
} |
|
732 |
||
733 |
checkOutputMethod(); |
|
734 |
processModes(); |
|
735 |
compileModes(classGen); |
|
736 |
compileStaticInitializer(classGen); |
|
737 |
compileConstructor(classGen, _lastOutputElement); |
|
738 |
||
739 |
if (!getParser().errorsFound()) { |
|
740 |
getXSLTC().dumpClass(classGen.getJavaClass()); |
|
741 |
} |
|
742 |
} |
|
743 |
||
744 |
/** |
|
745 |
* Compile the namesArray, urisArray and typesArray into |
|
746 |
* the static initializer. They are read-only from the |
|
747 |
* translet. All translet instances can share a single |
|
748 |
* copy of this informtion. |
|
749 |
*/ |
|
750 |
private void compileStaticInitializer(ClassGenerator classGen) { |
|
751 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
752 |
final InstructionList il = new InstructionList(); |
|
753 |
||
754 |
final MethodGenerator staticConst = |
|
755 |
new MethodGenerator(ACC_PUBLIC|ACC_STATIC, |
|
756 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
757 |
null, null, "<clinit>", |
|
758 |
_className, il, cpg); |
|
759 |
||
760 |
addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD); |
|
761 |
addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD); |
|
762 |
addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD); |
|
763 |
addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD); |
|
764 |
// Create fields of type char[] that will contain literal text from |
|
765 |
// the stylesheet. |
|
766 |
final int charDataFieldCount = getXSLTC().getCharacterDataCount(); |
|
767 |
for (int i = 0; i < charDataFieldCount; i++) { |
|
768 |
addStaticField(classGen, STATIC_CHAR_DATA_FIELD_SIG, |
|
769 |
STATIC_CHAR_DATA_FIELD+i); |
|
770 |
} |
|
771 |
||
772 |
// Put the names array into the translet - used for dom/translet mapping |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
773 |
final List<String> namesIndex = getXSLTC().getNamesIndex(); |
6 | 774 |
int size = namesIndex.size(); |
775 |
String[] namesArray = new String[size]; |
|
776 |
String[] urisArray = new String[size]; |
|
777 |
int[] typesArray = new int[size]; |
|
778 |
||
779 |
int index; |
|
780 |
for (int i = 0; i < size; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
781 |
String encodedName = namesIndex.get(i); |
6 | 782 |
if ((index = encodedName.lastIndexOf(':')) > -1) { |
783 |
urisArray[i] = encodedName.substring(0, index); |
|
784 |
} |
|
785 |
||
786 |
index = index + 1; |
|
787 |
if (encodedName.charAt(index) == '@') { |
|
788 |
typesArray[i] = DTM.ATTRIBUTE_NODE; |
|
789 |
index++; |
|
790 |
} else if (encodedName.charAt(index) == '?') { |
|
791 |
typesArray[i] = DTM.NAMESPACE_NODE; |
|
792 |
index++; |
|
793 |
} else { |
|
794 |
typesArray[i] = DTM.ELEMENT_NODE; |
|
795 |
} |
|
796 |
||
797 |
if (index == 0) { |
|
798 |
namesArray[i] = encodedName; |
|
799 |
} |
|
800 |
else { |
|
801 |
namesArray[i] = encodedName.substring(index); |
|
802 |
} |
|
803 |
} |
|
804 |
||
12458 | 805 |
staticConst.markChunkStart(); |
6 | 806 |
il.append(new PUSH(cpg, size)); |
807 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
12458 | 808 |
int namesArrayRef = cpg.addFieldref(_className, |
809 |
STATIC_NAMES_ARRAY_FIELD, |
|
810 |
NAMES_INDEX_SIG); |
|
811 |
il.append(new PUTSTATIC(namesArrayRef)); |
|
812 |
staticConst.markChunkEnd(); |
|
6 | 813 |
|
814 |
for (int i = 0; i < size; i++) { |
|
815 |
final String name = namesArray[i]; |
|
12458 | 816 |
staticConst.markChunkStart(); |
817 |
il.append(new GETSTATIC(namesArrayRef)); |
|
6 | 818 |
il.append(new PUSH(cpg, i)); |
819 |
il.append(new PUSH(cpg, name)); |
|
820 |
il.append(AASTORE); |
|
12458 | 821 |
staticConst.markChunkEnd(); |
6 | 822 |
} |
823 |
||
12458 | 824 |
staticConst.markChunkStart(); |
6 | 825 |
il.append(new PUSH(cpg, size)); |
826 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
12458 | 827 |
int urisArrayRef = cpg.addFieldref(_className, |
828 |
STATIC_URIS_ARRAY_FIELD, |
|
829 |
URIS_INDEX_SIG); |
|
830 |
il.append(new PUTSTATIC(urisArrayRef)); |
|
831 |
staticConst.markChunkEnd(); |
|
6 | 832 |
|
833 |
for (int i = 0; i < size; i++) { |
|
834 |
final String uri = urisArray[i]; |
|
12458 | 835 |
staticConst.markChunkStart(); |
836 |
il.append(new GETSTATIC(urisArrayRef)); |
|
6 | 837 |
il.append(new PUSH(cpg, i)); |
838 |
il.append(new PUSH(cpg, uri)); |
|
839 |
il.append(AASTORE); |
|
12458 | 840 |
staticConst.markChunkEnd(); |
6 | 841 |
} |
842 |
||
12458 | 843 |
staticConst.markChunkStart(); |
6 | 844 |
il.append(new PUSH(cpg, size)); |
845 |
il.append(new NEWARRAY(BasicType.INT)); |
|
12458 | 846 |
int typesArrayRef = cpg.addFieldref(_className, |
847 |
STATIC_TYPES_ARRAY_FIELD, |
|
848 |
TYPES_INDEX_SIG); |
|
849 |
il.append(new PUTSTATIC(typesArrayRef)); |
|
850 |
staticConst.markChunkEnd(); |
|
6 | 851 |
|
852 |
for (int i = 0; i < size; i++) { |
|
853 |
final int nodeType = typesArray[i]; |
|
12458 | 854 |
staticConst.markChunkStart(); |
855 |
il.append(new GETSTATIC(typesArrayRef)); |
|
6 | 856 |
il.append(new PUSH(cpg, i)); |
857 |
il.append(new PUSH(cpg, nodeType)); |
|
858 |
il.append(IASTORE); |
|
859 |
} |
|
860 |
||
861 |
// Put the namespace names array into the translet |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
862 |
final List<String> namespaces = getXSLTC().getNamespaceIndex(); |
12458 | 863 |
staticConst.markChunkStart(); |
6 | 864 |
il.append(new PUSH(cpg, namespaces.size())); |
865 |
il.append(new ANEWARRAY(cpg.addClass(STRING))); |
|
12458 | 866 |
int namespaceArrayRef = cpg.addFieldref(_className, |
867 |
STATIC_NAMESPACE_ARRAY_FIELD, |
|
868 |
NAMESPACE_INDEX_SIG); |
|
869 |
il.append(new PUTSTATIC(namespaceArrayRef)); |
|
870 |
staticConst.markChunkEnd(); |
|
6 | 871 |
|
872 |
for (int i = 0; i < namespaces.size(); i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
873 |
final String ns = namespaces.get(i); |
12458 | 874 |
staticConst.markChunkStart(); |
875 |
il.append(new GETSTATIC(namespaceArrayRef)); |
|
6 | 876 |
il.append(new PUSH(cpg, i)); |
877 |
il.append(new PUSH(cpg, ns)); |
|
878 |
il.append(AASTORE); |
|
12458 | 879 |
staticConst.markChunkEnd(); |
6 | 880 |
} |
881 |
||
882 |
// Grab all the literal text in the stylesheet and put it in a char[] |
|
883 |
final int charDataCount = getXSLTC().getCharacterDataCount(); |
|
884 |
final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C"); |
|
885 |
for (int i = 0; i < charDataCount; i++) { |
|
12458 | 886 |
staticConst.markChunkStart(); |
6 | 887 |
il.append(new PUSH(cpg, getXSLTC().getCharacterData(i))); |
888 |
il.append(new INVOKEVIRTUAL(toCharArray)); |
|
889 |
il.append(new PUTSTATIC(cpg.addFieldref(_className, |
|
890 |
STATIC_CHAR_DATA_FIELD+i, |
|
891 |
STATIC_CHAR_DATA_FIELD_SIG))); |
|
12458 | 892 |
staticConst.markChunkEnd(); |
6 | 893 |
} |
894 |
||
895 |
il.append(RETURN); |
|
896 |
||
12458 | 897 |
classGen.addMethod(staticConst); |
6 | 898 |
|
899 |
} |
|
900 |
||
901 |
/** |
|
902 |
* Compile the translet's constructor |
|
903 |
*/ |
|
904 |
private void compileConstructor(ClassGenerator classGen, Output output) { |
|
905 |
||
906 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
907 |
final InstructionList il = new InstructionList(); |
|
908 |
||
909 |
final MethodGenerator constructor = |
|
910 |
new MethodGenerator(ACC_PUBLIC, |
|
911 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
912 |
null, null, "<init>", |
|
913 |
_className, il, cpg); |
|
914 |
||
915 |
// Call the constructor in the AbstractTranslet superclass |
|
916 |
il.append(classGen.loadTranslet()); |
|
917 |
il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS, |
|
918 |
"<init>", "()V"))); |
|
919 |
||
12458 | 920 |
constructor.markChunkStart(); |
6 | 921 |
il.append(classGen.loadTranslet()); |
922 |
il.append(new GETSTATIC(cpg.addFieldref(_className, |
|
923 |
STATIC_NAMES_ARRAY_FIELD, |
|
924 |
NAMES_INDEX_SIG))); |
|
925 |
il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, |
|
926 |
NAMES_INDEX, |
|
927 |
NAMES_INDEX_SIG))); |
|
928 |
||
929 |
il.append(classGen.loadTranslet()); |
|
930 |
il.append(new GETSTATIC(cpg.addFieldref(_className, |
|
931 |
STATIC_URIS_ARRAY_FIELD, |
|
932 |
URIS_INDEX_SIG))); |
|
933 |
il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, |
|
934 |
URIS_INDEX, |
|
935 |
URIS_INDEX_SIG))); |
|
12458 | 936 |
constructor.markChunkEnd(); |
6 | 937 |
|
12458 | 938 |
constructor.markChunkStart(); |
6 | 939 |
il.append(classGen.loadTranslet()); |
940 |
il.append(new GETSTATIC(cpg.addFieldref(_className, |
|
941 |
STATIC_TYPES_ARRAY_FIELD, |
|
942 |
TYPES_INDEX_SIG))); |
|
943 |
il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, |
|
944 |
TYPES_INDEX, |
|
945 |
TYPES_INDEX_SIG))); |
|
12458 | 946 |
constructor.markChunkEnd(); |
6 | 947 |
|
12458 | 948 |
constructor.markChunkStart(); |
6 | 949 |
il.append(classGen.loadTranslet()); |
950 |
il.append(new GETSTATIC(cpg.addFieldref(_className, |
|
951 |
STATIC_NAMESPACE_ARRAY_FIELD, |
|
952 |
NAMESPACE_INDEX_SIG))); |
|
953 |
il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, |
|
954 |
NAMESPACE_INDEX, |
|
955 |
NAMESPACE_INDEX_SIG))); |
|
12458 | 956 |
constructor.markChunkEnd(); |
6 | 957 |
|
12458 | 958 |
constructor.markChunkStart(); |
6 | 959 |
il.append(classGen.loadTranslet()); |
960 |
il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION)); |
|
961 |
il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, |
|
962 |
TRANSLET_VERSION_INDEX, |
|
963 |
TRANSLET_VERSION_INDEX_SIG))); |
|
12458 | 964 |
constructor.markChunkEnd(); |
6 | 965 |
|
966 |
if (_hasIdCall) { |
|
12458 | 967 |
constructor.markChunkStart(); |
6 | 968 |
il.append(classGen.loadTranslet()); |
969 |
il.append(new PUSH(cpg, Boolean.TRUE)); |
|
970 |
il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS, |
|
971 |
HASIDCALL_INDEX, |
|
972 |
HASIDCALL_INDEX_SIG))); |
|
12458 | 973 |
constructor.markChunkEnd(); |
6 | 974 |
} |
975 |
||
976 |
// Compile in code to set the output configuration from <xsl:output> |
|
977 |
if (output != null) { |
|
978 |
// Set all the output settings files in the translet |
|
12458 | 979 |
constructor.markChunkStart(); |
6 | 980 |
output.translate(classGen, constructor); |
12458 | 981 |
constructor.markChunkEnd(); |
6 | 982 |
} |
983 |
||
984 |
// Compile default decimal formatting symbols. |
|
985 |
// This is an implicit, nameless xsl:decimal-format top-level element. |
|
12458 | 986 |
if (_numberFormattingUsed) { |
987 |
constructor.markChunkStart(); |
|
6 | 988 |
DecimalFormatting.translateDefaultDFS(classGen, constructor); |
12458 | 989 |
constructor.markChunkEnd(); |
990 |
} |
|
6 | 991 |
|
992 |
il.append(RETURN); |
|
993 |
||
12458 | 994 |
classGen.addMethod(constructor); |
6 | 995 |
} |
996 |
||
997 |
/** |
|
998 |
* Compile a topLevel() method into the output class. This method is |
|
999 |
* called from transform() to handle all non-template top-level elements. |
|
1000 |
* Returns the signature of the topLevel() method. |
|
1001 |
* |
|
1002 |
* Global variables/params and keys are first sorted to resolve |
|
1003 |
* dependencies between them. The XSLT 1.0 spec does not allow a key |
|
1004 |
* to depend on a variable. However, for compatibility with Xalan |
|
1005 |
* interpretive, that type of dependency is allowed. Note also that |
|
1006 |
* the buildKeys() method is still generated as it is used by the |
|
1007 |
* LoadDocument class, but it no longer called from transform(). |
|
1008 |
*/ |
|
1009 |
private String compileTopLevel(ClassGenerator classGen) { |
|
1010 |
||
1011 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
1012 |
||
1013 |
final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = { |
|
1014 |
Util.getJCRefType(DOM_INTF_SIG), |
|
1015 |
Util.getJCRefType(NODE_ITERATOR_SIG), |
|
1016 |
Util.getJCRefType(TRANSLET_OUTPUT_SIG) |
|
1017 |
}; |
|
1018 |
||
1019 |
final String[] argNames = { |
|
1020 |
DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME |
|
1021 |
}; |
|
1022 |
||
1023 |
final InstructionList il = new InstructionList(); |
|
1024 |
||
1025 |
final MethodGenerator toplevel = |
|
1026 |
new MethodGenerator(ACC_PUBLIC, |
|
1027 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
1028 |
argTypes, argNames, |
|
1029 |
"topLevel", _className, il, |
|
1030 |
classGen.getConstantPool()); |
|
1031 |
||
1032 |
toplevel.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); |
|
1033 |
||
12458 | 1034 |
// Define and initialize 'current' variable with the root node |
1035 |
final LocalVariableGen current = |
|
1036 |
toplevel.addLocalVariable("current", |
|
1037 |
com.sun.org.apache.bcel.internal.generic.Type.INT, |
|
1038 |
null, null); |
|
1039 |
||
6 | 1040 |
final int setFilter = cpg.addInterfaceMethodref(DOM_INTF, |
1041 |
"setFilter", |
|
1042 |
"(Lcom/sun/org/apache/xalan/internal/xsltc/StripFilter;)V"); |
|
1043 |
||
1044 |
final int gitr = cpg.addInterfaceMethodref(DOM_INTF, |
|
12458 | 1045 |
"getIterator", |
1046 |
"()"+NODE_ITERATOR_SIG); |
|
6 | 1047 |
il.append(toplevel.loadDOM()); |
1048 |
il.append(new INVOKEINTERFACE(gitr, 1)); |
|
12458 | 1049 |
il.append(toplevel.nextNode()); |
1050 |
current.setStart(il.append(new ISTORE(current.getIndex()))); |
|
6 | 1051 |
|
1052 |
// Create a new list containing variables/params + keys |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1053 |
List<SyntaxTreeNode> varDepElements = new ArrayList<>(_globals); |
33349 | 1054 |
Iterator<SyntaxTreeNode> elements = elements(); |
1055 |
while (elements.hasNext()) { |
|
1056 |
SyntaxTreeNode element = elements.next(); |
|
6 | 1057 |
if (element instanceof Key) { |
1058 |
varDepElements.add(element); |
|
1059 |
} |
|
1060 |
} |
|
1061 |
||
1062 |
// Determine a partial order for the variables/params and keys |
|
1063 |
varDepElements = resolveDependencies(varDepElements); |
|
1064 |
||
1065 |
// Translate vars/params and keys in the right order |
|
1066 |
final int count = varDepElements.size(); |
|
1067 |
for (int i = 0; i < count; i++) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1068 |
final TopLevelElement tle = (TopLevelElement) varDepElements.get(i); |
6 | 1069 |
tle.translate(classGen, toplevel); |
1070 |
if (tle instanceof Key) { |
|
1071 |
final Key key = (Key) tle; |
|
1072 |
_keys.put(key.getName(), key); |
|
1073 |
} |
|
1074 |
} |
|
1075 |
||
1076 |
// Compile code for other top-level elements |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1077 |
List<Whitespace.WhitespaceRule> whitespaceRules = new ArrayList<>(); |
6 | 1078 |
elements = elements(); |
33349 | 1079 |
while (elements.hasNext()) { |
1080 |
SyntaxTreeNode element = elements.next(); |
|
6 | 1081 |
// xsl:decimal-format |
1082 |
if (element instanceof DecimalFormatting) { |
|
1083 |
((DecimalFormatting)element).translate(classGen,toplevel); |
|
1084 |
} |
|
1085 |
// xsl:strip/preserve-space |
|
1086 |
else if (element instanceof Whitespace) { |
|
1087 |
whitespaceRules.addAll(((Whitespace)element).getRules()); |
|
1088 |
} |
|
1089 |
} |
|
1090 |
||
1091 |
// Translate all whitespace strip/preserve rules |
|
1092 |
if (whitespaceRules.size() > 0) { |
|
1093 |
Whitespace.translateRules(whitespaceRules,classGen); |
|
1094 |
} |
|
1095 |
||
1096 |
if (classGen.containsMethod(STRIP_SPACE, STRIP_SPACE_PARAMS) != null) { |
|
1097 |
il.append(toplevel.loadDOM()); |
|
1098 |
il.append(classGen.loadTranslet()); |
|
1099 |
il.append(new INVOKEINTERFACE(setFilter, 2)); |
|
1100 |
} |
|
1101 |
||
1102 |
il.append(RETURN); |
|
1103 |
||
1104 |
// Compute max locals + stack and add method to class |
|
12458 | 1105 |
classGen.addMethod(toplevel); |
6 | 1106 |
|
1107 |
return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+")V"); |
|
1108 |
} |
|
1109 |
||
1110 |
/** |
|
1111 |
* This method returns a vector with variables/params and keys in the |
|
1112 |
* order in which they are to be compiled for initialization. The order |
|
1113 |
* is determined by analyzing the dependencies between them. The XSLT 1.0 |
|
1114 |
* spec does not allow a key to depend on a variable. However, for |
|
1115 |
* compatibility with Xalan interpretive, that type of dependency is |
|
1116 |
* allowed and, therefore, consider to determine the partial order. |
|
1117 |
*/ |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1118 |
private List<SyntaxTreeNode> resolveDependencies(List<SyntaxTreeNode> input) { |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1119 |
List<SyntaxTreeNode> result = new ArrayList<>(); |
6 | 1120 |
while (input.size() > 0) { |
1121 |
boolean changed = false; |
|
1122 |
for (int i = 0; i < input.size(); ) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1123 |
final TopLevelElement vde = (TopLevelElement) input.get(i); |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1124 |
final List<SyntaxTreeNode> dep = vde.getDependencies(); |
6 | 1125 |
if (dep == null || result.containsAll(dep)) { |
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1126 |
result.add(vde); |
6 | 1127 |
input.remove(i); |
1128 |
changed = true; |
|
1129 |
} |
|
1130 |
else { |
|
1131 |
i++; |
|
1132 |
} |
|
1133 |
} |
|
1134 |
||
1135 |
// If nothing was changed in this pass then we have a circular ref |
|
1136 |
if (!changed) { |
|
1137 |
ErrorMsg err = new ErrorMsg(ErrorMsg.CIRCULAR_VARIABLE_ERR, |
|
1138 |
input.toString(), this); |
|
1139 |
getParser().reportError(Constants.ERROR, err); |
|
1140 |
return(result); |
|
1141 |
} |
|
1142 |
} |
|
1143 |
||
1144 |
return result; |
|
1145 |
} |
|
1146 |
||
1147 |
/** |
|
1148 |
* Compile a buildKeys() method into the output class. Note that keys |
|
1149 |
* for the input document are created in topLevel(), not in this method. |
|
1150 |
* However, we still need this method to create keys for documents loaded |
|
1151 |
* via the XPath document() function. |
|
1152 |
*/ |
|
1153 |
private String compileBuildKeys(ClassGenerator classGen) { |
|
1154 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
1155 |
||
1156 |
final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = { |
|
1157 |
Util.getJCRefType(DOM_INTF_SIG), |
|
1158 |
Util.getJCRefType(NODE_ITERATOR_SIG), |
|
1159 |
Util.getJCRefType(TRANSLET_OUTPUT_SIG), |
|
1160 |
com.sun.org.apache.bcel.internal.generic.Type.INT |
|
1161 |
}; |
|
1162 |
||
1163 |
final String[] argNames = { |
|
1164 |
DOCUMENT_PNAME, ITERATOR_PNAME, TRANSLET_OUTPUT_PNAME, "current" |
|
1165 |
}; |
|
1166 |
||
1167 |
final InstructionList il = new InstructionList(); |
|
1168 |
||
1169 |
final MethodGenerator buildKeys = |
|
1170 |
new MethodGenerator(ACC_PUBLIC, |
|
1171 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
1172 |
argTypes, argNames, |
|
1173 |
"buildKeys", _className, il, |
|
1174 |
classGen.getConstantPool()); |
|
1175 |
||
1176 |
buildKeys.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); |
|
1177 |
||
33349 | 1178 |
final Iterator<SyntaxTreeNode> elements = elements(); |
1179 |
while (elements.hasNext()) { |
|
6 | 1180 |
// xsl:key |
33349 | 1181 |
final SyntaxTreeNode element = elements.next(); |
6 | 1182 |
if (element instanceof Key) { |
1183 |
final Key key = (Key)element; |
|
1184 |
key.translate(classGen, buildKeys); |
|
1185 |
_keys.put(key.getName(),key); |
|
1186 |
} |
|
1187 |
} |
|
1188 |
||
1189 |
il.append(RETURN); |
|
1190 |
||
1191 |
// Compute max locals + stack and add method to class |
|
1192 |
buildKeys.stripAttributes(true); |
|
1193 |
buildKeys.setMaxLocals(); |
|
1194 |
buildKeys.setMaxStack(); |
|
1195 |
buildKeys.removeNOPs(); |
|
1196 |
||
1197 |
classGen.addMethod(buildKeys.getMethod()); |
|
1198 |
||
1199 |
return("("+DOM_INTF_SIG+NODE_ITERATOR_SIG+TRANSLET_OUTPUT_SIG+"I)V"); |
|
1200 |
} |
|
1201 |
||
1202 |
/** |
|
1203 |
* Compile transform() into the output class. This method is used to |
|
1204 |
* initialize global variables and global parameters. The current node |
|
1205 |
* is set to be the document's root node. |
|
1206 |
*/ |
|
1207 |
private void compileTransform(ClassGenerator classGen) { |
|
1208 |
final ConstantPoolGen cpg = classGen.getConstantPool(); |
|
1209 |
||
1210 |
/* |
|
1211 |
* Define the the method transform with the following signature: |
|
1212 |
* void transform(DOM, NodeIterator, HandlerBase) |
|
1213 |
*/ |
|
1214 |
final com.sun.org.apache.bcel.internal.generic.Type[] argTypes = |
|
1215 |
new com.sun.org.apache.bcel.internal.generic.Type[3]; |
|
1216 |
argTypes[0] = Util.getJCRefType(DOM_INTF_SIG); |
|
1217 |
argTypes[1] = Util.getJCRefType(NODE_ITERATOR_SIG); |
|
1218 |
argTypes[2] = Util.getJCRefType(TRANSLET_OUTPUT_SIG); |
|
1219 |
||
1220 |
final String[] argNames = new String[3]; |
|
1221 |
argNames[0] = DOCUMENT_PNAME; |
|
1222 |
argNames[1] = ITERATOR_PNAME; |
|
1223 |
argNames[2] = TRANSLET_OUTPUT_PNAME; |
|
1224 |
||
1225 |
final InstructionList il = new InstructionList(); |
|
1226 |
final MethodGenerator transf = |
|
1227 |
new MethodGenerator(ACC_PUBLIC, |
|
1228 |
com.sun.org.apache.bcel.internal.generic.Type.VOID, |
|
1229 |
argTypes, argNames, |
|
1230 |
"transform", |
|
1231 |
_className, |
|
1232 |
il, |
|
1233 |
classGen.getConstantPool()); |
|
1234 |
transf.addException("com.sun.org.apache.xalan.internal.xsltc.TransletException"); |
|
1235 |
||
41623
d32a755d06d1
8167179: Make XSL generated namespace prefixes local to transformation process
aefimov
parents:
33349
diff
changeset
|
1236 |
// call resetPrefixIndex at the beginning of transform |
d32a755d06d1
8167179: Make XSL generated namespace prefixes local to transformation process
aefimov
parents:
33349
diff
changeset
|
1237 |
final int check = cpg.addMethodref(BASIS_LIBRARY_CLASS, "resetPrefixIndex", "()V"); |
d32a755d06d1
8167179: Make XSL generated namespace prefixes local to transformation process
aefimov
parents:
33349
diff
changeset
|
1238 |
il.append(new INVOKESTATIC(check)); |
d32a755d06d1
8167179: Make XSL generated namespace prefixes local to transformation process
aefimov
parents:
33349
diff
changeset
|
1239 |
|
6 | 1240 |
// Define and initialize current with the root node |
1241 |
final LocalVariableGen current = |
|
1242 |
transf.addLocalVariable("current", |
|
1243 |
com.sun.org.apache.bcel.internal.generic.Type.INT, |
|
12458 | 1244 |
null, null); |
6 | 1245 |
final String applyTemplatesSig = classGen.getApplyTemplatesSig(); |
1246 |
final int applyTemplates = cpg.addMethodref(getClassName(), |
|
1247 |
"applyTemplates", |
|
1248 |
applyTemplatesSig); |
|
1249 |
final int domField = cpg.addFieldref(getClassName(), |
|
1250 |
DOM_FIELD, |
|
1251 |
DOM_INTF_SIG); |
|
1252 |
||
1253 |
// push translet for PUTFIELD |
|
1254 |
il.append(classGen.loadTranslet()); |
|
1255 |
// prepare appropriate DOM implementation |
|
1256 |
||
1257 |
if (isMultiDocument()) { |
|
1258 |
il.append(new NEW(cpg.addClass(MULTI_DOM_CLASS))); |
|
1259 |
il.append(DUP); |
|
1260 |
} |
|
1261 |
||
1262 |
il.append(classGen.loadTranslet()); |
|
1263 |
il.append(transf.loadDOM()); |
|
1264 |
il.append(new INVOKEVIRTUAL(cpg.addMethodref(TRANSLET_CLASS, |
|
1265 |
"makeDOMAdapter", |
|
1266 |
"("+DOM_INTF_SIG+")"+ |
|
1267 |
DOM_ADAPTER_SIG))); |
|
1268 |
// DOMAdapter is on the stack |
|
1269 |
||
1270 |
if (isMultiDocument()) { |
|
1271 |
final int init = cpg.addMethodref(MULTI_DOM_CLASS, |
|
1272 |
"<init>", |
|
1273 |
"("+DOM_INTF_SIG+")V"); |
|
1274 |
il.append(new INVOKESPECIAL(init)); |
|
1275 |
// MultiDOM is on the stack |
|
1276 |
} |
|
1277 |
||
1278 |
//store to _dom variable |
|
1279 |
il.append(new PUTFIELD(domField)); |
|
1280 |
||
12458 | 1281 |
// continue with globals initialization |
1282 |
final int gitr = cpg.addInterfaceMethodref(DOM_INTF, |
|
1283 |
"getIterator", |
|
1284 |
"()"+NODE_ITERATOR_SIG); |
|
1285 |
il.append(transf.loadDOM()); |
|
1286 |
il.append(new INVOKEINTERFACE(gitr, 1)); |
|
1287 |
il.append(transf.nextNode()); |
|
1288 |
current.setStart(il.append(new ISTORE(current.getIndex()))); |
|
1289 |
||
6 | 1290 |
// Transfer the output settings to the output post-processor |
1291 |
il.append(classGen.loadTranslet()); |
|
1292 |
il.append(transf.loadHandler()); |
|
1293 |
final int index = cpg.addMethodref(TRANSLET_CLASS, |
|
1294 |
"transferOutputSettings", |
|
1295 |
"("+OUTPUT_HANDLER_SIG+")V"); |
|
1296 |
il.append(new INVOKEVIRTUAL(index)); |
|
1297 |
||
1298 |
/* |
|
1299 |
* Compile buildKeys() method. Note that this method is not |
|
1300 |
* invoked here as keys for the input document are now created |
|
1301 |
* in topLevel(). However, this method is still needed by the |
|
1302 |
* LoadDocument class. |
|
1303 |
*/ |
|
1304 |
final String keySig = compileBuildKeys(classGen); |
|
1305 |
final int keyIdx = cpg.addMethodref(getClassName(), |
|
1306 |
"buildKeys", keySig); |
|
1307 |
||
1308 |
// Look for top-level elements that need handling |
|
33349 | 1309 |
final Iterator<SyntaxTreeNode> toplevel = elements(); |
1310 |
if (_globals.size() > 0 || toplevel.hasNext()) { |
|
6 | 1311 |
// Compile method for handling top-level elements |
1312 |
final String topLevelSig = compileTopLevel(classGen); |
|
1313 |
// Get a reference to that method |
|
1314 |
final int topLevelIdx = cpg.addMethodref(getClassName(), |
|
1315 |
"topLevel", |
|
1316 |
topLevelSig); |
|
1317 |
// Push all parameters on the stack and call topLevel() |
|
1318 |
il.append(classGen.loadTranslet()); // The 'this' pointer |
|
1319 |
il.append(classGen.loadTranslet()); |
|
1320 |
il.append(new GETFIELD(domField)); // The DOM reference |
|
1321 |
il.append(transf.loadIterator()); |
|
1322 |
il.append(transf.loadHandler()); // The output handler |
|
1323 |
il.append(new INVOKEVIRTUAL(topLevelIdx)); |
|
1324 |
} |
|
1325 |
||
1326 |
// start document |
|
1327 |
il.append(transf.loadHandler()); |
|
1328 |
il.append(transf.startDocument()); |
|
1329 |
||
1330 |
// push first arg for applyTemplates |
|
1331 |
il.append(classGen.loadTranslet()); |
|
1332 |
// push translet for GETFIELD to get DOM arg |
|
1333 |
il.append(classGen.loadTranslet()); |
|
1334 |
il.append(new GETFIELD(domField)); |
|
1335 |
// push remaining 2 args |
|
1336 |
il.append(transf.loadIterator()); |
|
1337 |
il.append(transf.loadHandler()); |
|
1338 |
il.append(new INVOKEVIRTUAL(applyTemplates)); |
|
1339 |
// endDocument |
|
1340 |
il.append(transf.loadHandler()); |
|
1341 |
il.append(transf.endDocument()); |
|
1342 |
||
1343 |
il.append(RETURN); |
|
1344 |
||
1345 |
// Compute max locals + stack and add method to class |
|
12458 | 1346 |
classGen.addMethod(transf); |
6 | 1347 |
|
1348 |
} |
|
1349 |
||
1350 |
/** |
|
1351 |
* Peephole optimization: Remove sequences of [ALOAD, POP]. |
|
1352 |
*/ |
|
1353 |
private void peepHoleOptimization(MethodGenerator methodGen) { |
|
1354 |
final String pattern = "`aload'`pop'`instruction'"; |
|
1355 |
final InstructionList il = methodGen.getInstructionList(); |
|
1356 |
final InstructionFinder find = new InstructionFinder(il); |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1357 |
for(Iterator<InstructionHandle[]> iter=find.search(pattern); iter.hasNext(); ) { |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1358 |
InstructionHandle[] match = iter.next(); |
6 | 1359 |
try { |
1360 |
il.delete(match[0], match[1]); |
|
1361 |
} |
|
1362 |
catch (TargetLostException e) { |
|
1363 |
// TODO: move target down into the list |
|
1364 |
} |
|
1365 |
} |
|
1366 |
} |
|
1367 |
||
1368 |
public int addParam(Param param) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1369 |
_globals.add(param); |
6 | 1370 |
return _globals.size() - 1; |
1371 |
} |
|
1372 |
||
1373 |
public int addVariable(Variable global) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1374 |
_globals.add(global); |
6 | 1375 |
return _globals.size() - 1; |
1376 |
} |
|
1377 |
||
1378 |
public void display(int indent) { |
|
1379 |
indent(indent); |
|
1380 |
Util.println("Stylesheet"); |
|
1381 |
displayContents(indent + IndentIncrement); |
|
1382 |
} |
|
1383 |
||
1384 |
// do we need this wrapper ????? |
|
1385 |
public String getNamespace(String prefix) { |
|
1386 |
return lookupNamespace(prefix); |
|
1387 |
} |
|
1388 |
||
1389 |
public String getClassName() { |
|
1390 |
return _className; |
|
1391 |
} |
|
1392 |
||
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1393 |
public List<Template> getTemplates() { |
6 | 1394 |
return _templates; |
1395 |
} |
|
1396 |
||
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1397 |
public List<Template> getAllValidTemplates() { |
6 | 1398 |
// Return templates if no imported/included stylesheets |
1399 |
if (_includedStylesheets == null) { |
|
1400 |
return _templates; |
|
1401 |
} |
|
1402 |
||
1403 |
// Is returned value cached? |
|
1404 |
if (_allValidTemplates == null) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1405 |
List<Template> templates = new ArrayList<>(); |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1406 |
templates.addAll(_templates); |
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1407 |
for (Stylesheet included : _includedStylesheets) { |
6 | 1408 |
templates.addAll(included.getAllValidTemplates()); |
1409 |
} |
|
1410 |
//templates.addAll(_templates); |
|
1411 |
||
1412 |
// Cache results in top-level stylesheet only |
|
1413 |
if (_parentStylesheet != null) { |
|
1414 |
return templates; |
|
1415 |
} |
|
1416 |
_allValidTemplates = templates; |
|
1417 |
} |
|
1418 |
||
1419 |
return _allValidTemplates; |
|
1420 |
} |
|
1421 |
||
1422 |
protected void addTemplate(Template template) { |
|
47359
e1a6c0168741
8181150: Fix lint warnings in JAXP repo: rawtypes and unchecked
joehw
parents:
47216
diff
changeset
|
1423 |
_templates.add(template); |
6 | 1424 |
} |
1425 |
} |