Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions xalan/src/main/java/org/apache/xalan/xsltc/compiler/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,10 @@ public interface Constants extends InstructionConstants {
= "org.apache.xalan.xsltc.dom.SingletonIterator";
public static final String MATCHING_ITERATOR
= "org.apache.xalan.xsltc.dom.MatchingIterator";
public static final String HASHMAP_CLASS = "java.util.HashMap";
public static final String HASHMAP_SIG = "Ljava/util/HashMap;";
public static final String MAP_SIG = "Ljava/util/Map;";

public static final String NODE_SIG
= "I";
public static final String GET_PARENT
Expand Down Expand Up @@ -409,6 +413,13 @@ public interface Constants extends InstructionConstants {
+ PREFIX_URIS_IDX_SIG
+ PREFIX_URIS_ARRAY_SIG
+ "Z)" + STRING_SIG;
public static final String ADD_NAMESPACE_PREFIX_REF
= "addPrefix";
public static final String ADD_NAMESPACE_PREFIX_SIG
= "(" + STRING_SIG
+ STRING_SIG
+ "Ljava/util/Map;"+
")" + STRING_SIG;

public static final String DOM_FIELD
= "_dom";
Expand All @@ -430,6 +441,7 @@ public interface Constants extends InstructionConstants {
= "_scharData";
public static final String STATIC_CHAR_DATA_FIELD_SIG
= "[C";
public static final String STATIC_NS_MAP_FIELD = "_sNamespaceMap";
public static final String FORMAT_SYMBOLS_FIELD
= "format_symbols";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -808,6 +808,7 @@ private void compileStaticInitializer(ClassGenerator classGen) {
addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD);
addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD);
addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD);
addStaticField(classGen, MAP_SIG, STATIC_NS_MAP_FIELD );
// Create fields of type char[] that will contain literal text from
// the stylesheet.
final int charDataFieldCount = getXSLTC().getCharacterDataCount();
Expand Down Expand Up @@ -927,6 +928,20 @@ private void compileStaticInitializer(ClassGenerator classGen) {
staticConst.markChunkEnd();
}

// Create the namespace -> prefix map
staticConst.markChunkStart();
il.append(new NEW(cpg.addClass(HASHMAP_CLASS)));
il.append(DUP);
final int init = cpg.addMethodref(HASHMAP_CLASS, "<init>","()V");
il.append(new INVOKESPECIAL(init));

int nsMapRef = cpg.addFieldref(_className,
STATIC_NS_MAP_FIELD,
MAP_SIG);
il.append(new PUTSTATIC(nsMapRef));
staticConst.markChunkEnd();


// Put the tree of stylesheet namespace declarations into the translet
final Vector namespaceAncestors = getXSLTC().getNSAncestorPointers();
if (namespaceAncestors != null && namespaceAncestors.size() != 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ final class XslElement extends Instruction {
private String _prefix;
private boolean _ignore = false;
private boolean _isLiteralName = true;
private boolean _isLiteralNamespace = false;
private AttributeValueTemplate _name;
private AttributeValueTemplate _namespace;

Expand Down Expand Up @@ -81,8 +82,7 @@ public void parseContents(Parser parser) {
return;
}

// Get namespace attribute
String namespace = getAttribute("namespace");
String namespace = getAttribute("namespace");

// Optimize compilation when name is known at compile time
_isLiteralName = Util.isLiteral(name);
Expand Down Expand Up @@ -141,6 +141,11 @@ public void parseContents(Parser parser) {
// name attribute contains variable parts. If there is no namespace
// attribute, the generated code needs to be prepared to look up
// any prefix in the stylesheet at run-time.
// if the namespace is literal, we can avoid generating a new
// prefix every time though
if (Util.isLiteral(namespace)) {
_isLiteralNamespace = true;
}
_namespace = (namespace == EMPTYSTRING) ? null :
new AttributeValueTemplate(namespace, parser, this);
}
Expand Down Expand Up @@ -245,13 +250,42 @@ public void translate(ClassGenerator classGen, MethodGenerator methodGen) {
// Push handler for call to endElement()
il.append(methodGen.loadHandler());

// load name value again
nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex())));

if (_namespace != null) {
_namespace.translate(classGen, methodGen);
}
else {
if (_namespace != null) {
// If the namespace is a literal, we'll want to avoid creating a new
// prefix for it
if(_isLiteralNamespace){
// we want to call to BasisLibrary.addPrefix(String qname, String namespace, Map prefixMap);
// So store the namespace in a var
LocalVariableGen namespaceValue = methodGen.addLocalVariable2(
"namespaceValue", Util.getJCRefType(STRING_SIG), null);
_namespace.translate(classGen, methodGen);
namespaceValue.setStart(il.append(new ASTORE(namespaceValue.getIndex())));

String transletClassName = getXSLTC().getClassName();
// load name value again
nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex())));

il.append(new ALOAD(namespaceValue.getIndex()));
il.append(new GETSTATIC(cpg.addFieldref(
transletClassName,
STATIC_NS_MAP_FIELD,
MAP_SIG)));
il.append(
new INVOKESTATIC(
cpg.addMethodref(BASIS_LIBRARY_CLASS,
ADD_NAMESPACE_PREFIX_REF,
ADD_NAMESPACE_PREFIX_SIG)));
namespaceValue.setEnd(il.append(new ALOAD(namespaceValue.getIndex())));
}
else{
// load name value again
nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex())));
_namespace.translate(classGen, methodGen);
}
}
else {
// load name value again
nameValue.setEnd(il.append(new ALOAD(nameValue.getIndex())));
// If name is an AVT and namespace is not specified, need to
// look up any prefix in the stylesheet by calling
// BasisLibrary.lookupStylesheetQNameNamespace(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
import java.text.NumberFormat;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.HashMap;
import java.util.Map;
import java.util.Collections;

import javax.xml.transform.dom.DOMSource;

Expand Down Expand Up @@ -1599,8 +1602,42 @@ public static String getPrefix(String qname) {
* This function is used in the execution of xsl:element
*/
private static int prefixIndex = 0; // not thread safe!!
private static Map<String,String> nsMap = Collections.synchronizedMap(new HashMap());
public static String generatePrefix() {
return ("ns" + prefixIndex++);
return ("ns" + prefixIndex++);
}
// This will record a new prefix used globally by XSLTC
// it *shouldn't be used anymore, but there might still be an edge case
public static String generatePrefix(String namespace) {
if(nsMap.containsKey(namespace)){
return nsMap.get(namespace);
}
else{
// Create a prefix, add to map and return it
String result = generatePrefix();
nsMap.put(namespace,result);
return result;
}
}
// This will record a new prefix (if there isn't one already)
// and add it to the qname if it doesn't already have a prefix.
// This stores the new prefix in the map belonging to the translet
// so we don't leak prefix between separate translets.
public static String addPrefix(String qname, String namespace, Map prefixMap){
// if it already has a prefix we don't need to do anything
if(qname.indexOf(':') == -1){
if(prefixMap.containsKey(namespace)){
return prefixMap.get(namespace)+":"+qname;
}
else{
String prefix = "ns"+prefixMap.size();
prefixMap.put(namespace,prefix);
return prefix+":"+qname;
}
}
else{
return qname;
}
}

public static final String RUN_TIME_INTERNAL_ERR =
Expand Down