286N/A/*
286N/A * reserved comment block
286N/A * DO NOT REMOVE OR ALTER!
286N/A */
286N/A/*
286N/A * Copyright 2001-2004 The Apache Software Foundation.
286N/A *
286N/A * Licensed under the Apache License, Version 2.0 (the "License");
286N/A * you may not use this file except in compliance with the License.
286N/A * You may obtain a copy of the License at
286N/A *
286N/A * http://www.apache.org/licenses/LICENSE-2.0
286N/A *
286N/A * Unless required by applicable law or agreed to in writing, software
286N/A * distributed under the License is distributed on an "AS IS" BASIS,
286N/A * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
286N/A * See the License for the specific language governing permissions and
286N/A * limitations under the License.
286N/A */
286N/A/*
286N/A * $Id: SymbolTable.java,v 1.5 2005/09/28 13:48:16 pvedula Exp $
286N/A */
286N/A
286N/Apackage com.sun.org.apache.xalan.internal.xsltc.compiler;
286N/A
286N/Aimport java.util.Hashtable;
286N/Aimport java.util.Stack;
286N/Aimport java.util.StringTokenizer;
286N/Aimport java.util.Vector;
286N/A
286N/Aimport com.sun.org.apache.xalan.internal.xsltc.compiler.util.MethodType;
286N/A
286N/A/**
286N/A * @author Jacek Ambroziak
286N/A * @author Santiago Pericas-Geertsen
286N/A * @author Morten Jorgensen
286N/A */
286N/Afinal class SymbolTable {
286N/A
286N/A // These hashtables are used for all stylesheets
286N/A private final Hashtable _stylesheets = new Hashtable();
286N/A private final Hashtable _primops = new Hashtable();
286N/A
286N/A // These hashtables are used for some stylesheets
286N/A private Hashtable _variables = null;
286N/A private Hashtable _templates = null;
286N/A private Hashtable _attributeSets = null;
286N/A private Hashtable _aliases = null;
286N/A private Hashtable _excludedURI = null;
286N/A private Stack _excludedURIStack = null;
286N/A private Hashtable _decimalFormats = null;
286N/A private Hashtable _keys = null;
286N/A
286N/A public DecimalFormatting getDecimalFormatting(QName name) {
286N/A if (_decimalFormats == null) return null;
286N/A return((DecimalFormatting)_decimalFormats.get(name));
286N/A }
286N/A
286N/A public void addDecimalFormatting(QName name, DecimalFormatting symbols) {
286N/A if (_decimalFormats == null) _decimalFormats = new Hashtable();
286N/A _decimalFormats.put(name, symbols);
286N/A }
286N/A
286N/A public Key getKey(QName name) {
286N/A if (_keys == null) return null;
286N/A return (Key) _keys.get(name);
286N/A }
286N/A
286N/A public void addKey(QName name, Key key) {
286N/A if (_keys == null) _keys = new Hashtable();
286N/A _keys.put(name, key);
286N/A }
286N/A
286N/A public Stylesheet addStylesheet(QName name, Stylesheet node) {
286N/A return (Stylesheet)_stylesheets.put(name, node);
286N/A }
286N/A
286N/A public Stylesheet lookupStylesheet(QName name) {
286N/A return (Stylesheet)_stylesheets.get(name);
286N/A }
286N/A
286N/A public Template addTemplate(Template template) {
286N/A final QName name = template.getName();
286N/A if (_templates == null) _templates = new Hashtable();
286N/A return (Template)_templates.put(name, template);
286N/A }
286N/A
286N/A public Template lookupTemplate(QName name) {
286N/A if (_templates == null) return null;
286N/A return (Template)_templates.get(name);
286N/A }
286N/A
286N/A public Variable addVariable(Variable variable) {
286N/A if (_variables == null) _variables = new Hashtable();
286N/A final String name = variable.getName().getStringRep();
286N/A return (Variable)_variables.put(name, variable);
286N/A }
286N/A
286N/A public Param addParam(Param parameter) {
286N/A if (_variables == null) _variables = new Hashtable();
286N/A final String name = parameter.getName().getStringRep();
286N/A return (Param)_variables.put(name, parameter);
286N/A }
286N/A
286N/A public Variable lookupVariable(QName qname) {
286N/A if (_variables == null) return null;
286N/A final String name = qname.getStringRep();
286N/A final Object obj = _variables.get(name);
286N/A return obj instanceof Variable ? (Variable)obj : null;
286N/A }
286N/A
286N/A public Param lookupParam(QName qname) {
286N/A if (_variables == null) return null;
286N/A final String name = qname.getStringRep();
286N/A final Object obj = _variables.get(name);
286N/A return obj instanceof Param ? (Param)obj : null;
286N/A }
286N/A
286N/A public SyntaxTreeNode lookupName(QName qname) {
286N/A if (_variables == null) return null;
286N/A final String name = qname.getStringRep();
286N/A return (SyntaxTreeNode)_variables.get(name);
286N/A }
286N/A
286N/A public AttributeSet addAttributeSet(AttributeSet atts) {
286N/A if (_attributeSets == null) _attributeSets = new Hashtable();
286N/A return (AttributeSet)_attributeSets.put(atts.getName(), atts);
286N/A }
286N/A
286N/A public AttributeSet lookupAttributeSet(QName name) {
286N/A if (_attributeSets == null) return null;
286N/A return (AttributeSet)_attributeSets.get(name);
286N/A }
286N/A
286N/A /**
286N/A * Add a primitive operator or function to the symbol table. To avoid
286N/A * name clashes with user-defined names, the prefix <tt>PrimopPrefix</tt>
286N/A * is prepended.
286N/A */
286N/A public void addPrimop(String name, MethodType mtype) {
286N/A Vector methods = (Vector)_primops.get(name);
286N/A if (methods == null) {
286N/A _primops.put(name, methods = new Vector());
286N/A }
286N/A methods.addElement(mtype);
286N/A }
286N/A
286N/A /**
286N/A * Lookup a primitive operator or function in the symbol table by
286N/A * prepending the prefix <tt>PrimopPrefix</tt>.
286N/A */
286N/A public Vector lookupPrimop(String name) {
286N/A return (Vector)_primops.get(name);
286N/A }
286N/A
286N/A /**
286N/A * This is used for xsl:attribute elements that have a "namespace"
286N/A * attribute that is currently not defined using xmlns:
286N/A */
286N/A private int _nsCounter = 0;
286N/A
286N/A public String generateNamespacePrefix() {
293N/A return("ns"+(_nsCounter++));
286N/A }
286N/A
286N/A /**
286N/A * Use a namespace prefix to lookup a namespace URI
286N/A */
286N/A private SyntaxTreeNode _current = null;
286N/A
286N/A public void setCurrentNode(SyntaxTreeNode node) {
286N/A _current = node;
286N/A }
286N/A
286N/A public String lookupNamespace(String prefix) {
286N/A if (_current == null) return(Constants.EMPTYSTRING);
286N/A return(_current.lookupNamespace(prefix));
286N/A }
286N/A
286N/A /**
286N/A * Adds an alias for a namespace prefix
286N/A */
286N/A public void addPrefixAlias(String prefix, String alias) {
286N/A if (_aliases == null) _aliases = new Hashtable();
286N/A _aliases.put(prefix,alias);
286N/A }
286N/A
286N/A /**
286N/A * Retrieves any alias for a given namespace prefix
286N/A */
286N/A public String lookupPrefixAlias(String prefix) {
286N/A if (_aliases == null) return null;
286N/A return (String)_aliases.get(prefix);
286N/A }
286N/A
286N/A /**
286N/A * Register a namespace URI so that it will not be declared in the output
286N/A * unless it is actually referenced in the output.
286N/A */
286N/A public void excludeURI(String uri) {
286N/A // The null-namespace cannot be excluded
286N/A if (uri == null) return;
286N/A
286N/A // Create new hashtable of exlcuded URIs if none exists
286N/A if (_excludedURI == null) _excludedURI = new Hashtable();
286N/A
286N/A // Register the namespace URI
286N/A Integer refcnt = (Integer)_excludedURI.get(uri);
286N/A if (refcnt == null)
286N/A refcnt = new Integer(1);
286N/A else
286N/A refcnt = new Integer(refcnt.intValue() + 1);
286N/A _excludedURI.put(uri,refcnt);
286N/A }
286N/A
286N/A /**
286N/A * Exclude a series of namespaces given by a list of whitespace
286N/A * separated namespace prefixes.
286N/A */
286N/A public void excludeNamespaces(String prefixes) {
286N/A if (prefixes != null) {
286N/A StringTokenizer tokens = new StringTokenizer(prefixes);
286N/A while (tokens.hasMoreTokens()) {
286N/A final String prefix = tokens.nextToken();
286N/A final String uri;
286N/A if (prefix.equals("#default"))
286N/A uri = lookupNamespace(Constants.EMPTYSTRING);
286N/A else
286N/A uri = lookupNamespace(prefix);
286N/A if (uri != null) excludeURI(uri);
286N/A }
286N/A }
286N/A }
286N/A
286N/A /**
286N/A * Check if a namespace should not be declared in the output (unless used)
286N/A */
286N/A public boolean isExcludedNamespace(String uri) {
286N/A if (uri != null && _excludedURI != null) {
286N/A final Integer refcnt = (Integer)_excludedURI.get(uri);
286N/A return (refcnt != null && refcnt.intValue() > 0);
286N/A }
286N/A return false;
286N/A }
286N/A
286N/A /**
286N/A * Turn of namespace declaration exclusion
286N/A */
286N/A public void unExcludeNamespaces(String prefixes) {
286N/A if (_excludedURI == null) return;
286N/A if (prefixes != null) {
286N/A StringTokenizer tokens = new StringTokenizer(prefixes);
286N/A while (tokens.hasMoreTokens()) {
286N/A final String prefix = tokens.nextToken();
286N/A final String uri;
286N/A if (prefix.equals("#default"))
286N/A uri = lookupNamespace(Constants.EMPTYSTRING);
286N/A else
286N/A uri = lookupNamespace(prefix);
286N/A Integer refcnt = (Integer)_excludedURI.get(uri);
286N/A if (refcnt != null)
286N/A _excludedURI.put(uri, new Integer(refcnt.intValue() - 1));
286N/A }
286N/A }
286N/A }
286N/A /**
286N/A * Exclusion of namespaces by a stylesheet does not extend to any stylesheet
286N/A * imported or included by the stylesheet. Upon entering the context of a
286N/A * new stylesheet, a call to this method is needed to clear the current set
286N/A * of excluded namespaces temporarily. Every call to this method requires
286N/A * a corresponding call to {@link #popExcludedNamespacesContext()}.
286N/A */
286N/A public void pushExcludedNamespacesContext() {
286N/A if (_excludedURIStack == null) {
286N/A _excludedURIStack = new Stack();
286N/A }
286N/A _excludedURIStack.push(_excludedURI);
286N/A _excludedURI = null;
286N/A }
286N/A
286N/A /**
286N/A * Exclusion of namespaces by a stylesheet does not extend to any stylesheet
286N/A * imported or included by the stylesheet. Upon exiting the context of a
286N/A * stylesheet, a call to this method is needed to restore the set of
286N/A * excluded namespaces that was in effect prior to entering the context of
286N/A * the current stylesheet.
286N/A */
286N/A public void popExcludedNamespacesContext() {
286N/A _excludedURI = (Hashtable) _excludedURIStack.pop();
286N/A if (_excludedURIStack.isEmpty()) {
286N/A _excludedURIStack = null;
286N/A }
286N/A }
286N/A
286N/A}