xalan-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zong...@apache.org
Subject cvs commit: xml-xalan/java/src/org/apache/xalan/xsltc/runtime AbstractTranslet.java BasisLibrary.java
Date Mon, 24 Nov 2003 22:18:54 GMT
zongaro     2003/11/24 14:18:54

  Modified:    java/src/org/apache/xalan/xsltc/compiler Constants.java
                        Stylesheet.java
               java/src/org/apache/xalan/xsltc/runtime
                        AbstractTranslet.java BasisLibrary.java
  Log:
  Patch from Morris Kwan (mkwan@ca.ibm.com), reviewed by myself:
  
  Split namesArray in translet into three arrays:  namesArray, urisArray and
  typesArray.
  
  Previously, entries in the namesArray had to be examined at run-time to
  distinguish those that represented elements, from those that represented
  attributes (prefixed by an '@'), and those that represented namespace node
  names (prefixed by a '?').  In addition, any namespace URI for the element or
  attribute was similarly stored in the namesArray entry.  So,
  "http://example.org:abc" and "http://example.org:@abc" respectively represented
  an element and an attribute named abc in the http://example.org namespace;
  "?abc" represented a namespace prefix of abc.
  
  With this change, the namesArray will have entries for "abc" in all three
  cases; the urisArray will contain entries for "http://example.org" for the
  element and attribute, and an empty string for the namespace prefix; and the
  typesArray will contain the value 1 for the element, 2 for the attribute and 13
  for the namespace (which correspond to the DTM constant values for those kinds
  of nodes).
  
  In addition, these values are stored in static arrays in the translet, and
  references to those arrays are copied to instance fields in the translet's
  constructor, rather than constructing arrays and initializing all their entries
  in the constructor each time.
  
  All this serves to reduce the overhead of initializing a transformation.
  
  Patch from myself, reviewed by Morris Kwan:
  
  Introduced a versioning mechanism in AbstractTranslet.  After constructing an
  object of a class that extends AbstractTranslet, the postInitialization method
  must be called.  That method will detect any versioning differences that can
  be resolved automatically, if a translet was compiled with an older version of
  the XSLTC than is being used at run-time.  The version number is stored in the
  translet's transletVersion field.
  
  In many cases, incompabilities run up against Java's binary compatibility
  rules, and fail catastrophically.  This versioning mechanism is designed to
  detect those cases that can't be detected by the JVM.  The first use of this
  mechanism is to translate from the old form of the namesArray used by old
  translets, to the new form expected by the modified version of the XSLTC
  run-time, as described above.
  
  In addition, if the translet version detected by the XSLTC run-time is more
  recent than any supported by the XSLTC run-time, an error will be reported.
  
  Revision  Changes    Path
  1.37      +21 -1     xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java
  
  Index: Constants.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Constants.java,v
  retrieving revision 1.36
  retrieving revision 1.37
  diff -u -r1.36 -r1.37
  --- Constants.java	8 Aug 2003 21:55:14 -0000	1.36
  +++ Constants.java	24 Nov 2003 22:18:54 -0000	1.37
  @@ -400,6 +400,14 @@
   	= "namesArray";
       public static final String NAMES_INDEX_SIG
   	= "[" + STRING_SIG;
  +    public static final String URIS_INDEX
  +       = "urisArray";
  +    public static final String URIS_INDEX_SIG
  +       = "[" + STRING_SIG;
  +    public static final String TYPES_INDEX
  +       = "typesArray";
  +    public static final String TYPES_INDEX_SIG
  +       = "[I";
       public static final String NAMESPACE_INDEX
   	= "namespaceArray";
       public static final String NAMESPACE_INDEX_SIG
  @@ -408,9 +416,21 @@
           = "_hasIdCall";
       public static final String HASIDCALL_INDEX_SIG
           = "Z";
  +    public static final String TRANSLET_VERSION_INDEX
  +        = "transletVersion";
  +    public static final String TRANSLET_VERSION_INDEX_SIG
  +        = "I";
   
       public static final String DOM_FIELD
   	= "_dom";
  +    public static final String STATIC_NAMES_ARRAY_FIELD
  +        = "_sNamesArray";
  +    public static final String STATIC_URIS_ARRAY_FIELD
  +        = "_sUrisArray";
  +    public static final String STATIC_TYPES_ARRAY_FIELD
  +        = "_sTypesArray";
  +    public static final String STATIC_NAMESPACE_ARRAY_FIELD
  +        = "_sNamespaceArray";
       public static final String STATIC_CHAR_DATA_FIELD
           = "_scharData";
       public static final String STATIC_CHAR_DATA_FIELD_SIG
  
  
  
  1.57      +151 -44   xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java
  
  Index: Stylesheet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/compiler/Stylesheet.java,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -r1.56 -r1.57
  --- Stylesheet.java	17 Oct 2003 16:14:19 -0000	1.56
  +++ Stylesheet.java	24 Nov 2003 22:18:54 -0000	1.57
  @@ -76,9 +76,11 @@
   
   import org.apache.xml.utils.SystemIDResolver;
   import org.apache.bcel.generic.ANEWARRAY;
  +import org.apache.bcel.generic.BasicType;
   import org.apache.bcel.generic.ConstantPoolGen;
   import org.apache.bcel.generic.FieldGen;
   import org.apache.bcel.generic.GETFIELD;
  +import org.apache.bcel.generic.GETSTATIC;
   import org.apache.bcel.generic.INVOKEINTERFACE;
   import org.apache.bcel.generic.INVOKESPECIAL;
   import org.apache.bcel.generic.INVOKEVIRTUAL;
  @@ -87,6 +89,7 @@
   import org.apache.bcel.generic.InstructionList;
   import org.apache.bcel.generic.LocalVariableGen;
   import org.apache.bcel.generic.NEW;
  +import org.apache.bcel.generic.NEWARRAY;
   import org.apache.bcel.generic.PUSH;
   import org.apache.bcel.generic.PUTFIELD;
   import org.apache.bcel.generic.PUTSTATIC;
  @@ -98,6 +101,7 @@
   import org.apache.xalan.xsltc.compiler.util.Type;
   import org.apache.xalan.xsltc.compiler.util.TypeCheckError;
   import org.apache.xalan.xsltc.compiler.util.Util;
  +import org.apache.xalan.xsltc.runtime.AbstractTranslet;
   import org.apache.xml.dtm.DTM;
   
   public final class Stylesheet extends SyntaxTreeNode {
  @@ -656,7 +660,7 @@
   					   classGen.getConstantPool());
   	classGen.addField(fgen.getField());
       }
  -
  +    
       /**
        * Add a static field
        */
  @@ -730,19 +734,25 @@
       }
   
       /**
  -     * Create a static initializer for the translet which will contain
  -     * read-only that can be shared by all translet instances.
  +     * Compile the namesArray, urisArray and typesArray into
  +     * the static initializer. They are read-only from the
  +     * translet. All translet instances can share a single
  +     * copy of this informtion.
        */
       private void compileStaticInitializer(ClassGenerator classGen) {
  -        final ConstantPoolGen cpg = classGen.getConstantPool();
  -        final InstructionList il = new InstructionList();
  +	final ConstantPoolGen cpg = classGen.getConstantPool();
  +	final InstructionList il = new InstructionList();
   
  -        final MethodGenerator staticConst =
  -            new MethodGenerator(ACC_PUBLIC|ACC_STATIC,
  -                                org.apache.bcel.generic.Type.VOID,
  -                                null, null, "<clinit>",
  -                                _className, il, cpg);
  +	final MethodGenerator staticConst =
  +	    new MethodGenerator(ACC_PUBLIC|ACC_STATIC,
  +				org.apache.bcel.generic.Type.VOID, 
  +				null, null, "<clinit>", 
  +				_className, il, cpg);
   
  +	addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMES_ARRAY_FIELD);
  +	addStaticField(classGen, "[" + STRING_SIG, STATIC_URIS_ARRAY_FIELD);
  +	addStaticField(classGen, "[I", STATIC_TYPES_ARRAY_FIELD);
  +	addStaticField(classGen, "[" + STRING_SIG, STATIC_NAMESPACE_ARRAY_FIELD);
           // Create fields of type char[] that will contain literal text from
           // the stylesheet.
           final int charDataFieldCount = getXSLTC().getCharacterDataCount();
  @@ -751,6 +761,97 @@
                              STATIC_CHAR_DATA_FIELD+i);
           }
   
  +	// Put the names array into the translet - used for dom/translet mapping
  +	final Vector namesIndex = getXSLTC().getNamesIndex();
  +	int size = namesIndex.size();
  +	String[] namesArray = new String[size];
  +	String[] urisArray = new String[size];
  +	int[] typesArray = new int[size];
  +	
  +	int index;
  +	for (int i = 0; i < size; i++) {
  +	    String encodedName = (String)namesIndex.elementAt(i);
  +	    if ((index = encodedName.lastIndexOf(':')) > -1) {
  +	        urisArray[i] = encodedName.substring(0, index);
  +	    }
  +	    
  +	    index = index + 1;
  +	    if (encodedName.charAt(index) == '@') {
  +	    	typesArray[i] = DTM.ATTRIBUTE_NODE;
  +	    	index++;
  +	    } else if (encodedName.charAt(index) == '?') {
  +	    	typesArray[i] = DTM.NAMESPACE_NODE;
  +	    	index++;
  +	    } else {
  +	        typesArray[i] = DTM.ELEMENT_NODE;
  +	    }
  +	    
  +	    if (index == 0) {
  +	        namesArray[i] = encodedName;
  +	    }
  +	    else {
  +	        namesArray[i] = encodedName.substring(index);
  +	    }	    
  +	}
  +	
  +	il.append(new PUSH(cpg, size));
  +	il.append(new ANEWARRAY(cpg.addClass(STRING)));		
  +
  +	for (int i = 0; i < size; i++) {
  +	    final String name = namesArray[i];
  +	    il.append(DUP);
  +	    il.append(new PUSH(cpg, i));
  +	    il.append(new PUSH(cpg, name));
  +	    il.append(AASTORE);
  +	}
  +	il.append(new PUTSTATIC(cpg.addFieldref(_className,
  +					       STATIC_NAMES_ARRAY_FIELD,
  +					       NAMES_INDEX_SIG)));
  +
  +	il.append(new PUSH(cpg, size));
  +	il.append(new ANEWARRAY(cpg.addClass(STRING)));		
  +
  +	for (int i = 0; i < size; i++) {
  +	    final String uri = urisArray[i];
  +	    il.append(DUP);
  +	    il.append(new PUSH(cpg, i));
  +	    il.append(new PUSH(cpg, uri));
  +	    il.append(AASTORE);
  +	}
  +	il.append(new PUTSTATIC(cpg.addFieldref(_className,
  +					       STATIC_URIS_ARRAY_FIELD,
  +					       URIS_INDEX_SIG)));
  +
  +	il.append(new PUSH(cpg, size));
  +	il.append(new NEWARRAY(BasicType.INT));		
  +
  +	for (int i = 0; i < size; i++) {
  +	    final int nodeType = typesArray[i];
  +	    il.append(DUP);
  +	    il.append(new PUSH(cpg, i));
  +	    il.append(new PUSH(cpg, nodeType));
  +	    il.append(IASTORE);
  +	}
  +	il.append(new PUTSTATIC(cpg.addFieldref(_className,
  +					       STATIC_TYPES_ARRAY_FIELD,
  +					       TYPES_INDEX_SIG)));
  +
  +	// Put the namespace names array into the translet
  +	final Vector namespaces = getXSLTC().getNamespaceIndex();
  +	il.append(new PUSH(cpg, namespaces.size()));
  +	il.append(new ANEWARRAY(cpg.addClass(STRING)));		
  +
  +	for (int i = 0; i < namespaces.size(); i++) {
  +	    final String ns = (String)namespaces.elementAt(i);
  +	    il.append(DUP);
  +	    il.append(new PUSH(cpg, i));
  +	    il.append(new PUSH(cpg, ns));
  +	    il.append(AASTORE);
  +	}
  +	il.append(new PUTSTATIC(cpg.addFieldref(_className,
  +					       STATIC_NAMESPACE_ARRAY_FIELD,
  +					       NAMESPACE_INDEX_SIG)));
  +
           // Grab all the literal text in the stylesheet and put it in a char[]
           final int charDataCount = getXSLTC().getCharacterDataCount();
           final int toCharArray = cpg.addMethodref(STRING, "toCharArray", "()[C");
  @@ -762,13 +863,15 @@
                                                  STATIC_CHAR_DATA_FIELD_SIG)));
           }
   
  -        il.append(RETURN);
  +	il.append(RETURN);
   
  -        staticConst.stripAttributes(true);
  -        staticConst.setMaxLocals();
  -        staticConst.setMaxStack();
  -        classGen.addMethod(staticConst.getMethod());
  +	staticConst.stripAttributes(true);
  +	staticConst.setMaxLocals();
  +	staticConst.setMaxStack();
  +	classGen.addMethod(staticConst.getMethod());
  +    	
       }
  +
       /**
        * Compile the translet's constructor
        */
  @@ -787,41 +890,45 @@
   	il.append(classGen.loadTranslet());
   	il.append(new INVOKESPECIAL(cpg.addMethodref(TRANSLET_CLASS,
   						     "<init>", "()V")));
  -
  -	// Put the names array into the translet - used for dom/translet mapping
  -	final Vector names = getXSLTC().getNamesIndex();
  +	
   	il.append(classGen.loadTranslet());
  -	il.append(new PUSH(cpg, names.size()));
  -	il.append(new ANEWARRAY(cpg.addClass(STRING)));		
  -
  -	for (int i = 0; i < names.size(); i++) {
  -	    final String name = (String)names.elementAt(i);
  -	    il.append(DUP);
  -	    il.append(new PUSH(cpg, i));
  -	    il.append(new PUSH(cpg, name));
  -	    il.append(AASTORE);
  -	}
  +	il.append(new GETSTATIC(cpg.addFieldref(_className,
  +	                                        STATIC_NAMES_ARRAY_FIELD,
  +	                                        NAMES_INDEX_SIG)));
   	il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS,
  -					       NAMES_INDEX,
  -					       NAMES_INDEX_SIG)));
  +	                                       NAMES_INDEX,
  +	                                       NAMES_INDEX_SIG)));
  +	
  +	il.append(classGen.loadTranslet());
  +	il.append(new GETSTATIC(cpg.addFieldref(_className,
  +	                                        STATIC_URIS_ARRAY_FIELD,
  +	                                        URIS_INDEX_SIG)));
  +	il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS,
  +	                                       URIS_INDEX,
  +	                                       URIS_INDEX_SIG)));
   
  -	// Put the namespace names array into the translet
  -	final Vector namespaces = getXSLTC().getNamespaceIndex();
   	il.append(classGen.loadTranslet());
  -	il.append(new PUSH(cpg, namespaces.size()));
  -	il.append(new ANEWARRAY(cpg.addClass(STRING)));		
  +	il.append(new GETSTATIC(cpg.addFieldref(_className,
  +	                                        STATIC_TYPES_ARRAY_FIELD,
  +	                                        TYPES_INDEX_SIG)));
  +	il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS,
  +	                                       TYPES_INDEX,
  +	                                       TYPES_INDEX_SIG)));
   
  -	for (int i = 0; i < namespaces.size(); i++) {
  -	    final String ns = (String)namespaces.elementAt(i);
  -	    il.append(DUP);
  -	    il.append(new PUSH(cpg, i));
  -	    il.append(new PUSH(cpg, ns));
  -	    il.append(AASTORE);
  -	}
  +	il.append(classGen.loadTranslet());
  +	il.append(new GETSTATIC(cpg.addFieldref(_className,
  +	                                        STATIC_NAMESPACE_ARRAY_FIELD,
  +	                                        NAMESPACE_INDEX_SIG)));
   	il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS,
  -					       NAMESPACE_INDEX,
  -					       NAMESPACE_INDEX_SIG)));
  +	                                       NAMESPACE_INDEX,
  +	                                       NAMESPACE_INDEX_SIG)));
   
  +	il.append(classGen.loadTranslet());
  +        il.append(new PUSH(cpg, AbstractTranslet.CURRENT_TRANSLET_VERSION));
  +	il.append(new PUTFIELD(cpg.addFieldref(TRANSLET_CLASS,
  +	                                       TRANSLET_VERSION_INDEX,
  +	                                       TRANSLET_VERSION_INDEX_SIG)));
  +	
   	if (_hasIdCall) {
   	    il.append(classGen.loadTranslet());
   	    il.append(new PUSH(cpg, Boolean.TRUE));
  
  
  
  1.50      +78 -2     xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java
  
  Index: AbstractTranslet.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/AbstractTranslet.java,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- AbstractTranslet.java	11 Nov 2003 14:40:29 -0000	1.49
  +++ AbstractTranslet.java	24 Nov 2003 22:18:54 -0000	1.50
  @@ -73,6 +73,8 @@
   import java.util.Vector;
   import javax.xml.transform.Templates;
   
  +import org.apache.xml.dtm.DTM;
  +
   import org.apache.xalan.xsltc.DOM;
   import org.apache.xalan.xsltc.DOMCache;
   import org.apache.xalan.xsltc.Translet;
  @@ -99,8 +101,21 @@
       public String  _mediaType = null;
       public Vector _cdata = null;
   
  +    public static final int FIRST_TRANSLET_VERSION = 100;
  +    public static final int VER_SPLIT_NAMES_ARRAY = 101;
  +    public static final int CURRENT_TRANSLET_VERSION = VER_SPLIT_NAMES_ARRAY;
  +
  +    // Initialize Translet version field to base value.  A class that extends
  +    // AbstractTranslet may override this value to a more recent translet
  +    // version; if it doesn't override the value (because it was compiled
  +    // before the notion of a translet version was introduced, it will get
  +    // this default value).
  +    protected int transletVersion = FIRST_TRANSLET_VERSION;
  +
       // DOM/translet handshaking - the arrays are set by the compiled translet
       protected String[] namesArray;
  +    protected String[] urisArray;
  +    protected int[]    typesArray;
       protected String[] namespaceArray;
       
       // The Templates object that is used to create this Translet instance
  @@ -141,7 +156,7 @@
        */
       public final DOMAdapter makeDOMAdapter(DOM dom)
   	throws TransletException {
  -	return new DOMAdapter(dom, namesArray, namespaceArray);
  +	return new DOMAdapter(dom, namesArray, urisArray, typesArray, namespaceArray);
       }
   
       /************************************************************************
  @@ -366,6 +381,58 @@
           }
       }
   
  +    /**
  +     * After constructing the translet object, this method must be called to
  +     * perform any version-specific post-initialization that's required.
  +     */
  +    public final void postInitialization() {
  +        // If the version of the translet had just one namesArray, split
  +        // it into multiple fields.
  +        if (transletVersion < VER_SPLIT_NAMES_ARRAY) {
  +            int arraySize = namesArray.length;
  +            String[] newURIsArray = new String[arraySize];
  +            String[] newNamesArray = new String[arraySize];
  +            int[] newTypesArray = new int[arraySize];
  +
  +            for (int i = 0; i < arraySize; i++) {
  +                String name = namesArray[i];
  +                int colonIndex = name.lastIndexOf(':');
  +                int lNameStartIdx = colonIndex+1;
  +
  +                if (colonIndex > -1) {
  +                    newURIsArray[i] = name.substring(0, colonIndex);
  +                }
  +
  +               // Distinguish attribute and element names.  Attribute has
  +               // @ before local part of name.
  +               if (name.charAt(lNameStartIdx) == '@') {
  +                   lNameStartIdx++;
  +                   newTypesArray[i] = DTM.ATTRIBUTE_NODE;
  +               } else if (name.charAt(lNameStartIdx) == '?') {
  +                   lNameStartIdx++;
  +                   newTypesArray[i] = DTM.NAMESPACE_NODE;
  +               } else {
  +                   newTypesArray[i] = DTM.ELEMENT_NODE;
  +               }
  +               newNamesArray[i] =
  +                          (lNameStartIdx == 0) ? name
  +                                               : name.substring(lNameStartIdx);
  +            }
  +
  +            namesArray = newNamesArray;
  +            urisArray  = newURIsArray;
  +            typesArray = newTypesArray;
  +        }
  +
  +        // Was translet compiled using a more recent version of the XSLTC
  +        // compiler than is known by the AbstractTranslet class?  If, so
  +        // and we've made it this far (which is doubtful), we should give up.
  +        if (transletVersion > CURRENT_TRANSLET_VERSION) {
  +            BasisLibrary.runTimeError(BasisLibrary.UNKNOWN_TRANSLET_VERSION_ERR,
  +                                      this.getClass().getName());
  +        }
  +    }
  +
       /************************************************************************
        * Index(es) for <xsl:key> / key() / id()
        ************************************************************************/
  @@ -655,6 +722,15 @@
       public String[] getNamesArray() {
   	return namesArray;
       }
  +    
  +    public String[] getUrisArray() {
  +    	return urisArray;
  +    }
  +    
  +    public int[] getTypesArray() {
  +    	return typesArray;
  +    }
  +    
       public String[] getNamespaceArray() {
   	return namespaceArray;
       }
  
  
  
  1.64      +7 -3      xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java
  
  Index: BasisLibrary.java
  ===================================================================
  RCS file: /home/cvs/xml-xalan/java/src/org/apache/xalan/xsltc/runtime/BasisLibrary.java,v
  retrieving revision 1.63
  retrieving revision 1.64
  diff -u -r1.63 -r1.64
  --- BasisLibrary.java	11 Nov 2003 14:40:29 -0000	1.63
  +++ BasisLibrary.java	24 Nov 2003 22:18:54 -0000	1.64
  @@ -1196,6 +1196,8 @@
   	    // Create DOMAdapter and register with MultiDOM
   	    DOMAdapter domAdapter = new DOMAdapter(idom, 
                   translet.getNamesArray(),
  +                translet.getUrisArray(),
  +                translet.getTypesArray(),
   		translet.getNamespaceArray());
               multiDOM.addDOMAdapter(domAdapter);
   
  @@ -1366,10 +1368,12 @@
                                              "NAMESPACES_SUPPORT_ERR";
       public static final String CANT_RESOLVE_RELATIVE_URI_ERR =
                                              "CANT_RESOLVE_RELATIVE_URI_ERR";
  -    public static final String UNSUPPORTED_XSL_ERR =                                  
    
  +    public static final String UNSUPPORTED_XSL_ERR =
                                              "UNSUPPORTED_XSL_ERR";
  -    public static final String UNSUPPORTED_EXT_ERR =                                  
    
  +    public static final String UNSUPPORTED_EXT_ERR =
                                              "UNSUPPORTED_EXT_ERR";
  +    public static final String UNKNOWN_TRANSLET_VERSION_ERR =
  +                                           "UNKNOWN_TRANSLET_VERSION_ERR";
   
       // All error messages are localized and are stored in resource bundles.
       protected static ResourceBundle m_bundle;
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org


Mime
View raw message