FileDocCategorySizeDatePackage
AbstractTranslet.javaAPI DocJava SE 6 API25298Tue Jun 10 00:22:32 BST 2008com.sun.org.apache.xalan.internal.xsltc.runtime

AbstractTranslet

public abstract class AbstractTranslet extends Object implements Translet
author
Jacek Ambroziak
author
Santiago Pericas-Geertsen
author
Morten Jorgensen
author
G. Todd Miller
author
John Howard, JohnH@schemasoft.com

Fields Summary
public String
_version
public String
_method
public String
_encoding
public boolean
_omitHeader
public String
_standalone
public String
_doctypePublic
public String
_doctypeSystem
public boolean
_indent
public String
_mediaType
public Vector
_cdata
public int
_indentamount
public static final int
FIRST_TRANSLET_VERSION
public static final int
VER_SPLIT_NAMES_ARRAY
public static final int
CURRENT_TRANSLET_VERSION
protected int
transletVersion
protected String[]
namesArray
protected String[]
urisArray
protected int[]
typesArray
protected String[]
namespaceArray
protected Templates
_templates
protected boolean
_hasIdCall
protected StringValueHandler
stringValueHandler
private static final String
EMPTYSTRING
private static final String
ID_INDEX_NAME
protected int
pbase
Parameter handling
protected int
pframe
protected ArrayList
paramsStack
private MessageHandler
_msgHandler
Message handling - implementation of
public Hashtable
_formatSymbols
Decimal number format symbol handling
private Hashtable
_keyIndexes
Index(es) for / key() / id()
private KeyIndex
_emptyKeyIndex
private int
_indexSize
private int
_currentRootForKeys
private DOMCache
_domCache
DOM cache handling
private Hashtable
_auxClasses
protected DOMImplementation
_domImplementation
DOMImplementation caching for basis library
Constructors Summary
Methods Summary
public voidaddAuxiliaryClass(java.lang.Class auxClass)


        
	if (_auxClasses == null) _auxClasses = new Hashtable();
	_auxClasses.put(auxClass.getName(), auxClass);
    
public voidaddCdataElement(java.lang.String name)
Add's a name of an element whose text contents should be output as CDATA

	if (_cdata == null) {
            _cdata = new Vector();
        }

        int lastColon = name.lastIndexOf(':");

        if (lastColon > 0) {
            String uri = name.substring(0, lastColon);
            String localName = name.substring(lastColon+1);
	    _cdata.addElement(uri);
	    _cdata.addElement(localName);
        } else {
	    _cdata.addElement(null);
	    _cdata.addElement(name);
        }
    
public voidaddDecimalFormat(java.lang.String name, java.text.DecimalFormatSymbols symbols)
Adds a DecimalFormat object to the _formatSymbols hashtable. The entry is created with the input DecimalFormatSymbols.


                         
          
	// Instanciate hashtable for formatting symbols if needed
	if (_formatSymbols == null) _formatSymbols = new Hashtable();

	// The name cannot be null - use empty string instead
	if (name == null) name = EMPTYSTRING;

	// Construct a DecimalFormat object containing the symbols we got
	final DecimalFormat df = new DecimalFormat();
	if (symbols != null) {
	    df.setDecimalFormatSymbols(symbols);
	}
	_formatSymbols.put(name, df);
    
public final java.lang.ObjectaddParameter(java.lang.String name, java.lang.Object value)
Add a new global parameter if not already in the current frame. To setParameters of the form {http://foo.bar}xyz This needs to get mapped to an instance variable in the class The mapping created so that the global variables in the generated class become http$colon$$flash$$flash$foo$dot$bar$colon$xyz

        name = BasisLibrary.mapQNameToJavaName (name);
	return addParameter(name, value, false);
    
public final java.lang.ObjectaddParameter(java.lang.String name, java.lang.Object value, boolean isDefault)
Add a new global or local parameter if not already in the current frame. The 'isDefault' parameter is set to true if the value passed is the default value from the element's select attribute or element body.

	// Local parameters need to be re-evaluated for each iteration
	for (int i = pframe - 1; i >= pbase; i--) {
	    final Parameter param = (Parameter) paramsStack.get(i);

	    if (param._name.equals(name)) {
		// Only overwrite if current value is the default value and
		// the new value is _NOT_ the default value.
		if (param._isDefault || !isDefault) {
		    param._value = value;
		    param._isDefault = isDefault;
		    return value;
		}
		return param._value;
	    }
	}

	// Add new parameter to parameter stack
	paramsStack.add(pframe++, new Parameter(name, value, isDefault));
	return value;
    
private final voidbuildIDIndex(com.sun.org.apache.xalan.internal.xsltc.DOM document)
Leverages the Key Class to implement the XSLT id() function. buildIdIndex creates the index (##id) that Key Class uses. The index contains the element node index (int) and Id value (String).

        setRootForKeys(document.getDocument());

        if (document instanceof DOMEnhancedForDTM) {
            DOMEnhancedForDTM enhancedDOM = (DOMEnhancedForDTM)document;
            
            // If the input source is DOMSource, the KeyIndex table is not
            // built at this time. It will be built later by the lookupId()
            // and containsId() methods of the KeyIndex class.
            if (enhancedDOM.hasDOMSource()) {
                buildKeyIndex(ID_INDEX_NAME, document);
                return;
            }
            else {
                final Hashtable elementsByID = enhancedDOM.getElementsWithIDs();

                if (elementsByID == null) {
            	    return;
                }

                // Given a Hashtable of DTM nodes indexed by ID attribute values,
                // loop through the table copying information to a KeyIndex
                // for the mapping from ID attribute value to DTM node
                final Enumeration idValues = elementsByID.keys();
                boolean hasIDValues = false;

                while (idValues.hasMoreElements()) {
            	    final Object idValue = idValues.nextElement();
            	    final int element =
                            document.getNodeHandle(
                                        ((Integer)elementsByID.get(idValue))
                                                .intValue());

            	    buildKeyIndex(ID_INDEX_NAME, element, idValue);
            	    hasIDValues = true;
                }

                if (hasIDValues) {
            	    setKeyIndexDom(ID_INDEX_NAME, document);
                }
            }
        }
    
public voidbuildKeyIndex(java.lang.String name, int node, java.lang.Object value)
Adds a value to a key/id index

param
name is the name of the index (the key or ##id)
param
node is the node handle of the node to insert
param
value is the value that will look up the node in the given index

	if (_keyIndexes == null) _keyIndexes = new Hashtable();
	
	KeyIndex index = (KeyIndex)_keyIndexes.get(name);
	if (index == null) {
	    _keyIndexes.put(name, index = new KeyIndex(_indexSize));
	}
	index.add(value, node, _currentRootForKeys);
    
public voidbuildKeyIndex(java.lang.String name, com.sun.org.apache.xalan.internal.xsltc.DOM dom)
Create an empty KeyIndex in the DOM case

param
name is the name of the index (the key or ##id)
param
dom is the DOM

	if (_keyIndexes == null) _keyIndexes = new Hashtable();
	
	KeyIndex index = (KeyIndex)_keyIndexes.get(name);
	if (index == null) {
	    _keyIndexes.put(name, index = new KeyIndex(_indexSize));
	}
	index.setDom(dom, dom.getDocument());
    
public voidbuildKeys(com.sun.org.apache.xalan.internal.xsltc.DOM document, com.sun.org.apache.xml.internal.dtm.DTMAxisIterator iterator, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler, int root)
This method builds key indexes - it is overridden in the compiled translet in cases where the element is used

			  	
    
public final voidcharacters(java.lang.String string, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)
Used by some compiled code as a shortcut for passing strings to the output handler

        if (string != null) {
           //final int length = string.length();
           try {
               handler.characters(string);
           } catch (Exception e) {
               throw new TransletException(e);
           }
        }   
    
public voidclearParameters()
Clears the parameter stack.

  
	pbase = pframe = 0;
	paramsStack.clear();
    
public voidcloseOutputHandler(com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)

	try {
	    handler.endDocument();
	    handler.close();
	}
	catch (Exception e) {
	    // what can you do?
	}
    
public com.sun.org.apache.xalan.internal.xsltc.dom.KeyIndexcreateKeyIndex()
Creates a KeyIndex object of the desired size - don't want to resize!!!

	return(new KeyIndex(_indexSize));
    
public final voiddisplayMessage(java.lang.String msg)
Pass a message to the message handler - used by Message class.

	if (_msgHandler == null) {
            System.err.println(msg);
	}
	else {
	    _msgHandler.displayMessage(msg);
	}
    
public java.lang.ClassgetAuxiliaryClass(java.lang.String className)

	if (_auxClasses == null) return null;
	return((Class)_auxClasses.get(className));
    
public com.sun.org.apache.xalan.internal.xsltc.DOMCachegetDOMCache()
Returns the DOM cache used for this translet. Used by the LoadDocument class (if present) when the document() function is used.

	return(_domCache);
    
public final java.text.DecimalFormatgetDecimalFormat(java.lang.String name)
Retrieves a named DecimalFormat object from _formatSymbols hashtable.


	if (_formatSymbols != null) {
	    // The name cannot be null - use empty string instead
	    if (name == null) name = EMPTYSTRING;

	    DecimalFormat df = (DecimalFormat)_formatSymbols.get(name);
	    if (df == null) df = (DecimalFormat)_formatSymbols.get(EMPTYSTRING);
	    return df;
	}
	return(null);
    
public com.sun.org.apache.xalan.internal.xsltc.dom.KeyIndexgetKeyIndex(java.lang.String name)
Returns the index for a given key (or id). The index implements our internal iterator interface

	// Return an empty key index iterator if none are defined
	if (_keyIndexes == null) {
	    return (_emptyKeyIndex != null) 
	        ? _emptyKeyIndex
	        : (_emptyKeyIndex = new KeyIndex(1)); 
	} 

	// Look up the requested key index
	final KeyIndex index = (KeyIndex)_keyIndexes.get(name);

	// Return an empty key index iterator if the requested index not found
	if (index == null) {
	    return (_emptyKeyIndex != null) 
	        ? _emptyKeyIndex
	        : (_emptyKeyIndex = new KeyIndex(1)); 
	}

	return(index);
    
public java.lang.String[]getNamesArray()

	return namesArray;
    
public java.lang.String[]getNamespaceArray()

	return namespaceArray;
    
public final java.lang.ObjectgetParameter(java.lang.String name)
Get the value of a parameter from the current frame or null if undefined.


        name = BasisLibrary.mapQNameToJavaName (name);

	for (int i = pframe - 1; i >= pbase; i--) {
	    final Parameter param = (Parameter)paramsStack.get(i);
	    if (param._name.equals(name)) return param._value;
	}
	return null;
    
public javax.xml.transform.TemplatesgetTemplates()

    	return _templates;
    
public int[]getTypesArray()

    	return typesArray;
    
public java.lang.String[]getUrisArray()

    	return urisArray;
    
public booleanhasIdCall()

    	return _hasIdCall;
    
public final com.sun.org.apache.xalan.internal.xsltc.dom.DOMAdaptermakeDOMAdapter(com.sun.org.apache.xalan.internal.xsltc.DOM dom)
Wrap the initial input DOM in a dom adapter. This adapter is wrapped in a DOM multiplexer if the document() function is used (handled by compiled code in the translet - see compiler/Stylesheet.compileTransform()).

        setRootForKeys(dom.getDocument());
	return new DOMAdapter(dom, namesArray, urisArray, typesArray, namespaceArray);
    
public org.w3c.dom.DocumentnewDocument(java.lang.String uri, java.lang.String qname)

    
          
          
    
        if (_domImplementation == null) {
            _domImplementation = DocumentBuilderFactory.newInstance()
                .newDocumentBuilder().getDOMImplementation();
        }
        return _domImplementation.createDocument(uri, qname, null);
    
public com.sun.org.apache.xml.internal.serializer.SerializationHandleropenOutputHandler(java.lang.String filename, boolean append)
Multiple output document extension. See compiler/TransletOutput for actual implementation.

	try {
	    final TransletOutputHandlerFactory factory 
		= TransletOutputHandlerFactory.newInstance();

            String dirStr = new File(filename).getParent();
            if ((null != dirStr) && (dirStr.length() > 0)) {
               File dir = new File(dirStr);
               dir.mkdirs();
            }

	    factory.setEncoding(_encoding);
	    factory.setOutputMethod(_method);
	    factory.setWriter(new FileWriter(filename, append));
	    factory.setOutputType(TransletOutputHandlerFactory.STREAM);

	    final SerializationHandler handler 
		= factory.getSerializationHandler();

	    transferOutputSettings(handler);
	    handler.startDocument();
	    return handler;
	}
	catch (Exception e) {
	    throw new TransletException(e);
	}
    
public com.sun.org.apache.xml.internal.serializer.SerializationHandleropenOutputHandler(java.lang.String filename)

       return openOutputHandler(filename, false);
    
public final voidpopParamFrame()
Pop the topmost parameter frame.

	if (pbase > 0) {
	    final int oldpbase = ((Integer)paramsStack.get(--pbase)).intValue();
	    for (int i = pframe - 1; i >= pbase; i--) {
		paramsStack.remove(i);
	    }
	    pframe = pbase; pbase = oldpbase;
	}
    
public final voidpostInitialization()
After constructing the translet object, this method must be called to perform any version-specific post-initialization that's required.

        // 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());
        }
    
public final voidprepassDocument(com.sun.org.apache.xalan.internal.xsltc.DOM document)
Give the translet an opportunity to perform a prepass on the document to extract any information that it can store in an optimized form. Currently, it only extracts information about attributes of type ID.

        setIndexSize(document.getSize());
        buildIDIndex(document);
    
public voidprintInternalState()
Debugging


    
          
       
	System.out.println("-------------------------------------");
	System.out.println("AbstractTranslet this = " + this);
	System.out.println("pbase = " + pbase);
	System.out.println("vframe = " + pframe);
	System.out.println("paramsStack.size() = " + paramsStack.size());
	System.out.println("namesArray.size = " + namesArray.length);
	System.out.println("namespaceArray.size = " + namespaceArray.length);
	System.out.println("");
	System.out.println("Total memory = " + Runtime.getRuntime().totalMemory());
    
public final voidpushParamFrame()
Push a new parameter frame.


              
        
	paramsStack.add(pframe, new Integer(pbase));
	pbase = ++pframe;
    
public voidsetAuxiliaryClasses(Hashtable auxClasses)

    	_auxClasses = auxClasses;
    
public voidsetDOMCache(com.sun.org.apache.xalan.internal.xsltc.DOMCache cache)
Sets the DOM cache used for additional documents loaded using the document() function.


                      
        
	_domCache = cache;
    
public voidsetIndexSize(int size)
This method is used to pass the largest DOM size to the translet. Needed to make sure that the translet can index the whole DOM.


                                  
        
	if (size > _indexSize) _indexSize = size;
    
public voidsetKeyIndexDom(java.lang.String name, com.sun.org.apache.xalan.internal.xsltc.DOM document)
This method builds key indexes - it is overridden in the compiled translet in cases where the element is used

    	getKeyIndex(name).setDom(document, document.getDocument());			  	
    
public final voidsetMessageHandler(com.sun.org.apache.xalan.internal.xsltc.runtime.MessageHandler handler)
Set the translet's message handler - must implement MessageHandler


                  
         
	_msgHandler = handler;
    
private voidsetRootForKeys(int root)

        _currentRootForKeys = root;
    
public voidsetTemplates(javax.xml.transform.Templates templates)

    	_templates = templates;
    
protected voidtransferOutputSettings(com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)
Transfer the output settings to the output post-processor

	if (_method != null) {
	    if (_method.equals("xml")) {
	        if (_standalone != null) {
		    handler.setStandalone(_standalone);
		}
		if (_omitHeader) {
		    handler.setOmitXMLDeclaration(true);
		}
		handler.setCdataSectionElements(_cdata);
		if (_version != null) {
		    handler.setVersion(_version);
		}
		handler.setIndent(_indent);
		handler.setIndentAmount(_indentamount);
		if (_doctypeSystem != null) {
		    handler.setDoctype(_doctypeSystem, _doctypePublic);
		}
	    }
	    else if (_method.equals("html")) {
		handler.setIndent(_indent);
		handler.setDoctype(_doctypeSystem, _doctypePublic);
		if (_mediaType != null) {
		    handler.setMediaType(_mediaType);
		}
	    }
	}
	else {
	    handler.setCdataSectionElements(_cdata);
	    if (_version != null) {
		handler.setVersion(_version);
	    }
	    if (_standalone != null) {
		handler.setStandalone(_standalone);
	    }
	    if (_omitHeader) {
		handler.setOmitXMLDeclaration(true);
	    }
	    handler.setIndent(_indent);
	    handler.setDoctype(_doctypeSystem, _doctypePublic);
	}
    
public abstract voidtransform(com.sun.org.apache.xalan.internal.xsltc.DOM document, com.sun.org.apache.xml.internal.dtm.DTMAxisIterator iterator, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)
Main transform() method - this is overridden by the compiled translet

public final voidtransform(com.sun.org.apache.xalan.internal.xsltc.DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler handler)
Calls transform() with a given output handler

        try {
            transform(document, document.getIterator(), handler);
        } finally {
            _keyIndexes = null;
        }