Mercurial > hg > release > icedtea7-forest-2.3 > jaxp
changeset 274:44f4743bbd56
6981408: Upgrade jaxp to 1.4.4
line wrap: on
line diff
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/CallTemplate.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/CallTemplate.java Wed Sep 28 17:10:18 2011 +0100 @@ -64,14 +64,14 @@ private Template _calleeTemplate = null; public void display(int indent) { - indent(indent); - System.out.print("CallTemplate"); - Util.println(" name " + _name); - displayContents(indent + IndentIncrement); + indent(indent); + System.out.print("CallTemplate"); + Util.println(" name " + _name); + displayContents(indent + IndentIncrement); } public boolean hasWithParams() { - return elementCount() > 0; + return elementCount() > 0; } public void parseContents(Parser parser) { @@ -86,72 +86,72 @@ else { reportError(this, parser, ErrorMsg.REQUIRED_ATTR_ERR, "name"); } - parseChildren(parser); + parseChildren(parser); } /** * Verify that a template with this name exists. */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { - final Template template = stable.lookupTemplate(_name); - if (template != null) { - typeCheckContents(stable); - } - else { - ErrorMsg err = new ErrorMsg(ErrorMsg.TEMPLATE_UNDEF_ERR,_name,this); - throw new TypeCheckError(err); - } - return Type.Void; + final Template template = stable.lookupTemplate(_name); + if (template != null) { + typeCheckContents(stable); + } + else { + ErrorMsg err = new ErrorMsg(ErrorMsg.TEMPLATE_UNDEF_ERR,_name,this); + throw new TypeCheckError(err); + } + return Type.Void; } public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - final Stylesheet stylesheet = classGen.getStylesheet(); - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); + final Stylesheet stylesheet = classGen.getStylesheet(); + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); // If there are Params in the stylesheet or WithParams in this call? - if (stylesheet.hasLocalParams() || hasContents()) { - _calleeTemplate = getCalleeTemplate(); + if (stylesheet.hasLocalParams() || hasContents()) { + _calleeTemplate = getCalleeTemplate(); - // Build the parameter list if the called template is simple named - if (_calleeTemplate != null) { - buildParameterList(); - } - // This is only needed when the called template is not - // a simple named template. - else { - // Push parameter frame - final int push = cpg.addMethodref(TRANSLET_CLASS, - PUSH_PARAM_FRAME, - PUSH_PARAM_FRAME_SIG); - il.append(classGen.loadTranslet()); - il.append(new INVOKEVIRTUAL(push)); - translateContents(classGen, methodGen); - } - } + // Build the parameter list if the called template is simple named + if (_calleeTemplate != null) { + buildParameterList(); + } + // This is only needed when the called template is not + // a simple named template. + else { + // Push parameter frame + final int push = cpg.addMethodref(TRANSLET_CLASS, + PUSH_PARAM_FRAME, + PUSH_PARAM_FRAME_SIG); + il.append(classGen.loadTranslet()); + il.append(new INVOKEVIRTUAL(push)); + translateContents(classGen, methodGen); + } + } // Generate a valid Java method name - final String className = stylesheet.getClassName(); + final String className = stylesheet.getClassName(); String methodName = Util.escape(_name.toString()); // Load standard arguments - il.append(classGen.loadTranslet()); - il.append(methodGen.loadDOM()); - il.append(methodGen.loadIterator()); - il.append(methodGen.loadHandler()); - il.append(methodGen.loadCurrentNode()); + il.append(classGen.loadTranslet()); + il.append(methodGen.loadDOM()); + il.append(methodGen.loadIterator()); + il.append(methodGen.loadHandler()); + il.append(methodGen.loadCurrentNode()); // Initialize prefix of method signature - StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG + StringBuffer methodSig = new StringBuffer("(" + DOM_INTF_SIG + NODE_ITERATOR_SIG + TRANSLET_OUTPUT_SIG + NODE_SIG); // If calling a simply named template, push actual arguments - if (_calleeTemplate != null) { - Vector calleeParams = _calleeTemplate.getParameters(); - int numParams = _parameters.length; + if (_calleeTemplate != null) { + Vector calleeParams = _calleeTemplate.getParameters(); + int numParams = _parameters.length; - for (int i = 0; i < numParams; i++) { - SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i]; + for (int i = 0; i < numParams; i++) { + SyntaxTreeNode node = (SyntaxTreeNode)_parameters[i]; methodSig.append(OBJECT_SIG); // append Object to signature // Push 'null' if Param to indicate no actual parameter specified @@ -165,21 +165,21 @@ } // Complete signature and generate invokevirtual call - methodSig.append(")V"); - il.append(new INVOKEVIRTUAL(cpg.addMethodref(className, - methodName, - methodSig.toString()))); + methodSig.append(")V"); + il.append(new INVOKEVIRTUAL(cpg.addMethodref(className, + methodName, + methodSig.toString()))); - // Do not need to call Translet.popParamFrame() if we are - // calling a simple named template. - if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) { - // Pop parameter frame - final int pop = cpg.addMethodref(TRANSLET_CLASS, - POP_PARAM_FRAME, - POP_PARAM_FRAME_SIG); - il.append(classGen.loadTranslet()); - il.append(new INVOKEVIRTUAL(pop)); - } + // Do not need to call Translet.popParamFrame() if we are + // calling a simple named template. + if (_calleeTemplate == null && (stylesheet.hasLocalParams() || hasContents())) { + // Pop parameter frame + final int pop = cpg.addMethodref(TRANSLET_CLASS, + POP_PARAM_FRAME, + POP_PARAM_FRAME_SIG); + il.append(classGen.loadTranslet()); + il.append(new INVOKEVIRTUAL(pop)); + } } /** @@ -188,7 +188,7 @@ * template is not a simple named template. */ public Template getCalleeTemplate() { - Template foundTemplate + Template foundTemplate = getXSLTC().getParser().getSymbolTable().lookupTemplate(_name); return foundTemplate.isSimpleNamedTemplate() ? foundTemplate : null; @@ -201,42 +201,43 @@ * the Param with a corresponding WithParam having the same name. */ private void buildParameterList() { - // Put the parameters from the called template into the array first. - // This is to ensure the order of the parameters. - Vector defaultParams = _calleeTemplate.getParameters(); - int numParams = defaultParams.size(); - _parameters = new Object[numParams]; - for (int i = 0; i < numParams; i++) { - _parameters[i] = defaultParams.elementAt(i); - } + // Put the parameters from the called template into the array first. + // This is to ensure the order of the parameters. + Vector defaultParams = _calleeTemplate.getParameters(); + int numParams = defaultParams.size(); + _parameters = new Object[numParams]; + for (int i = 0; i < numParams; i++) { + _parameters[i] = defaultParams.elementAt(i); + } - // Replace a Param with a WithParam if they have the same name. - int count = elementCount(); - for (int i = 0; i < count; i++) { - Object node = elementAt(i); + // Replace a Param with a WithParam if they have the same name. + int count = elementCount(); + for (int i = 0; i < count; i++) { + Object node = elementAt(i); // Ignore if not WithParam - if (node instanceof WithParam) { - WithParam withParam = (WithParam)node; - QName name = withParam.getName(); + if (node instanceof WithParam) { + WithParam withParam = (WithParam)node; + QName name = withParam.getName(); // Search for a Param with the same name - for (int k = 0; k < numParams; k++) { - Object object = _parameters[k]; - if (object instanceof Param - && ((Param)object).getName() == name) { - withParam.setDoParameterOptimization(true); - _parameters[k] = withParam; - break; - } - else if (object instanceof WithParam - && ((WithParam)object).getName() == name) { - withParam.setDoParameterOptimization(true); - _parameters[k] = withParam; - break; - } - } - } - } + for (int k = 0; k < numParams; k++) { + Object object = _parameters[k]; + if (object instanceof Param + && ((Param)object).getName().equals(name)) { + withParam.setDoParameterOptimization(true); + _parameters[k] = withParam; + break; + } + else if (object instanceof WithParam + && ((WithParam)object).getName().equals(name)) { + withParam.setDoParameterOptimization(true); + _parameters[k] = withParam; + break; + } + } + } + } } } +
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FilterExpr.java Wed Sep 28 17:10:18 2011 +0100 @@ -49,111 +49,118 @@ * @author Morten Jorgensen */ class FilterExpr extends Expression { - + /** * Primary expression of this filter. I.e., 'e' in '(e)[p1]...[pn]'. */ private Expression _primary; - + /** * Array of predicates in '(e)[p1]...[pn]'. */ private final Vector _predicates; public FilterExpr(Expression primary, Vector predicates) { - _primary = primary; - _predicates = predicates; - primary.setParent(this); + _primary = primary; + _predicates = predicates; + primary.setParent(this); } protected Expression getExpr() { - if (_primary instanceof CastExpr) - return ((CastExpr)_primary).getExpr(); - else - return _primary; + if (_primary instanceof CastExpr) + return ((CastExpr)_primary).getExpr(); + else + return _primary; } public void setParser(Parser parser) { - super.setParser(parser); - _primary.setParser(parser); - if (_predicates != null) { - final int n = _predicates.size(); - for (int i = 0; i < n; i++) { - final Expression exp = (Expression)_predicates.elementAt(i); - exp.setParser(parser); - exp.setParent(this); - } - } + super.setParser(parser); + _primary.setParser(parser); + if (_predicates != null) { + final int n = _predicates.size(); + for (int i = 0; i < n; i++) { + final Expression exp = (Expression)_predicates.elementAt(i); + exp.setParser(parser); + exp.setParent(this); + } + } } - + public String toString() { - return "filter-expr(" + _primary + ", " + _predicates + ")"; + return "filter-expr(" + _primary + ", " + _predicates + ")"; } /** - * Type check a FilterParentPath. If the filter is not a node-set add a - * cast to node-set only if it is of reference type. This type coercion + * Type check a FilterParentPath. If the filter is not a node-set add a + * cast to node-set only if it is of reference type. This type coercion * is needed for expressions like $x where $x is a parameter reference. * All optimizations are turned off before type checking underlying * predicates. */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { - Type ptype = _primary.typeCheck(stable); + Type ptype = _primary.typeCheck(stable); - if (ptype instanceof NodeSetType == false) { - if (ptype instanceof ReferenceType) { - _primary = new CastExpr(_primary, Type.NodeSet); - } - else { - throw new TypeCheckError(this); - } - } + if (ptype instanceof NodeSetType == false) { + if (ptype instanceof ReferenceType) { + _primary = new CastExpr(_primary, Type.NodeSet); + } + else { + throw new TypeCheckError(this); + } + } // Type check predicates and turn all optimizations off - int n = _predicates.size(); - for (int i = 0; i < n; i++) { - Predicate pred = (Predicate) _predicates.elementAt(i); + int n = _predicates.size(); + for (int i = 0; i < n; i++) { + Predicate pred = (Predicate) _predicates.elementAt(i); pred.dontOptimize(); - pred.typeCheck(stable); - } - return _type = Type.NodeSet; + pred.typeCheck(stable); + } + return _type = Type.NodeSet; } - + /** * Translate a filter expression by pushing the appropriate iterator * onto the stack. */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - if (_predicates.size() > 0) { - translatePredicates(classGen, methodGen); - } - else { - _primary.translate(classGen, methodGen); - } + translateFilterExpr(classGen, methodGen, _predicates == null ? -1 : _predicates.size() - 1); + } + + private void translateFilterExpr(ClassGenerator classGen, + MethodGenerator methodGen, + int predicateIndex) { + if (predicateIndex >= 0) { + translatePredicates(classGen, methodGen, predicateIndex); + } + else { + _primary.translate(classGen, methodGen); + } } /** - * Translate a sequence of predicates. Each predicate is translated - * by constructing an instance of <code>CurrentNodeListIterator</code> - * which is initialized from another iterator (recursive call), a - * filter and a closure (call to translate on the predicate) and "this". + * Translate a sequence of predicates. Each predicate is translated + * by constructing an instance of <code>CurrentNodeListIterator</code> + * which is initialized from another iterator (recursive call), a + * filter and a closure (call to translate on the predicate) and "this". */ public void translatePredicates(ClassGenerator classGen, - MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); + MethodGenerator methodGen, + int predicateIndex) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); // If not predicates left, translate primary expression - if (_predicates.size() == 0) { - translate(classGen, methodGen); - } - else { + if (predicateIndex < 0) { + translateFilterExpr(classGen, methodGen, predicateIndex); + } + else { // Translate predicates from right to left - final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, - "<init>", - "("+NODE_ITERATOR_SIG+"Z"+ - CURRENT_NODE_LIST_FILTER_SIG + - NODE_SIG+TRANSLET_SIG+")V"); + final int initCNLI = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, + "<init>", + "("+NODE_ITERATOR_SIG+"Z"+ + CURRENT_NODE_LIST_FILTER_SIG + + NODE_SIG+TRANSLET_SIG+")V"); // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. @@ -164,12 +171,11 @@ // in temporary variables, create the object and reload the // arguments from the temporaries to avoid the problem. - // Remove the next predicate to be translated - Predicate predicate = (Predicate)_predicates.lastElement(); - _predicates.remove(predicate); + // Get the next predicate to be translated + Predicate predicate = (Predicate) _predicates.get(predicateIndex--); // Translate the rest of the predicates from right to left - translatePredicates(classGen, methodGen); + translatePredicates(classGen, methodGen, predicateIndex); LocalVariableGen nodeIteratorTemp = methodGen.addLocalVariable("filter_expr_tmp1", @@ -187,7 +193,7 @@ // Create a CurrentNodeListIterator il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); il.append(DUP); - + // Initialize CurrentNodeListIterator il.append(new ALOAD(nodeIteratorTemp.getIndex())); il.append(ICONST_1); @@ -195,6 +201,6 @@ il.append(methodGen.loadCurrentNode()); il.append(classGen.loadTranslet()); il.append(new INVOKESPECIAL(initCNLI)); - } + } } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/LiteralElement.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/LiteralElement.java Wed Sep 28 17:10:18 2011 +0100 @@ -63,16 +63,16 @@ * Returns the QName for this literal element */ public QName getName() { - return _qname; + return _qname; } /** * Displays the contents of this literal element */ public void display(int indent) { - indent(indent); - Util.println("LiteralElement name = " + _name); - displayContents(indent + IndentIncrement); + indent(indent); + Util.println("LiteralElement name = " + _name); + displayContents(indent + IndentIncrement); } /** @@ -95,36 +95,36 @@ * definition for each namespace, so we stuff them in a hashtable. */ public void registerNamespace(String prefix, String uri, - SymbolTable stable, boolean declared) { + SymbolTable stable, boolean declared) { - // Check if the parent has a declaration for this namespace - if (_literalElemParent != null) { - final String parentUri = _literalElemParent.accessedNamespace(prefix); - if (parentUri != null && parentUri.equals(uri)) { + // Check if the parent has a declaration for this namespace + if (_literalElemParent != null) { + final String parentUri = _literalElemParent.accessedNamespace(prefix); + if (parentUri != null && parentUri.equals(uri)) { return; } - } + } - // Check if we have any declared namesaces - if (_accessedPrefixes == null) { - _accessedPrefixes = new Hashtable(); - } - else { - if (!declared) { - // Check if this node has a declaration for this namespace - final String old = (String)_accessedPrefixes.get(prefix); - if (old != null) { - if (old.equals(uri)) - return; - else - prefix = stable.generateNamespacePrefix(); - } - } - } + // Check if we have any declared namesaces + if (_accessedPrefixes == null) { + _accessedPrefixes = new Hashtable(); + } + else { + if (!declared) { + // Check if this node has a declaration for this namespace + final String old = (String)_accessedPrefixes.get(prefix); + if (old != null) { + if (old.equals(uri)) + return; + else + prefix = stable.generateNamespacePrefix(); + } + } + } - if (!prefix.equals("xml")) { - _accessedPrefixes.put(prefix,uri); - } + if (!prefix.equals("xml")) { + _accessedPrefixes.put(prefix,uri); + } } /** @@ -133,55 +133,55 @@ * that the output element contains the necessary namespace declarations. */ private String translateQName(QName qname, SymbolTable stable) { - // Break up the QName and get prefix:localname strings - String localname = qname.getLocalPart(); - String prefix = qname.getPrefix(); + // Break up the QName and get prefix:localname strings + String localname = qname.getLocalPart(); + String prefix = qname.getPrefix(); - // Treat default namespace as "" and not null - if (prefix == null) - prefix = Constants.EMPTYSTRING; - else if (prefix.equals(XMLNS_STRING)) - return(XMLNS_STRING); + // Treat default namespace as "" and not null + if (prefix == null) + prefix = Constants.EMPTYSTRING; + else if (prefix.equals(XMLNS_STRING)) + return(XMLNS_STRING); - // Check if we must translate the prefix - final String alternative = stable.lookupPrefixAlias(prefix); - if (alternative != null) { - stable.excludeNamespaces(prefix); - prefix = alternative; - } + // Check if we must translate the prefix + final String alternative = stable.lookupPrefixAlias(prefix); + if (alternative != null) { + stable.excludeNamespaces(prefix); + prefix = alternative; + } - // Get the namespace this prefix refers to - String uri = lookupNamespace(prefix); - if (uri == null) return(localname); + // Get the namespace this prefix refers to + String uri = lookupNamespace(prefix); + if (uri == null) return(localname); - // Register the namespace as accessed - registerNamespace(prefix, uri, stable, false); + // Register the namespace as accessed + registerNamespace(prefix, uri, stable, false); - // Construct the new name for the element (may be unchanged) - if (prefix != Constants.EMPTYSTRING) - return(prefix+":"+localname); - else - return(localname); + // Construct the new name for the element (may be unchanged) + if (prefix != Constants.EMPTYSTRING) + return(prefix+":"+localname); + else + return(localname); } /** * Add an attribute to this element */ public void addAttribute(SyntaxTreeNode attribute) { - if (_attributeElements == null) { - _attributeElements = new Vector(2); - } - _attributeElements.add(attribute); + if (_attributeElements == null) { + _attributeElements = new Vector(2); + } + _attributeElements.add(attribute); } /** * Set the first attribute of this element */ public void setFirstAttribute(SyntaxTreeNode attribute) { - if (_attributeElements == null) { - _attributeElements = new Vector(2); - } - _attributeElements.insertElementAt(attribute,0); + if (_attributeElements == null) { + _attributeElements = new Vector(2); + } + _attributeElements.insertElementAt(attribute,0); } /** @@ -189,17 +189,17 @@ * need any type checking as it leaves nothign on the JVM's stack. */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { - // Type-check all attributes - if (_attributeElements != null) { - final int count = _attributeElements.size(); - for (int i = 0; i < count; i++) { - SyntaxTreeNode node = - (SyntaxTreeNode)_attributeElements.elementAt(i); - node.typeCheck(stable); - } - } - typeCheckContents(stable); - return Type.Void; + // Type-check all attributes + if (_attributeElements != null) { + final int count = _attributeElements.size(); + for (int i = 0; i < count; i++) { + SyntaxTreeNode node = + (SyntaxTreeNode)_attributeElements.elementAt(i); + node.typeCheck(stable); + } + } + typeCheckContents(stable); + return Type.Void; } /** @@ -208,22 +208,22 @@ * to _ANY_ namespace URI. Used by literal result elements to determine */ public Enumeration getNamespaceScope(SyntaxTreeNode node) { - Hashtable all = new Hashtable(); + Hashtable all = new Hashtable(); - while (node != null) { - Hashtable mapping = node.getPrefixMapping(); - if (mapping != null) { - Enumeration prefixes = mapping.keys(); - while (prefixes.hasMoreElements()) { - String prefix = (String)prefixes.nextElement(); - if (!all.containsKey(prefix)) { - all.put(prefix, mapping.get(prefix)); - } - } - } - node = node.getParent(); - } - return(all.keys()); + while (node != null) { + Hashtable mapping = node.getPrefixMapping(); + if (mapping != null) { + Enumeration prefixes = mapping.keys(); + while (prefixes.hasMoreElements()) { + String prefix = (String)prefixes.nextElement(); + if (!all.containsKey(prefix)) { + all.put(prefix, mapping.get(prefix)); + } + } + } + node = node.getParent(); + } + return(all.keys()); } /** @@ -231,94 +231,94 @@ * Registers all namespaces that are used by the element/attributes */ public void parseContents(Parser parser) { - final SymbolTable stable = parser.getSymbolTable(); - stable.setCurrentNode(this); + final SymbolTable stable = parser.getSymbolTable(); + stable.setCurrentNode(this); - // Check if in a literal element context - SyntaxTreeNode parent = getParent(); + // Check if in a literal element context + SyntaxTreeNode parent = getParent(); if (parent != null && parent instanceof LiteralElement) { _literalElemParent = (LiteralElement) parent; - } + } - _name = translateQName(_qname, stable); + _name = translateQName(_qname, stable); - // Process all attributes and register all namespaces they use - final int count = _attributes.getLength(); - for (int i = 0; i < count; i++) { - final QName qname = parser.getQName(_attributes.getQName(i)); - final String uri = qname.getNamespace(); - final String val = _attributes.getValue(i); + // Process all attributes and register all namespaces they use + final int count = _attributes.getLength(); + for (int i = 0; i < count; i++) { + final QName qname = parser.getQName(_attributes.getQName(i)); + final String uri = qname.getNamespace(); + final String val = _attributes.getValue(i); - // Handle xsl:use-attribute-sets. Attribute sets are placed first - // in the vector or attributes to make sure that later local - // attributes can override an attributes in the set. - if (qname == parser.getUseAttributeSets()) { - if (!Util.isValidQNames(val)) { + // Handle xsl:use-attribute-sets. Attribute sets are placed first + // in the vector or attributes to make sure that later local + // attributes can override an attributes in the set. + if (qname.equals(parser.getUseAttributeSets())) { + if (!Util.isValidQNames(val)) { ErrorMsg err = new ErrorMsg(ErrorMsg.INVALID_QNAME_ERR, val, this); parser.reportError(Constants.ERROR, err); } - setFirstAttribute(new UseAttributeSets(val, parser)); - } - // Handle xsl:extension-element-prefixes - else if (qname == parser.getExtensionElementPrefixes()) { - stable.excludeNamespaces(val); - } - // Handle xsl:exclude-result-prefixes - else if (qname == parser.getExcludeResultPrefixes()) { - stable.excludeNamespaces(val); - } - else { - // Ignore special attributes (e.g. xmlns:prefix and xmlns) - final String prefix = qname.getPrefix(); - if (prefix != null && prefix.equals(XMLNS_PREFIX) || - prefix == null && qname.getLocalPart().equals("xmlns") || - uri != null && uri.equals(XSLT_URI)) - { - continue; - } + setFirstAttribute(new UseAttributeSets(val, parser)); + } + // Handle xsl:extension-element-prefixes + else if (qname.equals(parser.getExtensionElementPrefixes())) { + stable.excludeNamespaces(val); + } + // Handle xsl:exclude-result-prefixes + else if (qname.equals(parser.getExcludeResultPrefixes())) { + stable.excludeNamespaces(val); + } + else { + // Ignore special attributes (e.g. xmlns:prefix and xmlns) + final String prefix = qname.getPrefix(); + if (prefix != null && prefix.equals(XMLNS_PREFIX) || + prefix == null && qname.getLocalPart().equals("xmlns") || + uri != null && uri.equals(XSLT_URI)) + { + continue; + } - // Handle all other literal attributes - final String name = translateQName(qname, stable); - LiteralAttribute attr = new LiteralAttribute(name, val, parser, this); - addAttribute(attr); - attr.setParent(this); - attr.parseContents(parser); - } - } + // Handle all other literal attributes + final String name = translateQName(qname, stable); + LiteralAttribute attr = new LiteralAttribute(name, val, parser, this); + addAttribute(attr); + attr.setParent(this); + attr.parseContents(parser); + } + } - // Register all namespaces that are in scope, except for those that - // are listed in the xsl:stylesheet element's *-prefixes attributes - final Enumeration include = getNamespaceScope(this); - while (include.hasMoreElements()) { - final String prefix = (String)include.nextElement(); - if (!prefix.equals("xml")) { - final String uri = lookupNamespace(prefix); - if (uri != null && !stable.isExcludedNamespace(uri)) { - registerNamespace(prefix, uri, stable, true); - } - } - } + // Register all namespaces that are in scope, except for those that + // are listed in the xsl:stylesheet element's *-prefixes attributes + final Enumeration include = getNamespaceScope(this); + while (include.hasMoreElements()) { + final String prefix = (String)include.nextElement(); + if (!prefix.equals("xml")) { + final String uri = lookupNamespace(prefix); + if (uri != null && !stable.isExcludedNamespace(uri)) { + registerNamespace(prefix, uri, stable, true); + } + } + } - parseChildren(parser); + parseChildren(parser); - // Process all attributes and register all namespaces they use - for (int i = 0; i < count; i++) { - final QName qname = parser.getQName(_attributes.getQName(i)); - final String val = _attributes.getValue(i); + // Process all attributes and register all namespaces they use + for (int i = 0; i < count; i++) { + final QName qname = parser.getQName(_attributes.getQName(i)); + final String val = _attributes.getValue(i); - // Handle xsl:extension-element-prefixes - if (qname == parser.getExtensionElementPrefixes()) { - stable.unExcludeNamespaces(val); - } - // Handle xsl:exclude-result-prefixes - else if (qname == parser.getExcludeResultPrefixes()) { - stable.unExcludeNamespaces(val); - } - } + // Handle xsl:extension-element-prefixes + if (qname.equals(parser.getExtensionElementPrefixes())) { + stable.unExcludeNamespaces(val); + } + // Handle xsl:exclude-result-prefixes + else if (qname.equals(parser.getExcludeResultPrefixes())) { + stable.unExcludeNamespaces(val); + } + } } protected boolean contextDependent() { - return dependentContents(); + return dependentContents(); } /** @@ -330,91 +330,82 @@ */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); // Check whether all attributes are unique. _allAttributesUnique = checkAttributesUnique(); - // Compile code to emit element start tag - il.append(methodGen.loadHandler()); + // Compile code to emit element start tag + il.append(methodGen.loadHandler()); - il.append(new PUSH(cpg, _name)); - il.append(DUP2); // duplicate these 2 args for endElement - il.append(methodGen.startElement()); + il.append(new PUSH(cpg, _name)); + il.append(DUP2); // duplicate these 2 args for endElement + il.append(methodGen.startElement()); - // The value of an attribute may depend on a (sibling) variable - int j=0; - while (j < elementCount()) - { - final SyntaxTreeNode item = (SyntaxTreeNode) elementAt(j); - if (item instanceof Variable) { - item.translate(classGen, methodGen); - removeElement(item); // avoid translating it twice - /* When removing an element we do not increment j - * but the removal will reduce the value of elementCount() - * so this loop WILL end. The next iteration will process - * elementAt(j), but with the old element removed - * we are actually processing the next element. - */ + // The value of an attribute may depend on a (sibling) variable + int j=0; + while (j < elementCount()) { + final SyntaxTreeNode item = (SyntaxTreeNode) elementAt(j); + if (item instanceof Variable) { + item.translate(classGen, methodGen); } - else j++; } - // Compile code to emit namespace attributes - if (_accessedPrefixes != null) { - boolean declaresDefaultNS = false; - Enumeration e = _accessedPrefixes.keys(); + // Compile code to emit namespace attributes + if (_accessedPrefixes != null) { + boolean declaresDefaultNS = false; + Enumeration e = _accessedPrefixes.keys(); - while (e.hasMoreElements()) { - final String prefix = (String)e.nextElement(); - final String uri = (String)_accessedPrefixes.get(prefix); + while (e.hasMoreElements()) { + final String prefix = (String)e.nextElement(); + final String uri = (String)_accessedPrefixes.get(prefix); - if (uri != Constants.EMPTYSTRING || - prefix != Constants.EMPTYSTRING) - { - if (prefix == Constants.EMPTYSTRING) { - declaresDefaultNS = true; - } - il.append(methodGen.loadHandler()); - il.append(new PUSH(cpg,prefix)); - il.append(new PUSH(cpg,uri)); - il.append(methodGen.namespace()); - } - } + if (uri != Constants.EMPTYSTRING || + prefix != Constants.EMPTYSTRING) + { + if (prefix == Constants.EMPTYSTRING) { + declaresDefaultNS = true; + } + il.append(methodGen.loadHandler()); + il.append(new PUSH(cpg,prefix)); + il.append(new PUSH(cpg,uri)); + il.append(methodGen.namespace()); + } + } - /* - * If our XslElement parent redeclares the default NS, and this - * element doesn't, it must be redeclared one more time. - */ - if (!declaresDefaultNS && (_parent instanceof XslElement) - && ((XslElement) _parent).declaresDefaultNS()) - { - il.append(methodGen.loadHandler()); - il.append(new PUSH(cpg, Constants.EMPTYSTRING)); - il.append(new PUSH(cpg, Constants.EMPTYSTRING)); - il.append(methodGen.namespace()); - } - } + /* + * If our XslElement parent redeclares the default NS, and this + * element doesn't, it must be redeclared one more time. + */ + if (!declaresDefaultNS && (_parent instanceof XslElement) + && ((XslElement) _parent).declaresDefaultNS()) + { + il.append(methodGen.loadHandler()); + il.append(new PUSH(cpg, Constants.EMPTYSTRING)); + il.append(new PUSH(cpg, Constants.EMPTYSTRING)); + il.append(methodGen.namespace()); + } + } - // Output all attributes - if (_attributeElements != null) { - final int count = _attributeElements.size(); - for (int i = 0; i < count; i++) { - SyntaxTreeNode node = - (SyntaxTreeNode)_attributeElements.elementAt(i); - if (!(node instanceof XslAttribute)) { - node.translate(classGen, methodGen); - } - } - } + // Output all attributes + if (_attributeElements != null) { + final int count = _attributeElements.size(); + for (int i = 0; i < count; i++) { + SyntaxTreeNode node = + (SyntaxTreeNode)_attributeElements.elementAt(i); + if (!(node instanceof XslAttribute)) { + node.translate(classGen, methodGen); + } + } + } - // Compile code to emit attributes and child elements - translateContents(classGen, methodGen); + // Compile code to emit attributes and child elements + translateContents(classGen, methodGen); - // Compile code to emit element end tag - il.append(methodGen.endElement()); + // Compile code to emit element end tag + il.append(methodGen.endElement()); } /** @@ -430,67 +421,67 @@ * valid HTML element. */ public ElemDesc getElemDesc() { - if (isHTMLOutput()) { - return ToHTMLStream.getElemDesc(_name); - } - else - return null; + if (isHTMLOutput()) { + return ToHTMLStream.getElemDesc(_name); + } + else + return null; } /** * Return true if all attributes of this LRE have unique names. */ public boolean allAttributesUnique() { - return _allAttributesUnique; + return _allAttributesUnique; } /** * Check whether all attributes are unique. */ private boolean checkAttributesUnique() { - boolean hasHiddenXslAttribute = canProduceAttributeNodes(this, true); - if (hasHiddenXslAttribute) - return false; + boolean hasHiddenXslAttribute = canProduceAttributeNodes(this, true); + if (hasHiddenXslAttribute) + return false; - if (_attributeElements != null) { - int numAttrs = _attributeElements.size(); - Hashtable attrsTable = null; - for (int i = 0; i < numAttrs; i++) { - SyntaxTreeNode node = (SyntaxTreeNode)_attributeElements.elementAt(i); + if (_attributeElements != null) { + int numAttrs = _attributeElements.size(); + Hashtable attrsTable = null; + for (int i = 0; i < numAttrs; i++) { + SyntaxTreeNode node = (SyntaxTreeNode)_attributeElements.elementAt(i); - if (node instanceof UseAttributeSets) { - return false; - } - else if (node instanceof XslAttribute) { - if (attrsTable == null) { - attrsTable = new Hashtable(); - for (int k = 0; k < i; k++) { - SyntaxTreeNode n = (SyntaxTreeNode)_attributeElements.elementAt(k); - if (n instanceof LiteralAttribute) { - LiteralAttribute literalAttr = (LiteralAttribute)n; - attrsTable.put(literalAttr.getName(), literalAttr); - } - } - } + if (node instanceof UseAttributeSets) { + return false; + } + else if (node instanceof XslAttribute) { + if (attrsTable == null) { + attrsTable = new Hashtable(); + for (int k = 0; k < i; k++) { + SyntaxTreeNode n = (SyntaxTreeNode)_attributeElements.elementAt(k); + if (n instanceof LiteralAttribute) { + LiteralAttribute literalAttr = (LiteralAttribute)n; + attrsTable.put(literalAttr.getName(), literalAttr); + } + } + } - XslAttribute xslAttr = (XslAttribute)node; - AttributeValue attrName = xslAttr.getName(); - if (attrName instanceof AttributeValueTemplate) { - return false; - } - else if (attrName instanceof SimpleAttributeValue) { - SimpleAttributeValue simpleAttr = (SimpleAttributeValue)attrName; - String name = simpleAttr.toString(); - if (name != null && attrsTable.get(name) != null) - return false; - else if (name != null) { - attrsTable.put(name, xslAttr); - } - } - } - } - } - return true; + XslAttribute xslAttr = (XslAttribute)node; + AttributeValue attrName = xslAttr.getName(); + if (attrName instanceof AttributeValueTemplate) { + return false; + } + else if (attrName instanceof SimpleAttributeValue) { + SimpleAttributeValue simpleAttr = (SimpleAttributeValue)attrName; + String name = simpleAttr.toString(); + if (name != null && attrsTable.get(name) != null) + return false; + else if (name != null) { + attrsTable.put(name, xslAttr); + } + } + } + } + } + return true; } /** @@ -500,59 +491,59 @@ * <xsl:attribute> children of the current node are not included in the check. */ private boolean canProduceAttributeNodes(SyntaxTreeNode node, boolean ignoreXslAttribute) { - Vector contents = node.getContents(); - int size = contents.size(); - for (int i = 0; i < size; i++) { - SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); - if (child instanceof Text) { - Text text = (Text)child; - if (text.isIgnore()) - continue; - else - return false; - } - // Cannot add an attribute to an element after children have been added to it. - // We can safely return false when the instruction can produce an output node. - else if (child instanceof LiteralElement - || child instanceof ValueOf - || child instanceof XslElement - || child instanceof Comment - || child instanceof Number - || child instanceof ProcessingInstruction) - return false; - else if (child instanceof XslAttribute) { - if (ignoreXslAttribute) - continue; - else - return true; - } - // In general, there is no way to check whether <xsl:call-template> or - // <xsl:apply-templates> can produce attribute nodes. <xsl:copy> and - // <xsl:copy-of> can also copy attribute nodes to an element. Return - // true in those cases to be safe. - else if (child instanceof CallTemplate - || child instanceof ApplyTemplates - || child instanceof Copy - || child instanceof CopyOf) - return true; - else if ((child instanceof If - || child instanceof ForEach) - && canProduceAttributeNodes(child, false)) { - return true; - } - else if (child instanceof Choose) { - Vector chooseContents = child.getContents(); - int num = chooseContents.size(); - for (int k = 0; k < num; k++) { - SyntaxTreeNode chooseChild = (SyntaxTreeNode)chooseContents.elementAt(k); - if (chooseChild instanceof When || chooseChild instanceof Otherwise) { - if (canProduceAttributeNodes(chooseChild, false)) - return true; - } - } - } - } - return false; + Vector contents = node.getContents(); + int size = contents.size(); + for (int i = 0; i < size; i++) { + SyntaxTreeNode child = (SyntaxTreeNode)contents.elementAt(i); + if (child instanceof Text) { + Text text = (Text)child; + if (text.isIgnore()) + continue; + else + return false; + } + // Cannot add an attribute to an element after children have been added to it. + // We can safely return false when the instruction can produce an output node. + else if (child instanceof LiteralElement + || child instanceof ValueOf + || child instanceof XslElement + || child instanceof Comment + || child instanceof Number + || child instanceof ProcessingInstruction) + return false; + else if (child instanceof XslAttribute) { + if (ignoreXslAttribute) + continue; + else + return true; + } + // In general, there is no way to check whether <xsl:call-template> or + // <xsl:apply-templates> can produce attribute nodes. <xsl:copy> and + // <xsl:copy-of> can also copy attribute nodes to an element. Return + // true in those cases to be safe. + else if (child instanceof CallTemplate + || child instanceof ApplyTemplates + || child instanceof Copy + || child instanceof CopyOf) + return true; + else if ((child instanceof If + || child instanceof ForEach) + && canProduceAttributeNodes(child, false)) { + return true; + } + else if (child instanceof Choose) { + Vector chooseContents = child.getContents(); + int num = chooseContents.size(); + for (int k = 0; k < num; k++) { + SyntaxTreeNode chooseChild = (SyntaxTreeNode)chooseContents.elementAt(k); + if (chooseChild instanceof When || chooseChild instanceof Otherwise) { + if (canProduceAttributeNodes(chooseChild, false)) + return true; + } + } + } + } + return false; } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentLocationPath.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/ParentLocationPath.java Wed Sep 28 17:10:18 2011 +0100 @@ -52,58 +52,58 @@ private boolean _axisMismatch = false; public ParentLocationPath(RelativeLocationPath path, Expression step) { - _path = path; - _step = step; - _path.setParent(this); - _step.setParent(this); + _path = path; + _step = step; + _path.setParent(this); + _step.setParent(this); - if (_step instanceof Step) { - _axisMismatch = checkAxisMismatch(); - } + if (_step instanceof Step) { + _axisMismatch = checkAxisMismatch(); + } } - + public void setAxis(int axis) { - _path.setAxis(axis); + _path.setAxis(axis); } public int getAxis() { - return _path.getAxis(); + return _path.getAxis(); } public RelativeLocationPath getPath() { - return(_path); + return(_path); } public Expression getStep() { - return(_step); + return(_step); } public void setParser(Parser parser) { - super.setParser(parser); - _step.setParser(parser); - _path.setParser(parser); + super.setParser(parser); + _step.setParser(parser); + _path.setParser(parser); } - + public String toString() { - return "ParentLocationPath(" + _path + ", " + _step + ')'; + return "ParentLocationPath(" + _path + ", " + _step + ')'; } public Type typeCheck(SymbolTable stable) throws TypeCheckError { - stype = _step.typeCheck(stable); - _path.typeCheck(stable); + stype = _step.typeCheck(stable); + _path.typeCheck(stable); - if (_axisMismatch) enableNodeOrdering(); + if (_axisMismatch) enableNodeOrdering(); - return _type = Type.NodeSet; + return _type = Type.NodeSet; } public void enableNodeOrdering() { - SyntaxTreeNode parent = getParent(); - if (parent instanceof ParentLocationPath) - ((ParentLocationPath)parent).enableNodeOrdering(); - else { - _orderNodes = true; - } + SyntaxTreeNode parent = getParent(); + if (parent instanceof ParentLocationPath) + ((ParentLocationPath)parent).enableNodeOrdering(); + else { + _orderNodes = true; + } } /** @@ -113,62 +113,70 @@ */ public boolean checkAxisMismatch() { - int left = _path.getAxis(); - int right = ((Step)_step).getAxis(); + int left = _path.getAxis(); + int right = ((Step)_step).getAxis(); - if (((left == Axis.ANCESTOR) || (left == Axis.ANCESTORORSELF)) && - ((right == Axis.CHILD) || - (right == Axis.DESCENDANT) || - (right == Axis.DESCENDANTORSELF) || - (right == Axis.PARENT) || - (right == Axis.PRECEDING) || - (right == Axis.PRECEDINGSIBLING))) - return true; + if (((left == Axis.ANCESTOR) || (left == Axis.ANCESTORORSELF)) && + ((right == Axis.CHILD) || + (right == Axis.DESCENDANT) || + (right == Axis.DESCENDANTORSELF) || + (right == Axis.PARENT) || + (right == Axis.PRECEDING) || + (right == Axis.PRECEDINGSIBLING))) + return true; - if ((left == Axis.CHILD) && - (right == Axis.ANCESTOR) || - (right == Axis.ANCESTORORSELF) || - (right == Axis.PARENT) || - (right == Axis.PRECEDING)) - return true; + if ((left == Axis.CHILD) && + (right == Axis.ANCESTOR) || + (right == Axis.ANCESTORORSELF) || + (right == Axis.PARENT) || + (right == Axis.PRECEDING)) + return true; - if ((left == Axis.DESCENDANT) || (left == Axis.DESCENDANTORSELF)) - return true; + if ((left == Axis.DESCENDANT) || (left == Axis.DESCENDANTORSELF)) + return true; - if (((left == Axis.FOLLOWING) || (left == Axis.FOLLOWINGSIBLING)) && - ((right == Axis.FOLLOWING) || - (right == Axis.PARENT) || - (right == Axis.PRECEDING) || - (right == Axis.PRECEDINGSIBLING))) - return true; + if (((left == Axis.FOLLOWING) || (left == Axis.FOLLOWINGSIBLING)) && + ((right == Axis.FOLLOWING) || + (right == Axis.PARENT) || + (right == Axis.PRECEDING) || + (right == Axis.PRECEDINGSIBLING))) + return true; - if (((left == Axis.PRECEDING) || (left == Axis.PRECEDINGSIBLING)) && - ((right == Axis.DESCENDANT) || - (right == Axis.DESCENDANTORSELF) || - (right == Axis.FOLLOWING) || - (right == Axis.FOLLOWINGSIBLING) || - (right == Axis.PARENT) || - (right == Axis.PRECEDING) || - (right == Axis.PRECEDINGSIBLING))) - return true; + if (((left == Axis.PRECEDING) || (left == Axis.PRECEDINGSIBLING)) && + ((right == Axis.DESCENDANT) || + (right == Axis.DESCENDANTORSELF) || + (right == Axis.FOLLOWING) || + (right == Axis.FOLLOWINGSIBLING) || + (right == Axis.PARENT) || + (right == Axis.PRECEDING) || + (right == Axis.PRECEDINGSIBLING))) + return true; - if ((right == Axis.FOLLOWING) && (left == Axis.CHILD)) { - // Special case for '@*/following::*' expressions. The resulting - // iterator is initialised with the parent's first child, and this - // can cause duplicates in the output if the parent has more than - // one attribute that matches the left step. - if (_path instanceof Step) { - int type = ((Step)_path).getNodeType(); - if (type == DTM.ATTRIBUTE_NODE) return true; - } - } + if ((right == Axis.FOLLOWING) && (left == Axis.CHILD)) { + // Special case for '@*/following::*' expressions. The resulting + // iterator is initialised with the parent's first child, and this + // can cause duplicates in the output if the parent has more than + // one attribute that matches the left step. + if (_path instanceof Step) { + int type = ((Step)_path).getNodeType(); + if (type == DTM.ATTRIBUTE_NODE) return true; + } + } - return false; + return false; } public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); + + // Compile path iterator + _path.translate(classGen, methodGen); // iterator on stack.... + + translateStep(classGen, methodGen); + } + + public void translateStep(ClassGenerator classGen, MethodGenerator methodGen) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); // Backwards branches are prohibited if an uninitialized object is // on the stack by section 4.9.4 of the JVM Specification, 2nd Ed. @@ -179,68 +187,66 @@ // in temporary variables, create the object and reload the // arguments from the temporaries to avoid the problem. - // Compile path iterator - _path.translate(classGen, methodGen); // iterator on stack.... LocalVariableGen pathTemp = methodGen.addLocalVariable("parent_location_path_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), il.getEnd(), null); il.append(new ASTORE(pathTemp.getIndex())); - _step.translate(classGen, methodGen); + _step.translate(classGen, methodGen); LocalVariableGen stepTemp = methodGen.addLocalVariable("parent_location_path_tmp2", Util.getJCRefType(NODE_ITERATOR_SIG), il.getEnd(), null); il.append(new ASTORE(stepTemp.getIndex())); - // Create new StepIterator - final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS, - "<init>", - "(" - +NODE_ITERATOR_SIG - +NODE_ITERATOR_SIG - +")V"); - il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); - il.append(DUP); + // Create new StepIterator + final int initSI = cpg.addMethodref(STEP_ITERATOR_CLASS, + "<init>", + "(" + +NODE_ITERATOR_SIG + +NODE_ITERATOR_SIG + +")V"); + il.append(new NEW(cpg.addClass(STEP_ITERATOR_CLASS))); + il.append(DUP); il.append(new ALOAD(pathTemp.getIndex())); il.append(new ALOAD(stepTemp.getIndex())); - // Initialize StepIterator with iterators from the stack - il.append(new INVOKESPECIAL(initSI)); + // Initialize StepIterator with iterators from the stack + il.append(new INVOKESPECIAL(initSI)); - // This is a special case for the //* path with or without predicates - Expression stp = _step; - if (stp instanceof ParentLocationPath) - stp = ((ParentLocationPath)stp).getStep(); + // This is a special case for the //* path with or without predicates + Expression stp = _step; + if (stp instanceof ParentLocationPath) + stp = ((ParentLocationPath)stp).getStep(); - if ((_path instanceof Step) && (stp instanceof Step)) { - final int path = ((Step)_path).getAxis(); - final int step = ((Step)stp).getAxis(); - if ((path == Axis.DESCENDANTORSELF && step == Axis.CHILD) || - (path == Axis.PRECEDING && step == Axis.PARENT)) { - final int incl = cpg.addMethodref(NODE_ITERATOR_BASE, - "includeSelf", - "()" + NODE_ITERATOR_SIG); - il.append(new INVOKEVIRTUAL(incl)); - } - } + if ((_path instanceof Step) && (stp instanceof Step)) { + final int path = ((Step)_path).getAxis(); + final int step = ((Step)stp).getAxis(); + if ((path == Axis.DESCENDANTORSELF && step == Axis.CHILD) || + (path == Axis.PRECEDING && step == Axis.PARENT)) { + final int incl = cpg.addMethodref(NODE_ITERATOR_BASE, + "includeSelf", + "()" + NODE_ITERATOR_SIG); + il.append(new INVOKEVIRTUAL(incl)); + } + } - /* - * If this pattern contains a sequence of descendant iterators we - * run the risk of returning the same node several times. We put - * a new iterator on top of the existing one to assure node order - * and prevent returning a single node multiple times. - */ - if (_orderNodes) { - final int order = cpg.addInterfaceMethodref(DOM_INTF, - ORDER_ITERATOR, - ORDER_ITERATOR_SIG); - il.append(methodGen.loadDOM()); - il.append(SWAP); - il.append(methodGen.loadContextNode()); - il.append(new INVOKEINTERFACE(order, 3)); - } + /* + * If this pattern contains a sequence of descendant iterators we + * run the risk of returning the same node several times. We put + * a new iterator on top of the existing one to assure node order + * and prevent returning a single node multiple times. + */ + if (_orderNodes) { + final int order = cpg.addInterfaceMethodref(DOM_INTF, + ORDER_ITERATOR, + ORDER_ITERATOR_SIG); + il.append(methodGen.loadDOM()); + il.append(SWAP); + il.append(methodGen.loadContextNode()); + il.append(new INVOKEINTERFACE(order, 3)); + } } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/QName.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/QName.java Wed Sep 28 17:10:18 2011 +0100 @@ -36,51 +36,52 @@ private int _hashCode; public QName(String namespace, String prefix, String localname) { - _namespace = namespace; - _prefix = prefix; - _localname = localname; + _namespace = namespace; + _prefix = prefix; + _localname = localname; - _stringRep = - (namespace != null && !namespace.equals(Constants.EMPTYSTRING)) ? - (namespace + ':' + localname) : localname; + _stringRep = + (namespace != null && !namespace.equals(Constants.EMPTYSTRING)) ? + (namespace + ':' + localname) : localname; - _hashCode = _stringRep.hashCode() + 19; // cached for speed + _hashCode = _stringRep.hashCode() + 19; // cached for speed } public void clearNamespace() { - _namespace = Constants.EMPTYSTRING; + _namespace = Constants.EMPTYSTRING; } public String toString() { - return _stringRep; + return _stringRep; } public String getStringRep() { - return _stringRep; + return _stringRep; } public boolean equals(Object other) { - return (this == other); + return (this == other) + || (other instanceof QName + && _stringRep.equals(((QName) other).getStringRep())); } public String getLocalPart() { - return _localname; + return _localname; } public String getNamespace() { - return _namespace; + return _namespace; } public String getPrefix() { - return _prefix; + return _prefix; } public int hashCode() { - return _hashCode; + return _hashCode; } public String dump() { - return new String("QName: " + _namespace + "(" + _prefix + "):" - + _localname); + return "QName: " + _namespace + "(" + _prefix + "):" + _localname; } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Step.java Wed Sep 28 17:10:18 2011 +0100 @@ -77,64 +77,64 @@ private int _nodeType; public Step(int axis, int nodeType, Vector predicates) { - _axis = axis; - _nodeType = nodeType; - _predicates = predicates; + _axis = axis; + _nodeType = nodeType; + _predicates = predicates; } /** * Set the parser for this element and all child predicates */ public void setParser(Parser parser) { - super.setParser(parser); - if (_predicates != null) { - final int n = _predicates.size(); - for (int i = 0; i < n; i++) { - final Predicate exp = (Predicate)_predicates.elementAt(i); - exp.setParser(parser); - exp.setParent(this); - } - } + super.setParser(parser); + if (_predicates != null) { + final int n = _predicates.size(); + for (int i = 0; i < n; i++) { + final Predicate exp = (Predicate)_predicates.elementAt(i); + exp.setParser(parser); + exp.setParent(this); + } + } } - + /** * Define the axis (defined in Axis class) for this step */ public int getAxis() { - return _axis; + return _axis; } - + /** * Get the axis (defined in Axis class) for this step */ public void setAxis(int axis) { - _axis = axis; + _axis = axis; } /** * Returns the node-type for this step */ public int getNodeType() { - return _nodeType; + return _nodeType; } /** * Returns the vector containing all predicates for this step. */ public Vector getPredicates() { - return _predicates; + return _predicates; } /** * Returns the vector containing all predicates for this step. */ public void addPredicates(Vector predicates) { - if (_predicates == null) { - _predicates = predicates; - } - else { - _predicates.addAll(predicates); - } + if (_predicates == null) { + _predicates = predicates; + } + else { + _predicates.addAll(predicates); + } } /** @@ -143,44 +143,44 @@ * an element like <xsl:for-each> or <xsl:apply-templates>. */ private boolean hasParentPattern() { - final SyntaxTreeNode parent = getParent(); - return (parent instanceof ParentPattern || - parent instanceof ParentLocationPath || - parent instanceof UnionPathExpr || - parent instanceof FilterParentPath); + final SyntaxTreeNode parent = getParent(); + return (parent instanceof ParentPattern || + parent instanceof ParentLocationPath || + parent instanceof UnionPathExpr || + parent instanceof FilterParentPath); } - + /** * Returns 'true' if this step has a parent location path. */ private boolean hasParentLocationPath() { - return getParent() instanceof ParentLocationPath; + return getParent() instanceof ParentLocationPath; } - + /** * Returns 'true' if this step has any predicates */ private boolean hasPredicates() { - return _predicates != null && _predicates.size() > 0; + return _predicates != null && _predicates.size() > 0; } /** * Returns 'true' if this step is used within a predicate */ private boolean isPredicate() { - SyntaxTreeNode parent = this; - while (parent != null) { - parent = parent.getParent(); - if (parent instanceof Predicate) return true; - } - return false; + SyntaxTreeNode parent = this; + while (parent != null) { + parent = parent.getParent(); + if (parent instanceof Predicate) return true; + } + return false; } /** * True if this step is the abbreviated step '.' */ public boolean isAbbreviatedDot() { - return _nodeType == NodeTest.ANODE && _axis == Axis.SELF; + return _nodeType == NodeTest.ANODE && _axis == Axis.SELF; } @@ -188,42 +188,42 @@ * True if this step is the abbreviated step '..' */ public boolean isAbbreviatedDDot() { - return _nodeType == NodeTest.ANODE && _axis == Axis.PARENT; + return _nodeType == NodeTest.ANODE && _axis == Axis.PARENT; } /** * Type check this step. The abbreviated steps '.' and '@attr' are - * assigned type node if they have no predicates. All other steps + * assigned type node if they have no predicates. All other steps * have type node-set. */ public Type typeCheck(SymbolTable stable) throws TypeCheckError { - // Save this value for later - important for testing for special - // combinations of steps and patterns than can be optimised - _hadPredicates = hasPredicates(); + // Save this value for later - important for testing for special + // combinations of steps and patterns than can be optimised + _hadPredicates = hasPredicates(); - // Special case for '.' - // in the case where '.' has a context such as book/. - // or .[false()] we can not optimize the nodeset to a single node. - if (isAbbreviatedDot()) { - _type = (hasParentPattern() || hasPredicates() || hasParentLocationPath()) ? - Type.NodeSet : Type.Node; - } - else { - _type = Type.NodeSet; - } + // Special case for '.' + // in the case where '.' has a context such as book/. + // or .[false()] we can not optimize the nodeset to a single node. + if (isAbbreviatedDot()) { + _type = (hasParentPattern() || hasPredicates() || hasParentLocationPath()) ? + Type.NodeSet : Type.Node; + } + else { + _type = Type.NodeSet; + } - // Type check all predicates (expressions applied to the step) - if (_predicates != null) { - final int n = _predicates.size(); - for (int i = 0; i < n; i++) { - final Expression pred = (Expression)_predicates.elementAt(i); - pred.typeCheck(stable); - } - } + // Type check all predicates (expressions applied to the step) + if (_predicates != null) { + final int n = _predicates.size(); + for (int i = 0; i < n; i++) { + final Expression pred = (Expression)_predicates.elementAt(i); + pred.typeCheck(stable); + } + } - // Return either Type.Node or Type.NodeSet - return _type; + // Return either Type.Node or Type.NodeSet + return _type; } /** @@ -234,122 +234,128 @@ * onto the stack. */ public void translate(ClassGenerator classGen, MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); + translateStep(classGen, methodGen, hasPredicates() ? _predicates.size() - 1 : -1); + } - if (hasPredicates()) { - translatePredicates(classGen, methodGen); - } else { + private void translateStep(ClassGenerator classGen, + MethodGenerator methodGen, + int predicateIndex) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); + + if (predicateIndex >= 0) { + translatePredicates(classGen, methodGen, predicateIndex); + } else { int star = 0; String name = null; final XSLTC xsltc = getParser().getXSLTC(); if (_nodeType >= DTM.NTYPES) { - final Vector ni = xsltc.getNamesIndex(); - + final Vector ni = xsltc.getNamesIndex(); + name = (String)ni.elementAt(_nodeType-DTM.NTYPES); star = name.lastIndexOf('*'); } - // If it is an attribute, but not '@*', '@pre:*' or '@node()', + // If it is an attribute, but not '@*', '@pre:*' or '@node()', // and has no parent - if (_axis == Axis.ATTRIBUTE && _nodeType != NodeTest.ATTRIBUTE - && _nodeType != NodeTest.ANODE && !hasParentPattern() + if (_axis == Axis.ATTRIBUTE && _nodeType != NodeTest.ATTRIBUTE + && _nodeType != NodeTest.ANODE && !hasParentPattern() && star == 0) - { - int iter = cpg.addInterfaceMethodref(DOM_INTF, - "getTypedAxisIterator", - "(II)"+NODE_ITERATOR_SIG); - il.append(methodGen.loadDOM()); - il.append(new PUSH(cpg, Axis.ATTRIBUTE)); - il.append(new PUSH(cpg, _nodeType)); - il.append(new INVOKEINTERFACE(iter, 3)); - return; - } + { + int iter = cpg.addInterfaceMethodref(DOM_INTF, + "getTypedAxisIterator", + "(II)"+NODE_ITERATOR_SIG); + il.append(methodGen.loadDOM()); + il.append(new PUSH(cpg, Axis.ATTRIBUTE)); + il.append(new PUSH(cpg, _nodeType)); + il.append(new INVOKEINTERFACE(iter, 3)); + return; + } - SyntaxTreeNode parent = getParent(); - // Special case for '.' - if (isAbbreviatedDot()) { - if (_type == Type.Node) { - // Put context node on stack if using Type.Node - il.append(methodGen.loadContextNode()); - } - else { - if (parent instanceof ParentLocationPath){ - // Wrap the context node in a singleton iterator if not. - int init = cpg.addMethodref(SINGLETON_ITERATOR, - "<init>", - "("+NODE_SIG+")V"); - il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR))); - il.append(DUP); - il.append(methodGen.loadContextNode()); - il.append(new INVOKESPECIAL(init)); - } else { - // DOM.getAxisIterator(int axis); - int git = cpg.addInterfaceMethodref(DOM_INTF, - "getAxisIterator", - "(I)"+NODE_ITERATOR_SIG); - il.append(methodGen.loadDOM()); - il.append(new PUSH(cpg, _axis)); - il.append(new INVOKEINTERFACE(git, 2)); - } - } - return; - } + SyntaxTreeNode parent = getParent(); + // Special case for '.' + if (isAbbreviatedDot()) { + if (_type == Type.Node) { + // Put context node on stack if using Type.Node + il.append(methodGen.loadContextNode()); + } + else { + if (parent instanceof ParentLocationPath){ + // Wrap the context node in a singleton iterator if not. + int init = cpg.addMethodref(SINGLETON_ITERATOR, + "<init>", + "("+NODE_SIG+")V"); + il.append(new NEW(cpg.addClass(SINGLETON_ITERATOR))); + il.append(DUP); + il.append(methodGen.loadContextNode()); + il.append(new INVOKESPECIAL(init)); + } else { + // DOM.getAxisIterator(int axis); + int git = cpg.addInterfaceMethodref(DOM_INTF, + "getAxisIterator", + "(I)"+NODE_ITERATOR_SIG); + il.append(methodGen.loadDOM()); + il.append(new PUSH(cpg, _axis)); + il.append(new INVOKEINTERFACE(git, 2)); + } + } + return; + } - // Special case for /foo/*/bar - if ((parent instanceof ParentLocationPath) && - (parent.getParent() instanceof ParentLocationPath)) { - if ((_nodeType == NodeTest.ELEMENT) && (!_hadPredicates)) { - _nodeType = NodeTest.ANODE; - } - } + // Special case for /foo/*/bar + if ((parent instanceof ParentLocationPath) && + (parent.getParent() instanceof ParentLocationPath)) { + if ((_nodeType == NodeTest.ELEMENT) && (!_hadPredicates)) { + _nodeType = NodeTest.ANODE; + } + } - // "ELEMENT" or "*" or "@*" or ".." or "@attr" with a parent. - switch (_nodeType) { - case NodeTest.ATTRIBUTE: - _axis = Axis.ATTRIBUTE; - case NodeTest.ANODE: - // DOM.getAxisIterator(int axis); - int git = cpg.addInterfaceMethodref(DOM_INTF, - "getAxisIterator", - "(I)"+NODE_ITERATOR_SIG); - il.append(methodGen.loadDOM()); - il.append(new PUSH(cpg, _axis)); - il.append(new INVOKEINTERFACE(git, 2)); - break; - default: - if (star > 1) { - final String namespace; - if (_axis == Axis.ATTRIBUTE) - namespace = name.substring(0,star-2); - else - namespace = name.substring(0,star-1); + // "ELEMENT" or "*" or "@*" or ".." or "@attr" with a parent. + switch (_nodeType) { + case NodeTest.ATTRIBUTE: + _axis = Axis.ATTRIBUTE; + case NodeTest.ANODE: + // DOM.getAxisIterator(int axis); + int git = cpg.addInterfaceMethodref(DOM_INTF, + "getAxisIterator", + "(I)"+NODE_ITERATOR_SIG); + il.append(methodGen.loadDOM()); + il.append(new PUSH(cpg, _axis)); + il.append(new INVOKEINTERFACE(git, 2)); + break; + default: + if (star > 1) { + final String namespace; + if (_axis == Axis.ATTRIBUTE) + namespace = name.substring(0,star-2); + else + namespace = name.substring(0,star-1); - final int nsType = xsltc.registerNamespace(namespace); - final int ns = cpg.addInterfaceMethodref(DOM_INTF, - "getNamespaceAxisIterator", - "(II)"+NODE_ITERATOR_SIG); - il.append(methodGen.loadDOM()); - il.append(new PUSH(cpg, _axis)); - il.append(new PUSH(cpg, nsType)); - il.append(new INVOKEINTERFACE(ns, 3)); - break; - } - case NodeTest.ELEMENT: - // DOM.getTypedAxisIterator(int axis, int type); - final int ty = cpg.addInterfaceMethodref(DOM_INTF, - "getTypedAxisIterator", - "(II)"+NODE_ITERATOR_SIG); - // Get the typed iterator we're after - il.append(methodGen.loadDOM()); - il.append(new PUSH(cpg, _axis)); - il.append(new PUSH(cpg, _nodeType)); - il.append(new INVOKEINTERFACE(ty, 3)); + final int nsType = xsltc.registerNamespace(namespace); + final int ns = cpg.addInterfaceMethodref(DOM_INTF, + "getNamespaceAxisIterator", + "(II)"+NODE_ITERATOR_SIG); + il.append(methodGen.loadDOM()); + il.append(new PUSH(cpg, _axis)); + il.append(new PUSH(cpg, nsType)); + il.append(new INVOKEINTERFACE(ns, 3)); + break; + } + case NodeTest.ELEMENT: + // DOM.getTypedAxisIterator(int axis, int type); + final int ty = cpg.addInterfaceMethodref(DOM_INTF, + "getTypedAxisIterator", + "(II)"+NODE_ITERATOR_SIG); + // Get the typed iterator we're after + il.append(methodGen.loadDOM()); + il.append(new PUSH(cpg, _axis)); + il.append(new PUSH(cpg, _nodeType)); + il.append(new INVOKEINTERFACE(ty, 3)); - break; - } - } + break; + } + } } @@ -357,75 +363,76 @@ * Translate a sequence of predicates. Each predicate is translated * by constructing an instance of <code>CurrentNodeListIterator</code> * which is initialized from another iterator (recursive call), - * a filter and a closure (call to translate on the predicate) and "this". + * a filter and a closure (call to translate on the predicate) and "this". */ public void translatePredicates(ClassGenerator classGen, - MethodGenerator methodGen) { - final ConstantPoolGen cpg = classGen.getConstantPool(); - final InstructionList il = methodGen.getInstructionList(); + MethodGenerator methodGen, + int predicateIndex) { + final ConstantPoolGen cpg = classGen.getConstantPool(); + final InstructionList il = methodGen.getInstructionList(); - int idx = 0; + int idx = 0; - if (_predicates.size() == 0) { - translate(classGen, methodGen); - } - else { - final Predicate predicate = (Predicate)_predicates.lastElement(); - _predicates.remove(predicate); + if (predicateIndex < 0) { + translateStep(classGen, methodGen, predicateIndex); + } + else { + final Predicate predicate = (Predicate) _predicates.get(predicateIndex--); - // Special case for predicates that can use the NodeValueIterator - // instead of an auxiliary class. Certain path/predicates pairs - // are translated into a base path, on top of which we place a - // node value iterator that tests for the desired value: - // foo[@attr = 'str'] -> foo/@attr + test(value='str') - // foo[bar = 'str'] -> foo/bar + test(value='str') - // foo/bar[. = 'str'] -> foo/bar + test(value='str') - if (predicate.isNodeValueTest()) { - Step step = predicate.getStep(); + // Special case for predicates that can use the NodeValueIterator + // instead of an auxiliary class. Certain path/predicates pairs + // are translated into a base path, on top of which we place a + // node value iterator that tests for the desired value: + // foo[@attr = 'str'] -> foo/@attr + test(value='str') + // foo[bar = 'str'] -> foo/bar + test(value='str') + // foo/bar[. = 'str'] -> foo/bar + test(value='str') + if (predicate.isNodeValueTest()) { + Step step = predicate.getStep(); - il.append(methodGen.loadDOM()); - // If the predicate's Step is simply '.' we translate this Step - // and place the node test on top of the resulting iterator - if (step.isAbbreviatedDot()) { - translate(classGen, methodGen); - il.append(new ICONST(DOM.RETURN_CURRENT)); - } - // Otherwise we create a parent location path with this Step and - // the predicates Step, and place the node test on top of that - else { - ParentLocationPath path = new ParentLocationPath(this, step); + il.append(methodGen.loadDOM()); + // If the predicate's Step is simply '.' we translate this Step + // and place the node test on top of the resulting iterator + if (step.isAbbreviatedDot()) { + translateStep(classGen, methodGen, predicateIndex); + il.append(new ICONST(DOM.RETURN_CURRENT)); + } + // Otherwise we create a parent location path with this Step and + // the predicates Step, and place the node test on top of that + else { + ParentLocationPath path = new ParentLocationPath(this, step); _parent = step._parent = path; // Force re-parenting - - try { - path.typeCheck(getParser().getSymbolTable()); - } - catch (TypeCheckError e) { } - path.translate(classGen, methodGen); - il.append(new ICONST(DOM.RETURN_PARENT)); - } - predicate.translate(classGen, methodGen); - idx = cpg.addInterfaceMethodref(DOM_INTF, - GET_NODE_VALUE_ITERATOR, - GET_NODE_VALUE_ITERATOR_SIG); - il.append(new INVOKEINTERFACE(idx, 5)); - } - // Handle '//*[n]' expression - else if (predicate.isNthDescendant()) { - il.append(methodGen.loadDOM()); - // il.append(new ICONST(NodeTest.ELEMENT)); + + try { + path.typeCheck(getParser().getSymbolTable()); + } + catch (TypeCheckError e) { } + translateStep(classGen, methodGen, predicateIndex); + path.translateStep(classGen, methodGen); + il.append(new ICONST(DOM.RETURN_PARENT)); + } + predicate.translate(classGen, methodGen); + idx = cpg.addInterfaceMethodref(DOM_INTF, + GET_NODE_VALUE_ITERATOR, + GET_NODE_VALUE_ITERATOR_SIG); + il.append(new INVOKEINTERFACE(idx, 5)); + } + // Handle '//*[n]' expression + else if (predicate.isNthDescendant()) { + il.append(methodGen.loadDOM()); + // il.append(new ICONST(NodeTest.ELEMENT)); il.append(new PUSH(cpg, predicate.getPosType())); - predicate.translate(classGen, methodGen); - il.append(new ICONST(0)); - idx = cpg.addInterfaceMethodref(DOM_INTF, - "getNthDescendant", - "(IIZ)"+NODE_ITERATOR_SIG); - il.append(new INVOKEINTERFACE(idx, 4)); - } - // Handle 'elem[n]' expression - else if (predicate.isNthPositionFilter()) { - idx = cpg.addMethodref(NTH_ITERATOR_CLASS, - "<init>", - "("+NODE_ITERATOR_SIG+"I)V"); + predicate.translate(classGen, methodGen); + il.append(new ICONST(0)); + idx = cpg.addInterfaceMethodref(DOM_INTF, + "getNthDescendant", + "(IIZ)"+NODE_ITERATOR_SIG); + il.append(new INVOKEINTERFACE(idx, 4)); + } + // Handle 'elem[n]' expression + else if (predicate.isNthPositionFilter()) { + idx = cpg.addMethodref(NTH_ITERATOR_CLASS, + "<init>", + "("+NODE_ITERATOR_SIG+"I)V"); // Backwards branches are prohibited if an uninitialized object // is on the stack by section 4.9.4 of the JVM Specification, @@ -436,35 +443,35 @@ // constructor first, store them in temporary variables, create // the object and reload the arguments from the temporaries to // avoid the problem. - translatePredicates(classGen, methodGen); // recursive call + translatePredicates(classGen, methodGen, predicateIndex); // recursive call LocalVariableGen iteratorTemp = methodGen.addLocalVariable("step_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), il.getEnd(), null); il.append(new ASTORE(iteratorTemp.getIndex())); - predicate.translate(classGen, methodGen); + predicate.translate(classGen, methodGen); LocalVariableGen predicateValueTemp = methodGen.addLocalVariable("step_tmp2", Util.getJCRefType("I"), il.getEnd(), null); il.append(new ISTORE(predicateValueTemp.getIndex())); - il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS))); - il.append(DUP); + il.append(new NEW(cpg.addClass(NTH_ITERATOR_CLASS))); + il.append(DUP); il.append(new ALOAD(iteratorTemp.getIndex())); il.append(new ILOAD(predicateValueTemp.getIndex())); - il.append(new INVOKESPECIAL(idx)); - } - else { - idx = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, - "<init>", - "(" - + NODE_ITERATOR_SIG - + CURRENT_NODE_LIST_FILTER_SIG - + NODE_SIG - + TRANSLET_SIG - + ")V"); + il.append(new INVOKESPECIAL(idx)); + } + else { + idx = cpg.addMethodref(CURRENT_NODE_LIST_ITERATOR, + "<init>", + "(" + + NODE_ITERATOR_SIG + + CURRENT_NODE_LIST_FILTER_SIG + + NODE_SIG + + TRANSLET_SIG + + ")V"); // Backwards branches are prohibited if an uninitialized object // is on the stack by section 4.9.4 of the JVM Specification, @@ -475,51 +482,51 @@ // constructor first, store them in temporary variables, create // the object and reload the arguments from the temporaries to // avoid the problem. - translatePredicates(classGen, methodGen); // recursive call + translatePredicates(classGen, methodGen, predicateIndex); // recursive call LocalVariableGen iteratorTemp = methodGen.addLocalVariable("step_tmp1", Util.getJCRefType(NODE_ITERATOR_SIG), il.getEnd(), null); il.append(new ASTORE(iteratorTemp.getIndex())); - predicate.translateFilter(classGen, methodGen); + predicate.translateFilter(classGen, methodGen); LocalVariableGen filterTemp = methodGen.addLocalVariable("step_tmp2", Util.getJCRefType(CURRENT_NODE_LIST_FILTER_SIG), il.getEnd(), null); il.append(new ASTORE(filterTemp.getIndex())); - // create new CurrentNodeListIterator - il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); - il.append(DUP); + // create new CurrentNodeListIterator + il.append(new NEW(cpg.addClass(CURRENT_NODE_LIST_ITERATOR))); + il.append(DUP); il.append(new ALOAD(iteratorTemp.getIndex())); il.append(new ALOAD(filterTemp.getIndex())); - - il.append(methodGen.loadCurrentNode()); - il.append(classGen.loadTranslet()); - if (classGen.isExternal()) { - final String className = classGen.getClassName(); - il.append(new CHECKCAST(cpg.addClass(className))); - } - il.append(new INVOKESPECIAL(idx)); - } - } + + il.append(methodGen.loadCurrentNode()); + il.append(classGen.loadTranslet()); + if (classGen.isExternal()) { + final String className = classGen.getClassName(); + il.append(new CHECKCAST(cpg.addClass(className))); + } + il.append(new INVOKESPECIAL(idx)); + } + } } /** * Returns a string representation of this step. */ public String toString() { - final StringBuffer buffer = new StringBuffer("step(\""); + final StringBuffer buffer = new StringBuffer("step(\""); buffer.append(Axis.getNames(_axis)).append("\", ").append(_nodeType); - if (_predicates != null) { - final int n = _predicates.size(); - for (int i = 0; i < n; i++) { - final Predicate pred = (Predicate)_predicates.elementAt(i); - buffer.append(", ").append(pred.toString()); - } - } - return buffer.append(')').toString(); + if (_predicates != null) { + final int n = _predicates.size(); + for (int i = 0; i < n; i++) { + final Predicate pred = (Predicate)_predicates.elementAt(i); + buffer.append(", ").append(pred.toString()); + } + } + return buffer.append(')').toString(); } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/xpath.cup Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/xpath.cup Wed Sep 28 17:10:18 2011 +0100 @@ -86,11 +86,11 @@ public QName getQNameIgnoreDefaultNs(String name) { return _parser.getQNameIgnoreDefaultNs(name); - } + } public QName getQName(String namespace, String prefix, String localname) { return _parser.getQName(namespace, prefix, localname); - } + } public void setMultiDocument(boolean flag) { _xsltc.setMultiDocument(flag); @@ -101,16 +101,16 @@ } public void setHasIdCall(boolean flag) { - _xsltc.setHasIdCall(flag); + _xsltc.setHasIdCall(flag); } - + /** * This method is similar to findNodeType(int, Object) except that it - * creates a StepPattern instead of just returning a node type. It also - * differs in the way it handles "{uri}:*" and "{uri}:@*". The last two - * patterns are expanded as "*[namespace-uri() = 'uri']" and - * "@*[namespace-uri() = 'uri']", respectively. This expansion considerably + * creates a StepPattern instead of just returning a node type. It also + * differs in the way it handles "{uri}:*" and "{uri}:@*". The last two + * patterns are expanded as "*[namespace-uri() = 'uri']" and + * "@*[namespace-uri() = 'uri']", respectively. This expansion considerably * simplifies the grouping of patterns in the Mode class. For this * expansion to be correct, the priority of the pattern/template must be * set to -0.25 (when no other predicates are present). @@ -119,7 +119,7 @@ int nodeType; if (test == null) { // "*" - nodeType = (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE : + nodeType = (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE : (axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT; return new StepPattern(axis, nodeType, predicates); @@ -140,7 +140,7 @@ else { final String uri = name.getNamespace(); final String local = name.getLocalPart(); - final QName namespace_uri = + final QName namespace_uri = _parser.getQNameIgnoreDefaultNs("namespace-uri"); // Expand {uri}:* to *[namespace-uri() = 'uri'] - same for @* @@ -154,8 +154,8 @@ predicates.add( new Predicate( - new EqualityExpr(Operators.EQ, - new NamespaceUriCall(namespace_uri), + new EqualityExpr(Operators.EQ, + new NamespaceUriCall(namespace_uri), new LiteralExpr(uri)))); } @@ -168,11 +168,11 @@ } else { nodeType = (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name) - : _xsltc.registerElement(name); + : _xsltc.registerElement(name); } } - final StepPattern result = new StepPattern(axis, nodeType, predicates); + final StepPattern result = new StepPattern(axis, nodeType, predicates); // Set priority for case prefix:* and prefix:@* (no predicates) if (setPriority) { @@ -185,7 +185,7 @@ public int findNodeType(int axis, Object test) { if (test == null) { // * - return (axis == Axis.ATTRIBUTE) ? + return (axis == Axis.ATTRIBUTE) ? NodeTest.ATTRIBUTE : (axis == Axis.NAMESPACE) ? -1 : NodeTest.ELEMENT; } @@ -213,20 +213,20 @@ } return (axis == Axis.ATTRIBUTE) ? _xsltc.registerAttribute(name) - : _xsltc.registerElement(name); + : _xsltc.registerElement(name); } } /** * Parse the expression passed to the current scanner. If this - * expression contains references to local variables and it will be - * compiled in an external module (not in the main class) request + * expression contains references to local variables and it will be + * compiled in an external module (not in the main class) request * the current template to create a new variable stack frame. * * @param lineNumber Line where the current expression is defined. * @param external Set to <tt>true</tt> if this expression is * compiled in a separate module. - * + * */ public Symbol parse(String expression, int lineNumber) throws Exception { try { @@ -243,7 +243,7 @@ } /** - * Lookup a variable or parameter in the symbol table given its name. + * Lookup a variable or parameter in the symbol table given its name. * * @param name Name of the symbol being looked up. */ @@ -258,10 +258,10 @@ public final void addError(ErrorMsg error) { _parser.reportError(Constants.ERROR, error); - } - + } + public void report_error(String message, Object info) { - final ErrorMsg err = new ErrorMsg(ErrorMsg.SYNTAX_ERR, _lineNumber, + final ErrorMsg err = new ErrorMsg(ErrorMsg.SYNTAX_ERR, _lineNumber, _expression); _parser.reportError(Constants.FATAL, err); } @@ -269,7 +269,7 @@ public void report_fatal_error(String message, Object info) { // empty } - + public RelativeLocationPath insertStep(Step step, RelativeLocationPath rlp) { if (rlp instanceof Step) { return new ParentLocationPath(step, (Step) rlp); @@ -301,18 +301,18 @@ terminal DDOT, DCOLON, DSLASH; terminal EQ, NE; terminal LT, GT, LE, GE; -terminal PLUS, MINUS, DIV, MOD; +terminal PLUS, MINUS, DIV, MOD, MULT; terminal String Literal; terminal String QNAME; terminal ID, KEY, TEXT, NODE, OR, AND, COMMENT, PI, PIPARAM, PRECEDINGSIBLING; -terminal SELF, PARENT, CHILD, ATTRIBUTE, ANCESTOR, ANCESTORORSELF, DESCENDANT; +terminal SELF, PARENT, CHILD, ATTRIBUTE, ANCESTOR, ANCESTORORSELF, DESCENDANT; terminal DESCENDANTORSELF, FOLLOWING, FOLLOWINGSIBLING, NAMESPACE, PRECEDING; terminal Double REAL; terminal Long INT; terminal PATTERN, EXPRESSION; non terminal SyntaxTreeNode TopLevel; - + non terminal Expression Expr, Argument, LocationPath; non terminal Expression Predicate, FilterExpr, Step; non terminal Expression OrExpr, AndExpr, EqualityExpr; @@ -343,9 +343,9 @@ precedence left AND; precedence nonassoc EQ, NE; precedence left LT, GT, LE, GE; - + precedence left PLUS, MINUS; -precedence left DIV, MOD, STAR; +precedence left DIV, MOD, MULT; precedence left DOLLAR; precedence left ATSIGN; precedence right DCOLON; @@ -408,12 +408,12 @@ {: RESULT = new AncestorPattern(sp, rpp); :}; StepPattern ::= NodeTestPattern:nt - {: + {: RESULT = parser.createStepPattern(Axis.CHILD, nt, null); :} | NodeTestPattern:nt Predicates:pp - {: + {: RESULT = parser.createStepPattern(Axis.CHILD, nt, pp); :} @@ -424,33 +424,33 @@ {: RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); :} | ChildOrAttributeAxisSpecifier:axis NodeTestPattern:nt - {: + {: RESULT = parser.createStepPattern(axis.intValue(), nt, null); :} | ChildOrAttributeAxisSpecifier:axis NodeTestPattern:nt Predicates:pp - {: + {: RESULT = parser.createStepPattern(axis.intValue(), nt, pp); :} | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip - {: + {: RESULT = pip; // TODO: report error if axis is attribute :} - | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip + | ChildOrAttributeAxisSpecifier:axis ProcessingInstructionPattern:pip Predicates:pp - {: - // TODO: report error if axis is attribute - RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); + {: + // TODO: report error if axis is attribute + RESULT = (ProcessingInstructionPattern)pip.setPredicates(pp); :}; NodeTestPattern ::= NameTestPattern:nt {: RESULT = nt; :} | NODE - {: RESULT = new Integer(NodeTest.ANODE); :} + {: RESULT = new Integer(NodeTest.ANODE); :} | TEXT {: RESULT = new Integer(NodeTest.TEXT); :} @@ -477,14 +477,14 @@ {: RESULT = new Integer(Axis.ATTRIBUTE); :}; Predicates ::= Predicate:p - {: + {: Vector temp = new Vector(); temp.addElement(p); - RESULT = temp; + RESULT = temp; :} | Predicate:p Predicates:pp - {: pp.insertElementAt(p, 0); RESULT = pp; :}; + {: pp.insertElementAt(p, 0); RESULT = pp; :}; Predicate ::= LBRACK Expr:e RBRACK {: @@ -507,7 +507,7 @@ | AndExpr:ae AND EqualityExpr:ee {: RESULT = new LogicalExpr(LogicalExpr.AND, ae, ee); :}; - + EqualityExpr ::= RelationalExpr:re {: RESULT = re; :} @@ -544,7 +544,7 @@ MultiplicativeExpr ::= UnaryExpr:ue {: RESULT = ue; :} - | MultiplicativeExpr:me STAR UnaryExpr:ue + | MultiplicativeExpr:me MULT UnaryExpr:ue {: RESULT = new BinOpExpr(BinOpExpr.TIMES, me, ue); :} | MultiplicativeExpr:me DIV UnaryExpr:ue @@ -561,7 +561,7 @@ UnionExpr ::= PathExpr:pe {: RESULT = pe; :} - + | PathExpr:pe VBAR UnionExpr:rest {: RESULT = new UnionPathExpr(pe, rest); :}; @@ -576,13 +576,13 @@ | FilterExpr:fexp DSLASH RelativeLocationPath:rlp {: - // + // // Expand '//' into '/descendant-or-self::node()/' or // into /descendant-or-self::*/ // int nodeType = DOM.NO_TYPE; - if (rlp instanceof Step && - parser.isElementAxis(((Step) rlp).getAxis())) + if (rlp instanceof Step && + parser.isElementAxis(((Step) rlp).getAxis())) { nodeType = DTM.ELEMENT_NODE; } @@ -605,7 +605,7 @@ {: RESULT = step; :} | RelativeLocationPath:rlp SLASH Step:step - {: + {: if (rlp instanceof Step && ((Step) rlp).isAbbreviatedDot()) { RESULT = step; // Remove './' from the middle } @@ -614,7 +614,7 @@ } else { RESULT = - new ParentLocationPath((RelativeLocationPath) rlp, step); + new ParentLocationPath((RelativeLocationPath) rlp, step); } :} @@ -631,7 +631,7 @@ {: RESULT = aalp; :}; AbbreviatedRelativeLocationPath ::= RelativeLocationPath:rlp DSLASH Step:step - {: + {: final Step right = (Step)step; final int axis = right.getAxis(); final int type = right.getNodeType(); @@ -653,14 +653,14 @@ else { // Expand './/step' -> 'descendant-or-self::*/step' if (rlp instanceof Step && ((Step)rlp).isAbbreviatedDot()) { - Step left = new Step(Axis.DESCENDANTORSELF, + Step left = new Step(Axis.DESCENDANTORSELF, DTM.ELEMENT_NODE, null); RESULT = new ParentLocationPath(left, right); } else { // Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step' RelativeLocationPath left = (RelativeLocationPath)rlp; - Step mid = new Step(Axis.DESCENDANTORSELF, + Step mid = new Step(Axis.DESCENDANTORSELF, DTM.ELEMENT_NODE, null); ParentLocationPath ppl = new ParentLocationPath(mid, right); RESULT = new ParentLocationPath(left, ppl); @@ -670,7 +670,7 @@ else if ((axis == Axis.ATTRIBUTE) || (type == NodeTest.ATTRIBUTE)) { // Expand 'rlp//step' -> 'rlp/descendant-or-self::*/step' RelativeLocationPath left = (RelativeLocationPath)rlp; - Step middle = new Step(Axis.DESCENDANTORSELF, + Step middle = new Step(Axis.DESCENDANTORSELF, DTM.ELEMENT_NODE, null); ParentLocationPath ppl = new ParentLocationPath(middle, right); RESULT = new ParentLocationPath(left, ppl); @@ -678,8 +678,8 @@ else { // Expand 'rlp//step' -> 'rlp/descendant-or-self::node()/step' RelativeLocationPath left = (RelativeLocationPath)rlp; - Step middle = new Step(Axis.DESCENDANTORSELF, - DOM.NO_TYPE, null); + Step middle = new Step(Axis.DESCENDANTORSELF, + DOM.NO_TYPE, null); ParentLocationPath ppl = new ParentLocationPath(middle, right); RESULT = new ParentLocationPath(left, ppl); } @@ -688,18 +688,18 @@ AbbreviatedAbsoluteLocationPath ::= DSLASH RelativeLocationPath:rlp {: - // + // // Expand '//' into '/descendant-or-self::node()/' or // into /descendant-or-self::*/ // int nodeType = DOM.NO_TYPE; - if (rlp instanceof Step && - parser.isElementAxis(((Step) rlp).getAxis())) + if (rlp instanceof Step && + parser.isElementAxis(((Step) rlp).getAxis())) { nodeType = DTM.ELEMENT_NODE; } final Step step = new Step(Axis.DESCENDANTORSELF, nodeType, null); - RESULT = new AbsoluteLocationPath(parser.insertStep(step, + RESULT = new AbsoluteLocationPath(parser.insertStep(step, (RelativeLocationPath) rlp)); :}; @@ -716,7 +716,7 @@ :} | NodeTest:ntest Predicates:pp - {: + {: if (ntest instanceof Step) { Step step = (Step)ntest; step.addPredicates(pp); @@ -807,9 +807,9 @@ {: RESULT = ex; :} | Literal:string - {: + {: /* - * If the string appears to have the syntax of a QName, store + * If the string appears to have the syntax of a QName, store * namespace info in the literal expression. This is used for * element-available and function-available functions, among * others. Also, the default namespace must be ignored. @@ -822,11 +822,11 @@ namespace = parser._symbolTable.lookupNamespace(prefix); } RESULT = (namespace == null) ? new LiteralExpr(string) - : new LiteralExpr(string, namespace); + : new LiteralExpr(string, namespace); :} | INT:num - {: + {: long value = num.longValue(); if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) { RESULT = new RealExpr(value); @@ -838,7 +838,7 @@ RESULT = new IntExpr(num.intValue()); else if (num.doubleValue() == 0.0) RESULT = new RealExpr(num.doubleValue()); - else + else RESULT = new IntExpr(num.intValue()); } :} @@ -850,7 +850,7 @@ {: RESULT = fc; :}; VariableReference ::= DOLLAR VariableName:varName - {: + {: // An empty qname prefix for a variable or parameter reference // should map to the null namespace and not the default URI. SyntaxTreeNode node = parser.lookupName(varName); @@ -861,7 +861,7 @@ } else if (node instanceof Param) { RESULT = new ParameterRef((Param)node); - } + } else { RESULT = new UnresolvedRef(varName); } @@ -873,45 +873,45 @@ :}; FunctionCall ::= FunctionName:fname LPAREN RPAREN - {: + {: - if (fname == parser.getQNameIgnoreDefaultNs("current")) { + if (parser.getQNameIgnoreDefaultNs("current").equals(fname)) { RESULT = new CurrentCall(fname); } - else if (fname == parser.getQNameIgnoreDefaultNs("number")) { + else if (parser.getQNameIgnoreDefaultNs("number").equals(fname)) { RESULT = new NumberCall(fname, parser.EmptyArgs); } - else if (fname == parser.getQNameIgnoreDefaultNs("string")) { + else if (parser.getQNameIgnoreDefaultNs("string").equals(fname)) { RESULT = new StringCall(fname, parser.EmptyArgs); } - else if (fname == parser.getQNameIgnoreDefaultNs("concat")) { + else if (parser.getQNameIgnoreDefaultNs("concat").equals(fname)) { RESULT = new ConcatCall(fname, parser.EmptyArgs); } - else if (fname == parser.getQNameIgnoreDefaultNs("true")) { + else if (parser.getQNameIgnoreDefaultNs("true").equals(fname)) { RESULT = new BooleanExpr(true); } - else if (fname == parser.getQNameIgnoreDefaultNs("false")) { + else if (parser.getQNameIgnoreDefaultNs("false").equals(fname)) { RESULT = new BooleanExpr(false); } - else if (fname == parser.getQNameIgnoreDefaultNs("name")) { + else if (parser.getQNameIgnoreDefaultNs("name").equals(fname)) { RESULT = new NameCall(fname); } - else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) { + else if (parser.getQNameIgnoreDefaultNs("generate-id").equals(fname)) { RESULT = new GenerateIdCall(fname, parser.EmptyArgs); } - else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) { + else if (parser.getQNameIgnoreDefaultNs("string-length").equals(fname)) { RESULT = new StringLengthCall(fname, parser.EmptyArgs); } - else if (fname == parser.getQNameIgnoreDefaultNs("position")) { + else if (parser.getQNameIgnoreDefaultNs("position").equals(fname)) { RESULT = new PositionCall(fname); } - else if (fname == parser.getQNameIgnoreDefaultNs("last")) { + else if (parser.getQNameIgnoreDefaultNs("last").equals(fname)) { RESULT = new LastCall(fname); } - else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) { + else if (parser.getQNameIgnoreDefaultNs("local-name").equals(fname)) { RESULT = new LocalNameCall(fname); } - else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) { + else if (parser.getQNameIgnoreDefaultNs("namespace-uri").equals(fname)) { RESULT = new NamespaceUriCall(fname); } else { @@ -921,78 +921,78 @@ | FunctionName:fname LPAREN NonemptyArgumentList:argl RPAREN {: - if (fname == parser.getQNameIgnoreDefaultNs("concat")) { + if (parser.getQNameIgnoreDefaultNs("concat").equals(fname)) { RESULT = new ConcatCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("number")) { + else if (parser.getQNameIgnoreDefaultNs("number").equals(fname)) { RESULT = new NumberCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("document")) { + else if (parser.getQNameIgnoreDefaultNs("document").equals(fname)) { parser.setMultiDocument(true); RESULT = new DocumentCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("string")) { + else if (parser.getQNameIgnoreDefaultNs("string").equals(fname)) { RESULT = new StringCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("boolean")) { + else if (parser.getQNameIgnoreDefaultNs("boolean").equals(fname)) { RESULT = new BooleanCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("name")) { + else if (parser.getQNameIgnoreDefaultNs("name").equals(fname)) { RESULT = new NameCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("generate-id")) { + else if (parser.getQNameIgnoreDefaultNs("generate-id").equals(fname)) { RESULT = new GenerateIdCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("not")) { + else if (parser.getQNameIgnoreDefaultNs("not").equals(fname)) { RESULT = new NotCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("format-number")) { + else if (parser.getQNameIgnoreDefaultNs("format-number").equals(fname)) { RESULT = new FormatNumberCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("unparsed-entity-uri")) { + else if (parser.getQNameIgnoreDefaultNs("unparsed-entity-uri").equals(fname)) { RESULT = new UnparsedEntityUriCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("key")) { + else if (parser.getQNameIgnoreDefaultNs("key").equals(fname)) { RESULT = new KeyCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("id")) { + else if (parser.getQNameIgnoreDefaultNs("id").equals(fname)) { RESULT = new KeyCall(fname, argl); parser.setHasIdCall(true); } - else if (fname == parser.getQNameIgnoreDefaultNs("ceiling")) { + else if (parser.getQNameIgnoreDefaultNs("ceiling").equals(fname)) { RESULT = new CeilingCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("round")) { + else if (parser.getQNameIgnoreDefaultNs("round").equals(fname)) { RESULT = new RoundCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("floor")) { + else if (parser.getQNameIgnoreDefaultNs("floor").equals(fname)) { RESULT = new FloorCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("contains")) { + else if (parser.getQNameIgnoreDefaultNs("contains").equals(fname)) { RESULT = new ContainsCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("string-length")) { + else if (parser.getQNameIgnoreDefaultNs("string-length").equals(fname)) { RESULT = new StringLengthCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("starts-with")) { + else if (parser.getQNameIgnoreDefaultNs("starts-with").equals(fname)) { RESULT = new StartsWithCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("function-available")) { + else if (parser.getQNameIgnoreDefaultNs("function-available").equals(fname)) { RESULT = new FunctionAvailableCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("element-available")) { + else if (parser.getQNameIgnoreDefaultNs("element-available").equals(fname)) { RESULT = new ElementAvailableCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("local-name")) { + else if (parser.getQNameIgnoreDefaultNs("local-name").equals(fname)) { RESULT = new LocalNameCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("lang")) { + else if (parser.getQNameIgnoreDefaultNs("lang").equals(fname)) { RESULT = new LangCall(fname, argl); } - else if (fname == parser.getQNameIgnoreDefaultNs("namespace-uri")) { + else if (parser.getQNameIgnoreDefaultNs("namespace-uri").equals(fname)) { RESULT = new NamespaceUriCall(fname, argl); } - else if (fname == parser.getQName(Constants.TRANSLET_URI, "xsltc", "cast")) { + else if (parser.getQName(Constants.TRANSLET_URI, "xsltc", "cast").equals(fname)) { RESULT = new CastCall(fname, argl); } // Special case for extension function nodeset() @@ -1006,7 +1006,7 @@ :}; NonemptyArgumentList ::= Argument:arg - {: + {: Vector temp = new Vector(); temp.addElement(arg); RESULT = temp; @@ -1016,13 +1016,13 @@ {: argl.insertElementAt(arg, 0); RESULT = argl; :}; FunctionName ::= QName:fname - {: - RESULT = fname; + {: + RESULT = fname; :}; VariableName ::= QName:vname - {: - RESULT = vname; + {: + RESULT = vname; :}; Argument ::= Expr:ex
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/xpath.lex Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/compiler/xpath.lex Wed Sep 28 17:10:18 2011 +0100 @@ -38,10 +38,10 @@ %yyeof %{ - int last, beforeLast; + int last; void initialize() { - last, beforeLast = -1; + last = -1; } static boolean isWhitespace(int c) { @@ -51,7 +51,7 @@ /** * If symbol is not followed by '::' or '(', then treat it as a * name instead of an axis or function (Jira-1912). - */ + */ Symbol disambiguateAxisOrFunction(int ss) throws Exception { // Peek in the input buffer without changing the internal state int index = yy_buffer_index; @@ -75,14 +75,11 @@ /** * If symbol is first token or if it follows any of the operators - * listed in http://www.w3.org/TR/xpath#exprlex then treat as a - * name instead of a keyword (Jira-1912). Look two tokens behind - * to desambiguate expressions like "* and *" or "and * and". - */ + * listed in http://www.w3.org/TR/xpath#exprlex then treat as a + * name instead of a keyword (Jira-1912). + */ Symbol disambiguateOperator(int ss) throws Exception { switch (last) { - case sym.STAR: - if (beforeLast != sym.QNAME) break; case -1: // first token case sym.ATSIGN: case sym.DCOLON: @@ -93,6 +90,7 @@ case sym.OR: case sym.MOD: case sym.DIV: + case sym.MULT: case sym.SLASH: case sym.DSLASH: case sym.VBAR: @@ -109,26 +107,56 @@ return newSymbol(ss); } + /** + * If symbol is first token or if it follows any of the operators + * listed in http://www.w3.org/TR/xpath#exprlex then treat as a + * wildcard instead of a multiplication operator + */ + Symbol disambiguateStar() throws Exception { + switch (last) { + case -1: // first token + case sym.ATSIGN: + case sym.DCOLON: + case sym.LPAREN: + case sym.LBRACK: + case sym.COMMA: + case sym.AND: + case sym.OR: + case sym.MOD: + case sym.DIV: + case sym.MULT: + case sym.SLASH: + case sym.DSLASH: + case sym.VBAR: + case sym.PLUS: + case sym.MINUS: + case sym.EQ: + case sym.NE: + case sym.LT: + case sym.LE: + case sym.GT: + case sym.GE: + return newSymbol(sym.STAR); + } + return newSymbol(sym.MULT); + } + Symbol newSymbol(int ss) { - beforeLast = last; last = ss; return new Symbol(ss); } Symbol newSymbol(int ss, String value) { - beforeLast = last; last = ss; return new Symbol(ss, value); } Symbol newSymbol(int ss, Long value) { - beforeLast = last; last = ss; return new Symbol(ss, value); } Symbol newSymbol(int ss, Double value) { - beforeLast = last; last = ss; return new Symbol(ss, value); } @@ -146,13 +174,13 @@ BaseChar=[\u0041-\u005A\u0061-\u007A\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u00FF\u0100-\u0131\u0134-\u013E\u0141-\u0148\u014A-\u017E\u0180-\u01C3\u01CD-\u01F0\u01F4-\u01F5\u01FA-\u0217\u0250-\u02A8\u02BB-\u02C1\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03CE\u03D0-\u03D6\u03DA\u03DC\u03DE\u03E0\u03E2-\u03F3\u0401-\u040C\u040E-\u044F\u0451-\u045C\u045E-\u0481\u0490-\u04C4\u04C7-\u04C8\u04CB-\u04CC\u04D0-\u04EB\u04EE-\u04F5\u04F8-\u04F9\u0531-\u0556\u0559\u0561-\u0586\u05D0-\u05EA\u05F0-\u05F2\u0621-\u063A\u0641-\u064A\u0671-\u06B7\u06BA-\u06BE\u06C0-\u06CE\u06D0-\u06D3\u06D5\u06E5-\u06E6\u0905-\u0939\u093D\u0958-\u0961\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8B\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AE0\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B36-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB5\u0BB7-\u0BB9\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C33\u0C35-\u0C39\u0C60-\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CDE\u0CE0-\u0CE1\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D28\u0D2A-\u0D39\u0D60-\u0D61\u0E01-\u0E2E\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EAE\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0F40-\u0F47\u0F49-\u0F69\u10A0-\u10C5\u10D0-\u10F6\u1100\u1102-\u1103\u1105-\u1107\u1109\u110B-\u110C\u110E-\u1112\u113C\u113E\u1140\u114C\u114E\u1150\u1154-\u1155\u1159\u115F-\u1161\u1163\u1165\u1167\u1169\u116D-\u116E\u1172-\u1173\u1175\u119E\u11A8\u11AB\u11AE-\u11AF\u11B7-\u11B8\u11BA\u11BC-\u11C2\u11EB\u11F0\u11F9\u1E00-\u1E9B\u1EA0-\u1EF9\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2126\u212A-\u212B\u212E\u2180-\u2182\u3041-\u3094\u30A1-\u30FA\u3105-\u312C\uAC00-\uD7A3] -Ideographic=[\u4E00-\u9FA5\u3007\u3021-\u3029] +Ideographic=[\u4E00-\u9FA5\u3007\u3021-\u3029] -CombiningChar=[\u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1\u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4\u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C\u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE\u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7\u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57\u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7\u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A] +CombiningChar=[\u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05A1\u05A3-\u05B9\u05BB-\u05BD\u05BF\u05C1-\u05C2\u05C4\u064B-\u0652\u0670\u06D6-\u06DC\u06DD-\u06DF\u06E0-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0901-\u0903\u093C\u093E-\u094C\u094D\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09BC\u09BE\u09BF\u09C0-\u09C4\u09C7-\u09C8\u09CB-\u09CD\u09D7\u09E2-\u09E3\u0A02\u0A3C\u0A3E\u0A3F\u0A40-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A70-\u0A71\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0B01-\u0B03\u0B3C\u0B3E-\u0B43\u0B47-\u0B48\u0B4B-\u0B4D\u0B56-\u0B57\u0B82-\u0B83\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C01-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C82-\u0C83\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D43\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86-\u0F8B\u0F90-\u0F95\u0F97\u0F99-\u0FAD\u0FB1-\u0FB7\u0FB9\u20D0-\u20DC\u20E1\u302A-\u302F\u3099\u309A] -Digit=[\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29] +Digit=[\u0030-\u0039\u0660-\u0669\u06F0-\u06F9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE7-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29] -Extender=[\u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005\u3031-\u3035\u309D-\u309E\u30FC-\u30FE] +Extender=[\u00B7\u02D0\u02D1\u0387\u0640\u0E46\u0EC6\u3005\u3031-\u3035\u309D-\u309E\u30FC-\u30FE] NCName=({Letter}|"_"|{NCNameStartChar})({NCNameChar})* @@ -166,8 +194,8 @@ %% -"*" { return newSymbol(sym.STAR); } -"/" { return newSymbol(sym.SLASH); } +"*" { return disambiguateStar(); } +"/" { return newSymbol(sym.SLASH); } "+" { return newSymbol(sym.PLUS); } "-" { return newSymbol(sym.MINUS); } "div" { return disambiguateOperator(sym.DIV); } @@ -181,7 +209,7 @@ "//" { return newSymbol(sym.DSLASH); } "=" { return newSymbol(sym.EQ); } "!=" { return newSymbol(sym.NE); } -"<" { return newSymbol(sym.LT); } +"<" { return newSymbol(sym.LT); } ">" { return newSymbol(sym.GT); } "<=" { return newSymbol(sym.LE); } ">=" { return newSymbol(sym.GE); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/dom/AdaptiveResultTreeImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/dom/AdaptiveResultTreeImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -44,8 +44,8 @@ /** * AdaptiveResultTreeImpl is a adaptive DOM model for result tree fragments (RTF). It is - * used in the case where the RTF is likely to be pure text yet it can still be a DOM tree. - * It is designed for RTFs which have <xsl:call-template> or <xsl:apply-templates> in + * used in the case where the RTF is likely to be pure text yet it can still be a DOM tree. + * It is designed for RTFs which have <xsl:call-template> or <xsl:apply-templates> in * the contents. Example: * <pre> * <xsl:variable name = "x"> @@ -55,13 +55,13 @@ * </xsl:variable> * </pre> * <p>In this example the result produced by <xsl:call-template> is likely to be a single - * Text node. But it can also be a DOM tree. This kind of RTF cannot be modelled by - * SimpleResultTreeImpl. + * Text node. But it can also be a DOM tree. This kind of RTF cannot be modelled by + * SimpleResultTreeImpl. * <p> * AdaptiveResultTreeImpl can be considered as a smart switcher between SimpleResultTreeImpl * and SAXImpl. It treats the RTF as simple Text and uses the SimpleResultTreeImpl model * at the beginning. However, if it receives a call which indicates that this is a DOM tree - * (e.g. startElement), it will automatically transform itself into a wrapper around a + * (e.g. startElement), it will automatically transform itself into a wrapper around a * SAXImpl. In this way we can have a light-weight model when the result only contains * simple text, while at the same time it still works when the RTF is a DOM tree. * <p> @@ -70,54 +70,56 @@ * wrapped SAXImpl. * <p> * %REVISIT% Can we combine this class with SimpleResultTreeImpl? I think it is possible, but - * it will make SimpleResultTreeImpl more expensive. I will use two separate classes at + * it will make SimpleResultTreeImpl more expensive. I will use two separate classes at * this time. */ public class AdaptiveResultTreeImpl extends SimpleResultTreeImpl { - + // Document URI index, which increases by 1 at each getDocumentURI() call. private static int _documentURIIndex = 0; + private static final String EMPTY_STRING = "".intern(); + // The SAXImpl object wrapped by this class, if the RTF is a tree. private SAXImpl _dom; - + /** The following fields are only used for the nested SAXImpl **/ - + // The whitespace filter private DTMWSFilter _wsfilter; - + // The size of the RTF private int _initSize; - + // True if we want to build the ID index table private boolean _buildIdIndex; - + // The AttributeList private final AttributesImpl _attributes = new AttributesImpl(); - + // The element name private String _openElementName; - - + + // Create a AdaptiveResultTreeImpl public AdaptiveResultTreeImpl(XSLTCDTMManager dtmManager, int documentID, DTMWSFilter wsfilter, int initSize, boolean buildIdIndex) { super(dtmManager, documentID); - + _wsfilter = wsfilter; _initSize = initSize; _buildIdIndex = buildIdIndex; } - + // Return the DOM object wrapped in this object. public DOM getNestedDOM() { return _dom; } - + // Return the document ID public int getDocument() { @@ -139,7 +141,7 @@ return super.getStringValue(); } } - + public DTMAxisIterator getIterator() { if (_dom != null) { @@ -149,7 +151,7 @@ return super.getIterator(); } } - + public DTMAxisIterator getChildren(final int node) { if (_dom != null) { @@ -159,7 +161,7 @@ return super.getChildren(node); } } - + public DTMAxisIterator getTypedChildren(final int type) { if (_dom != null) { @@ -169,7 +171,7 @@ return super.getTypedChildren(type); } } - + public DTMAxisIterator getAxisIterator(final int axis) { if (_dom != null) { @@ -179,7 +181,7 @@ return super.getAxisIterator(axis); } } - + public DTMAxisIterator getTypedAxisIterator(final int axis, final int type) { if (_dom != null) { @@ -187,9 +189,9 @@ } else { return super.getTypedAxisIterator(axis, type); - } + } } - + public DTMAxisIterator getNthDescendant(int node, int n, boolean includeself) { if (_dom != null) { @@ -199,7 +201,7 @@ return super.getNthDescendant(node, n, includeself); } } - + public DTMAxisIterator getNamespaceAxisIterator(final int axis, final int ns) { if (_dom != null) { @@ -209,9 +211,9 @@ return super.getNamespaceAxisIterator(axis, ns); } } - + public DTMAxisIterator getNodeValueIterator(DTMAxisIterator iter, int returnType, - String value, boolean op) + String value, boolean op) { if (_dom != null) { return _dom.getNodeValueIterator(iter, returnType, value, op); @@ -220,7 +222,7 @@ return super.getNodeValueIterator(iter, returnType, value, op); } } - + public DTMAxisIterator orderNodes(DTMAxisIterator source, int node) { if (_dom != null) { @@ -230,7 +232,7 @@ return super.orderNodes(source, node); } } - + public String getNodeName(final int node) { if (_dom != null) { @@ -240,7 +242,7 @@ return super.getNodeName(node); } } - + public String getNodeNameX(final int node) { if (_dom != null) { @@ -250,7 +252,7 @@ return super.getNodeNameX(node); } } - + public String getNamespaceName(final int node) { if (_dom != null) { @@ -260,7 +262,7 @@ return super.getNamespaceName(node); } } - + // Return the expanded type id of a given node public int getExpandedTypeID(final int nodeHandle) { @@ -271,7 +273,7 @@ return super.getExpandedTypeID(nodeHandle); } } - + public int getNamespaceType(final int node) { if (_dom != null) { @@ -281,7 +283,7 @@ return super.getNamespaceType(node); } } - + public int getParent(final int nodeHandle) { if (_dom != null) { @@ -291,7 +293,7 @@ return super.getParent(nodeHandle); } } - + public int getAttributeNode(final int gType, final int element) { if (_dom != null) { @@ -301,7 +303,7 @@ return super.getAttributeNode(gType, element); } } - + public String getStringValueX(final int nodeHandle) { if (_dom != null) { @@ -311,9 +313,9 @@ return super.getStringValueX(nodeHandle); } } - + public void copy(final int node, SerializationHandler handler) - throws TransletException + throws TransletException { if (_dom != null) { _dom.copy(node, handler); @@ -322,9 +324,9 @@ super.copy(node, handler); } } - + public void copy(DTMAxisIterator nodes, SerializationHandler handler) - throws TransletException + throws TransletException { if (_dom != null) { _dom.copy(nodes, handler); @@ -333,9 +335,9 @@ super.copy(nodes, handler); } } - + public String shallowCopy(final int node, SerializationHandler handler) - throws TransletException + throws TransletException { if (_dom != null) { return _dom.shallowCopy(node, handler); @@ -344,7 +346,7 @@ return super.shallowCopy(node, handler); } } - + public boolean lessThan(final int node1, final int node2) { if (_dom != null) { @@ -354,7 +356,7 @@ return super.lessThan(node1, node2); } } - + /** * Dispatch the character content of a node to an output handler. * @@ -362,16 +364,16 @@ * a handler. */ public void characters(final int node, SerializationHandler handler) - throws TransletException + throws TransletException { if (_dom != null) { _dom.characters(node, handler); } else { super.characters(node, handler); - } + } } - + public Node makeNode(int index) { if (_dom != null) { @@ -379,9 +381,9 @@ } else { return super.makeNode(index); - } + } } - + public Node makeNode(DTMAxisIterator iter) { if (_dom != null) { @@ -389,9 +391,9 @@ } else { return super.makeNode(iter); - } + } } - + public NodeList makeNodeList(int index) { if (_dom != null) { @@ -399,9 +401,9 @@ } else { return super.makeNodeList(index); - } + } } - + public NodeList makeNodeList(DTMAxisIterator iter) { if (_dom != null) { @@ -409,9 +411,9 @@ } else { return super.makeNodeList(iter); - } + } } - + public String getLanguage(int node) { if (_dom != null) { @@ -419,9 +421,9 @@ } else { return super.getLanguage(node); - } + } } - + public int getSize() { if (_dom != null) { @@ -429,9 +431,9 @@ } else { return super.getSize(); - } + } } - + public String getDocumentURI(int node) { if (_dom != null) { @@ -439,9 +441,9 @@ } else { return "adaptive_rtf" + _documentURIIndex++; - } + } } - + public void setFilter(StripFilter filter) { if (_dom != null) { @@ -449,9 +451,9 @@ } else { super.setFilter(filter); - } + } } - + public void setupMapping(String[] names, String[] uris, int[] types, String[] namespaces) { if (_dom != null) { @@ -459,9 +461,9 @@ } else { super.setupMapping(names, uris, types, namespaces); - } + } } - + public boolean isElement(final int node) { if (_dom != null) { @@ -469,9 +471,9 @@ } else { return super.isElement(node); - } + } } - + public boolean isAttribute(final int node) { if (_dom != null) { @@ -479,20 +481,20 @@ } else { return super.isAttribute(node); - } + } } - + public String lookupNamespace(int node, String prefix) - throws TransletException + throws TransletException { if (_dom != null) { return _dom.lookupNamespace(node, prefix); } else { return super.lookupNamespace(node, prefix); - } + } } - + /** * Return the node identity from a node handle. */ @@ -503,9 +505,9 @@ } else { return super.getNodeIdent(nodehandle); - } + } } - + /** * Return the node handle from a node identity. */ @@ -516,9 +518,9 @@ } else { return super.getNodeHandle(nodeId); - } + } } - + public DOM getResultTreeFrag(int initialSize, int rtfType) { if (_dom != null) { @@ -526,14 +528,14 @@ } else { return super.getResultTreeFrag(initialSize, rtfType); - } + } } - + public SerializationHandler getOutputDomBuilder() { return this; } - + public int getNSType(int node) { if (_dom != null) { @@ -541,9 +543,9 @@ } else { return super.getNSType(node); - } + } } - + public String getUnparsedEntityURI(String name) { if (_dom != null) { @@ -551,9 +553,9 @@ } else { return super.getUnparsedEntityURI(name); - } + } } - + public Hashtable getElementsWithIDs() { if (_dom != null) { @@ -561,31 +563,31 @@ } else { return super.getElementsWithIDs(); - } + } } /** Implementation of the SerializationHandler interfaces **/ - + /** The code in some of the following interfaces are copied from SAXAdapter. **/ - + private void maybeEmitStartElement() throws SAXException { if (_openElementName != null) { - int index; - if ((index =_openElementName.indexOf(":")) < 0) - _dom.startElement(null, _openElementName, _openElementName, _attributes); - else { - String uri =_dom.getNamespaceURI(_openElementName.substring(0,index)); - _dom.startElement(uri, _openElementName.substring(index+1), _openElementName, _attributes); + int index; + if ((index =_openElementName.indexOf(":")) < 0) + _dom.startElement(null, _openElementName, _openElementName, _attributes); + else { + String uri =_dom.getNamespaceURI(_openElementName.substring(0,index)); + _dom.startElement(uri, _openElementName.substring(index+1), _openElementName, _attributes); } - _openElementName = null; - } - + _openElementName = null; + } + } - + // Create and initialize the wrapped SAXImpl object private void prepareNewDOM() throws SAXException { @@ -600,11 +602,11 @@ } _size = 0; } - + public void startDocument() throws SAXException - { + { } - + public void endDocument() throws SAXException { if (_dom != null) { @@ -624,19 +626,19 @@ super.characters(str); } } - + public void characters(char[] ch, int offset, int length) - throws SAXException + throws SAXException { if (_dom != null) { - maybeEmitStartElement(); - _dom.characters(ch, offset, length); + maybeEmitStartElement(); + _dom.characters(ch, offset, length); } else { super.characters(ch, offset, length); } } - + public boolean setEscaping(boolean escape) throws SAXException { if (_dom != null) { @@ -646,16 +648,16 @@ return super.setEscaping(escape); } } - + public void startElement(String elementName) throws SAXException { if (_dom == null) { prepareNewDOM(); } - - maybeEmitStartElement(); - _openElementName = elementName; - _attributes.clear(); + + maybeEmitStartElement(); + _openElementName = elementName; + _attributes.clear(); } public void startElement(String uri, String localName, String qName) @@ -669,11 +671,11 @@ { startElement(qName); } - + public void endElement(String elementName) throws SAXException - { - maybeEmitStartElement(); - _dom.endElement(null, null, elementName); + { + maybeEmitStartElement(); + _dom.endElement(null, null, elementName); } public void endElement(String uri, String localName, String qName) @@ -682,7 +684,23 @@ endElement(qName); } - public void addUniqueAttribute(String qName, String value, int flags) + public void addAttribute(String qName, String value) + { + // "prefix:localpart" or "localpart" + int colonpos = qName.indexOf(":"); + String uri = EMPTY_STRING; + String localName = qName; + if (colonpos >0) + { + String prefix = qName.substring(0, colonpos); + localName = qName.substring(colonpos+1); + uri = _dom.getNamespaceURI(prefix); + } + + addAttribute(uri, localName, qName, "CDATA", value); + } + + public void addUniqueAttribute(String qName, String value, int flags) throws SAXException { addAttribute(qName, value); @@ -691,73 +709,73 @@ public void addAttribute(String uri, String localName, String qname, String type, String value) { - if (_openElementName != null) { - _attributes.addAttribute(uri, localName, qname, type, value); - } - else { - BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR, qname); - } + if (_openElementName != null) { + _attributes.addAttribute(uri, localName, qname, type, value); + } + else { + BasisLibrary.runTimeError(BasisLibrary.STRAY_ATTRIBUTE_ERR, qname); + } } public void namespaceAfterStartElement(String prefix, String uri) throws SAXException - { - if (_dom == null) { - prepareNewDOM(); - } - - _dom.startPrefixMapping(prefix, uri); + { + if (_dom == null) { + prepareNewDOM(); + } + + _dom.startPrefixMapping(prefix, uri); } - + public void comment(String comment) throws SAXException - { - if (_dom == null) { - prepareNewDOM(); - } - - maybeEmitStartElement(); + { + if (_dom == null) { + prepareNewDOM(); + } + + maybeEmitStartElement(); char[] chars = comment.toCharArray(); _dom.comment(chars, 0, chars.length); } public void comment(char[] chars, int offset, int length) throws SAXException - { - if (_dom == null) { - prepareNewDOM(); - } - - maybeEmitStartElement(); + { + if (_dom == null) { + prepareNewDOM(); + } + + maybeEmitStartElement(); _dom.comment(chars, offset, length); } - + public void processingInstruction(String target, String data) - throws SAXException - { - if (_dom == null) { - prepareNewDOM(); - } - - maybeEmitStartElement(); - _dom.processingInstruction(target, data); + throws SAXException + { + if (_dom == null) { + prepareNewDOM(); + } + + maybeEmitStartElement(); + _dom.processingInstruction(target, data); } - + /** Implementation of the DTM interfaces **/ - + public void setFeature(String featureId, boolean state) { if (_dom != null) { _dom.setFeature(featureId, state); } } - + public void setProperty(String property, Object value) { if (_dom != null) { _dom.setProperty(property, value); } } - + public DTMAxisTraverser getAxisTraverser(final int axis) { if (_dom != null) { @@ -767,7 +785,7 @@ return super.getAxisTraverser(axis); } } - + public boolean hasChildNodes(int nodeHandle) { if (_dom != null) { @@ -777,7 +795,7 @@ return super.hasChildNodes(nodeHandle); } } - + public int getFirstChild(int nodeHandle) { if (_dom != null) { @@ -787,7 +805,7 @@ return super.getFirstChild(nodeHandle); } } - + public int getLastChild(int nodeHandle) { if (_dom != null) { @@ -797,7 +815,7 @@ return super.getLastChild(nodeHandle); } } - + public int getAttributeNode(int elementHandle, String namespaceURI, String name) { if (_dom != null) { @@ -807,7 +825,7 @@ return super.getAttributeNode(elementHandle, namespaceURI, name); } } - + public int getFirstAttribute(int nodeHandle) { if (_dom != null) { @@ -817,7 +835,7 @@ return super.getFirstAttribute(nodeHandle); } } - + public int getFirstNamespaceNode(int nodeHandle, boolean inScope) { if (_dom != null) { @@ -827,7 +845,7 @@ return super.getFirstNamespaceNode(nodeHandle, inScope); } } - + public int getNextSibling(int nodeHandle) { if (_dom != null) { @@ -837,7 +855,7 @@ return super.getNextSibling(nodeHandle); } } - + public int getPreviousSibling(int nodeHandle) { if (_dom != null) { @@ -847,7 +865,7 @@ return super.getPreviousSibling(nodeHandle); } } - + public int getNextAttribute(int nodeHandle) { if (_dom != null) { @@ -857,7 +875,7 @@ return super.getNextAttribute(nodeHandle); } } - + public int getNextNamespaceNode(int baseHandle, int namespaceHandle, boolean inScope) { @@ -868,7 +886,7 @@ return super.getNextNamespaceNode(baseHandle, namespaceHandle, inScope); } } - + public int getOwnerDocument(int nodeHandle) { if (_dom != null) { @@ -878,7 +896,7 @@ return super.getOwnerDocument(nodeHandle); } } - + public int getDocumentRoot(int nodeHandle) { if (_dom != null) { @@ -888,7 +906,7 @@ return super.getDocumentRoot(nodeHandle); } } - + public XMLString getStringValue(int nodeHandle) { if (_dom != null) { @@ -898,7 +916,7 @@ return super.getStringValue(nodeHandle); } } - + public int getStringValueChunkCount(int nodeHandle) { if (_dom != null) { @@ -908,7 +926,7 @@ return super.getStringValueChunkCount(nodeHandle); } } - + public char[] getStringValueChunk(int nodeHandle, int chunkIndex, int[] startAndLen) { @@ -919,7 +937,7 @@ return super.getStringValueChunk(nodeHandle, chunkIndex, startAndLen); } } - + public int getExpandedTypeID(String namespace, String localName, int type) { if (_dom != null) { @@ -929,7 +947,7 @@ return super.getExpandedTypeID(namespace, localName, type); } } - + public String getLocalNameFromExpandedNameID(int ExpandedNameID) { if (_dom != null) { @@ -939,7 +957,7 @@ return super.getLocalNameFromExpandedNameID(ExpandedNameID); } } - + public String getNamespaceFromExpandedNameID(int ExpandedNameID) { if (_dom != null) { @@ -949,7 +967,7 @@ return super.getNamespaceFromExpandedNameID(ExpandedNameID); } } - + public String getLocalName(int nodeHandle) { if (_dom != null) { @@ -959,7 +977,7 @@ return super.getLocalName(nodeHandle); } } - + public String getPrefix(int nodeHandle) { if (_dom != null) { @@ -969,7 +987,7 @@ return super.getPrefix(nodeHandle); } } - + public String getNamespaceURI(int nodeHandle) { if (_dom != null) { @@ -979,7 +997,7 @@ return super.getNamespaceURI(nodeHandle); } } - + public String getNodeValue(int nodeHandle) { if (_dom != null) { @@ -989,7 +1007,7 @@ return super.getNodeValue(nodeHandle); } } - + public short getNodeType(int nodeHandle) { if (_dom != null) { @@ -999,7 +1017,7 @@ return super.getNodeType(nodeHandle); } } - + public short getLevel(int nodeHandle) { if (_dom != null) { @@ -1009,7 +1027,7 @@ return super.getLevel(nodeHandle); } } - + public boolean isSupported(String feature, String version) { if (_dom != null) { @@ -1019,7 +1037,7 @@ return super.isSupported(feature, version); } } - + public String getDocumentBaseURI() { if (_dom != null) { @@ -1029,7 +1047,7 @@ return super.getDocumentBaseURI(); } } - + public void setDocumentBaseURI(String baseURI) { if (_dom != null) { @@ -1039,7 +1057,7 @@ super.setDocumentBaseURI(baseURI); } } - + public String getDocumentSystemIdentifier(int nodeHandle) { if (_dom != null) { @@ -1049,7 +1067,7 @@ return super.getDocumentSystemIdentifier(nodeHandle); } } - + public String getDocumentEncoding(int nodeHandle) { if (_dom != null) { @@ -1059,7 +1077,7 @@ return super.getDocumentEncoding(nodeHandle); } } - + public String getDocumentStandalone(int nodeHandle) { if (_dom != null) { @@ -1069,7 +1087,7 @@ return super.getDocumentStandalone(nodeHandle); } } - + public String getDocumentVersion(int documentHandle) { if (_dom != null) { @@ -1079,7 +1097,7 @@ return super.getDocumentVersion(documentHandle); } } - + public boolean getDocumentAllDeclarationsProcessed() { if (_dom != null) { @@ -1089,7 +1107,7 @@ return super.getDocumentAllDeclarationsProcessed(); } } - + public String getDocumentTypeDeclarationSystemIdentifier() { if (_dom != null) { @@ -1099,7 +1117,7 @@ return super.getDocumentTypeDeclarationSystemIdentifier(); } } - + public String getDocumentTypeDeclarationPublicIdentifier() { if (_dom != null) { @@ -1109,7 +1127,7 @@ return super.getDocumentTypeDeclarationPublicIdentifier(); } } - + public int getElementById(String elementId) { if (_dom != null) { @@ -1119,7 +1137,7 @@ return super.getElementById(elementId); } } - + public boolean supportsPreStripping() { if (_dom != null) { @@ -1129,7 +1147,7 @@ return super.supportsPreStripping(); } } - + public boolean isNodeAfter(int firstNodeHandle, int secondNodeHandle) { if (_dom != null) { @@ -1139,7 +1157,7 @@ return super.isNodeAfter(firstNodeHandle, secondNodeHandle); } } - + public boolean isCharacterElementContentWhitespace(int nodeHandle) { if (_dom != null) { @@ -1149,7 +1167,7 @@ return super.isCharacterElementContentWhitespace(nodeHandle); } } - + public boolean isDocumentAllDeclarationsProcessed(int documentHandle) { if (_dom != null) { @@ -1159,7 +1177,7 @@ return super.isDocumentAllDeclarationsProcessed(documentHandle); } } - + public boolean isAttributeSpecified(int attributeHandle) { if (_dom != null) { @@ -1169,7 +1187,7 @@ return super.isAttributeSpecified(attributeHandle); } } - + public void dispatchCharactersEvents(int nodeHandle, org.xml.sax.ContentHandler ch, boolean normalize) throws org.xml.sax.SAXException @@ -1181,7 +1199,7 @@ super.dispatchCharactersEvents(nodeHandle, ch, normalize); } } - + public void dispatchToEvents(int nodeHandle, org.xml.sax.ContentHandler ch) throws org.xml.sax.SAXException { @@ -1192,7 +1210,7 @@ super.dispatchToEvents(nodeHandle, ch); } } - + public org.w3c.dom.Node getNode(int nodeHandle) { if (_dom != null) { @@ -1202,7 +1220,7 @@ return super.getNode(nodeHandle); } } - + public boolean needsTwoThreads() { if (_dom != null) { @@ -1212,7 +1230,7 @@ return super.needsTwoThreads(); } } - + public org.xml.sax.ContentHandler getContentHandler() { if (_dom != null) { @@ -1222,7 +1240,7 @@ return super.getContentHandler(); } } - + public org.xml.sax.ext.LexicalHandler getLexicalHandler() { if (_dom != null) { @@ -1232,7 +1250,7 @@ return super.getLexicalHandler(); } } - + public org.xml.sax.EntityResolver getEntityResolver() { if (_dom != null) { @@ -1242,7 +1260,7 @@ return super.getEntityResolver(); } } - + public org.xml.sax.DTDHandler getDTDHandler() { if (_dom != null) { @@ -1252,7 +1270,7 @@ return super.getDTDHandler(); } } - + public org.xml.sax.ErrorHandler getErrorHandler() { if (_dom != null) { @@ -1262,7 +1280,7 @@ return super.getErrorHandler(); } } - + public org.xml.sax.ext.DeclHandler getDeclHandler() { if (_dom != null) { @@ -1272,7 +1290,7 @@ return super.getDeclHandler(); } } - + public void appendChild(int newChild, boolean clone, boolean cloneDepth) { if (_dom != null) { @@ -1282,7 +1300,7 @@ super.appendChild(newChild, clone, cloneDepth); } } - + public void appendTextChild(String str) { if (_dom != null) { @@ -1292,7 +1310,7 @@ super.appendTextChild(str); } } - + public SourceLocator getSourceLocatorFor(int node) { if (_dom != null) { @@ -1302,7 +1320,7 @@ return super.getSourceLocatorFor(node); } } - + public void documentRegistration() { if (_dom != null) { @@ -1312,7 +1330,7 @@ super.documentRegistration(); } } - + public void documentRelease() { if (_dom != null) {
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/runtime/AbstractTranslet.java Wed Sep 28 17:10:18 2011 +0100 @@ -25,6 +25,7 @@ import java.io.File; import java.io.FileOutputStream; +import java.io.BufferedOutputStream; import java.text.DecimalFormat; import java.text.DecimalFormatSymbols; import java.util.ArrayList; @@ -54,7 +55,7 @@ * @author Santiago Pericas-Geertsen * @author Morten Jorgensen * @author G. Todd Miller - * @author John Howard, JohnH@schemasoft.com + * @author John Howard, JohnH@schemasoft.com */ public abstract class AbstractTranslet implements Translet { @@ -88,10 +89,10 @@ protected String[] urisArray; protected int[] typesArray; protected String[] namespaceArray; - + // The Templates object that is used to create this Translet instance protected Templates _templates = null; - + // Boolean flag to indicate whether this translet has id functions. protected boolean _hasIdCall = false; @@ -104,20 +105,20 @@ // This is the name of the index used for ID attributes private final static String ID_INDEX_NAME = "##id"; - + /************************************************************************ * Debugging ************************************************************************/ public void printInternalState() { - 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()); + 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()); } /** @@ -126,16 +127,16 @@ * code in the translet - see compiler/Stylesheet.compileTransform()). */ public final DOMAdapter makeDOMAdapter(DOM dom) - throws TransletException { + throws TransletException { setRootForKeys(dom.getDocument()); - return new DOMAdapter(dom, namesArray, urisArray, typesArray, namespaceArray); + return new DOMAdapter(dom, namesArray, urisArray, typesArray, namespaceArray); } /************************************************************************ * Parameter handling ************************************************************************/ - // Parameter's stack: <tt>pbase</tt> and <tt>pframe</tt> are used + // Parameter's stack: <tt>pbase</tt> and <tt>pframe</tt> are used // to denote the current parameter frame. protected int pbase = 0, pframe = 0; protected ArrayList paramsStack = new ArrayList(); @@ -144,34 +145,34 @@ * Push a new parameter frame. */ public final void pushParamFrame() { - paramsStack.add(pframe, new Integer(pbase)); - pbase = ++pframe; + paramsStack.add(pframe, new Integer(pbase)); + pbase = ++pframe; } /** * Pop the topmost parameter frame. */ public final void popParamFrame() { - 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; - } + 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; + } } /** * 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 + * The mapping created so that + * the global variables in the generated class become * http$colon$$flash$$flash$foo$dot$bar$colon$xyz */ public final Object addParameter(String name, Object value) { name = BasisLibrary.mapQNameToJavaName (name); - return addParameter(name, value, false); + return addParameter(name, value, false); } /** @@ -180,36 +181,36 @@ * default value from the <xsl:parameter> element's select attribute or * element body. */ - public final Object addParameter(String name, Object value, - boolean isDefault) + public final Object addParameter(String name, Object value, + boolean isDefault) { - // 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); + // 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; - } - } + 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; + // Add new parameter to parameter stack + paramsStack.add(pframe++, new Parameter(name, value, isDefault)); + return value; } /** * Clears the parameter stack. */ - public void clearParameters() { - pbase = pframe = 0; - paramsStack.clear(); + public void clearParameters() { + pbase = pframe = 0; + paramsStack.clear(); } /** @@ -220,11 +221,11 @@ 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; + 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; } /************************************************************************ @@ -240,19 +241,19 @@ * Set the translet's message handler - must implement MessageHandler */ public final void setMessageHandler(MessageHandler handler) { - _msgHandler = handler; + _msgHandler = handler; } /** * Pass a message to the message handler - used by Message class. */ public final void displayMessage(String msg) { - if (_msgHandler == null) { + if (_msgHandler == null) { System.err.println(msg); - } - else { - _msgHandler.displayMessage(msg); - } + } + else { + _msgHandler.displayMessage(msg); + } } /************************************************************************ @@ -267,18 +268,18 @@ * The entry is created with the input DecimalFormatSymbols. */ public void addDecimalFormat(String name, DecimalFormatSymbols symbols) { - // Instanciate hashtable for formatting symbols if needed - if (_formatSymbols == null) _formatSymbols = new Hashtable(); + // 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; + // 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); + // Construct a DecimalFormat object containing the symbols we got + final DecimalFormat df = new DecimalFormat(); + if (symbols != null) { + df.setDecimalFormatSymbols(symbols); + } + _formatSymbols.put(name, df); } /** @@ -286,15 +287,15 @@ */ public final DecimalFormat getDecimalFormat(String name) { - if (_formatSymbols != null) { - // The name cannot be null - use empty string instead - if (name == null) name = EMPTYSTRING; + 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); + DecimalFormat df = (DecimalFormat)_formatSymbols.get(name); + if (df == null) df = (DecimalFormat)_formatSymbols.get(EMPTYSTRING); + return df; + } + return(null); } /** @@ -318,7 +319,7 @@ 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. @@ -330,7 +331,7 @@ final Hashtable elementsByID = enhancedDOM.getElementsWithIDs(); if (elementsByID == null) { - return; + return; } // Given a Hashtable of DTM nodes indexed by ID attribute values, @@ -340,18 +341,18 @@ boolean hasIDValues = false; while (idValues.hasMoreElements()) { - final Object idValue = idValues.nextElement(); - final int element = + final Object idValue = idValues.nextElement(); + final int element = document.getNodeHandle( ((Integer)elementsByID.get(idValue)) .intValue()); - buildKeyIndex(ID_INDEX_NAME, element, idValue); - hasIDValues = true; + buildKeyIndex(ID_INDEX_NAME, element, idValue); + hasIDValues = true; } if (hasIDValues) { - setKeyIndexDom(ID_INDEX_NAME, document); + setKeyIndexDom(ID_INDEX_NAME, document); } } } @@ -424,14 +425,14 @@ * Needed to make sure that the translet can index the whole DOM. */ public void setIndexSize(int size) { - if (size > _indexSize) _indexSize = size; + if (size > _indexSize) _indexSize = size; } /** * Creates a KeyIndex object of the desired size - don't want to resize!!! */ public KeyIndex createKeyIndex() { - return(new KeyIndex(_indexSize)); + return(new KeyIndex(_indexSize)); } /** @@ -441,13 +442,13 @@ * @param value is the value that will look up the node in the given index */ public void buildKeyIndex(String name, int node, Object value) { - 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); + 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); } /** @@ -456,13 +457,13 @@ * @param dom is the DOM */ public void buildKeyIndex(String name, DOM 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()); + 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()); } /** @@ -470,24 +471,24 @@ * The index implements our internal iterator interface */ public KeyIndex getKeyIndex(String name) { - // Return an empty key index iterator if none are defined - if (_keyIndexes == null) { - return (_emptyKeyIndex != null) - ? _emptyKeyIndex - : (_emptyKeyIndex = new KeyIndex(1)); - } + // 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); + // 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 an empty key index iterator if the requested index not found + if (index == null) { + return (_emptyKeyIndex != null) + ? _emptyKeyIndex + : (_emptyKeyIndex = new KeyIndex(1)); + } - return(index); + return(index); } private void setRootForKeys(int root) { @@ -499,17 +500,17 @@ * translet in cases where the <xsl:key> element is used */ public void buildKeys(DOM document, DTMAxisIterator iterator, - SerializationHandler handler, - int root) throws TransletException { - + SerializationHandler handler, + int root) throws TransletException { + } - + /** * This method builds key indexes - it is overridden in the compiled * translet in cases where the <xsl:key> element is used */ public void setKeyIndexDom(String name, DOM document) { - getKeyIndex(name).setDom(document, document.getDocument()); + getKeyIndex(name).setDom(document, document.getDocument()); } /************************************************************************ @@ -524,7 +525,7 @@ * document() function. */ public void setDOMCache(DOMCache cache) { - _domCache = cache; + _domCache = cache; } /** @@ -532,7 +533,7 @@ * class (if present) when the document() function is used. */ public DOMCache getDOMCache() { - return(_domCache); + return(_domCache); } /************************************************************************ @@ -540,12 +541,12 @@ * See compiler/TransletOutput for actual implementation. ************************************************************************/ - public SerializationHandler openOutputHandler(String filename, boolean append) - throws TransletException + public SerializationHandler openOutputHandler(String filename, boolean append) + throws TransletException { - try { - final TransletOutputHandlerFactory factory - = TransletOutputHandlerFactory.newInstance(); + try { + final TransletOutputHandlerFactory factory + = TransletOutputHandlerFactory.newInstance(); String dirStr = new File(filename).getParent(); if ((null != dirStr) && (dirStr.length() > 0)) { @@ -553,37 +554,37 @@ dir.mkdirs(); } - factory.setEncoding(_encoding); - factory.setOutputMethod(_method); - factory.setOutputStream(new FileOutputStream(filename, append)); - factory.setOutputType(TransletOutputHandlerFactory.STREAM); + factory.setEncoding(_encoding); + factory.setOutputMethod(_method); + factory.setOutputStream(new BufferedOutputStream(new FileOutputStream(filename, append))); + factory.setOutputType(TransletOutputHandlerFactory.STREAM); - final SerializationHandler handler - = factory.getSerializationHandler(); + final SerializationHandler handler + = factory.getSerializationHandler(); - transferOutputSettings(handler); - handler.startDocument(); - return handler; - } - catch (Exception e) { - throw new TransletException(e); - } + transferOutputSettings(handler); + handler.startDocument(); + return handler; + } + catch (Exception e) { + throw new TransletException(e); + } } - public SerializationHandler openOutputHandler(String filename) - throws TransletException + public SerializationHandler openOutputHandler(String filename) + throws TransletException { return openOutputHandler(filename, false); } public void closeOutputHandler(SerializationHandler handler) { - try { - handler.endDocument(); - handler.close(); - } - catch (Exception e) { - // what can you do? - } + try { + handler.endDocument(); + handler.close(); + } + catch (Exception e) { + // what can you do? + } } /************************************************************************ @@ -594,28 +595,28 @@ * Main transform() method - this is overridden by the compiled translet */ public abstract void transform(DOM document, DTMAxisIterator iterator, - SerializationHandler handler) - throws TransletException; + SerializationHandler handler) + throws TransletException; /** * Calls transform() with a given output handler */ - public final void transform(DOM document, SerializationHandler handler) - throws TransletException { + public final void transform(DOM document, SerializationHandler handler) + throws TransletException { try { transform(document, document.getIterator(), handler); } finally { _keyIndexes = null; } } - + /** * Used by some compiled code as a shortcut for passing strings to the * output handler */ public final void characters(final String string, - SerializationHandler handler) - throws TransletException { + SerializationHandler handler) + throws TransletException { if (string != null) { //final int length = string.length(); try { @@ -623,14 +624,14 @@ } catch (Exception e) { throw new TransletException(e); } - } + } } /** * Add's a name of an element whose text contents should be output as CDATA */ public void addCdataElement(String name) { - if (_cdata == null) { + if (_cdata == null) { _cdata = new Vector(); } @@ -639,11 +640,11 @@ if (lastColon > 0) { String uri = name.substring(0, lastColon); String localName = name.substring(lastColon+1); - _cdata.addElement(uri); - _cdata.addElement(localName); + _cdata.addElement(uri); + _cdata.addElement(localName); } else { - _cdata.addElement(null); - _cdata.addElement(name); + _cdata.addElement(null); + _cdata.addElement(name); } } @@ -651,100 +652,100 @@ * Transfer the output settings to the output post-processor */ protected void transferOutputSettings(SerializationHandler handler) { - 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); - } + 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); + } } private Hashtable _auxClasses = null; public void addAuxiliaryClass(Class auxClass) { - if (_auxClasses == null) _auxClasses = new Hashtable(); - _auxClasses.put(auxClass.getName(), auxClass); + if (_auxClasses == null) _auxClasses = new Hashtable(); + _auxClasses.put(auxClass.getName(), auxClass); } public void setAuxiliaryClasses(Hashtable auxClasses) { - _auxClasses = auxClasses; + _auxClasses = auxClasses; } - + public Class getAuxiliaryClass(String className) { - if (_auxClasses == null) return null; - return((Class)_auxClasses.get(className)); + if (_auxClasses == null) return null; + return((Class)_auxClasses.get(className)); } // GTM added (see pg 110) public String[] getNamesArray() { - return namesArray; + return namesArray; } - + public String[] getUrisArray() { - return urisArray; + return urisArray; } - + public int[] getTypesArray() { - return typesArray; + return typesArray; } - + public String[] getNamespaceArray() { - return namespaceArray; + return namespaceArray; } - + public boolean hasIdCall() { - return _hasIdCall; + return _hasIdCall; } - + public Templates getTemplates() { - return _templates; + return _templates; } - + public void setTemplates(Templates templates) { - _templates = templates; - } - + _templates = templates; + } + /************************************************************************ * DOMImplementation caching for basis library ************************************************************************/ protected DOMImplementation _domImplementation = null; - - public Document newDocument(String uri, String qname) - throws ParserConfigurationException + + public Document newDocument(String uri, String qname) + throws ParserConfigurationException { if (_domImplementation == null) { _domImplementation = DocumentBuilderFactory.newInstance()
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/runtime/BasisLibrary.java Wed Sep 28 17:10:18 2011 +0100 @@ -261,17 +261,19 @@ * conversions resulting into NaNs and rounding. */ public static String substringF(String value, double start) { - try { + if (Double.isNaN(start)) + return(EMPTYSTRING); + final int strlen = value.length(); int istart = (int)Math.round(start) - 1; - if (Double.isNaN(start)) return(EMPTYSTRING); - if (istart > strlen) return(EMPTYSTRING); - if (istart < 1) istart = 0; - + if (istart > strlen) + return(EMPTYSTRING); + if (istart < 1) + istart = 0; + try { return value.substring(istart); - } - catch (IndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException e) { runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); return null; } @@ -282,26 +284,31 @@ * conversions resulting into NaNs and rounding. */ public static String substringF(String value, double start, double length) { - try { - final int strlen = value.length(); - int istart = (int)Math.round(start) - 1; - int isum = istart + (int)Math.round(length); - - if (Double.isInfinite(length)) isum = Integer.MAX_VALUE; + if (Double.isInfinite(start) || + Double.isNaN(start) || + Double.isNaN(length)) + return(EMPTYSTRING); - if (Double.isNaN(start) || Double.isNaN(length)) + int istart = (int)Math.round(start) - 1; + final int isum; + if (Double.isInfinite(length)) + isum = Integer.MAX_VALUE; + else + isum = istart + (int)Math.round(length); + + final int strlen = value.length(); + if (isum < 0 || istart > strlen) return(EMPTYSTRING); - if (Double.isInfinite(start)) return(EMPTYSTRING); - if (istart > strlen) return(EMPTYSTRING); - if (isum < 0) return(EMPTYSTRING); - if (istart < 0) istart = 0; + if (istart < 0) + istart = 0; + + try { if (isum > strlen) return value.substring(istart); else return value.substring(istart, isum); - } - catch (IndexOutOfBoundsException e) { + } catch (IndexOutOfBoundsException e) { runTimeError(RUN_TIME_INTERNAL_ERR, "substring()"); return null; }
--- a/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -1377,6 +1377,8 @@ _parameters = null; _indentNumber = 0; setOutputProperties (null); + _tohFactory = null; + _ostream = null; } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/DeferredDocumentImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -40,7 +40,7 @@ * * @xerces.internal * - * @version $Id: DeferredDocumentImpl.java,v 1.7 2009/12/01 06:12:02 joehw Exp $ + * @version $Id: DeferredDocumentImpl.java,v 1.9 2010/08/11 07:18:39 joehw Exp $ * @since PR-DOM-Level-1-19980818. */ public class DeferredDocumentImpl @@ -1875,7 +1875,7 @@ while (start <= end) { // is this the one we're looking for? - int middle = (start + end) / 2; + int middle = (start + end) >>> 1; int value = values[middle]; if (DEBUG_IDS) { System.out.print(" value: "+value+", target: "+target+" // ");
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/DocumentImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -69,13 +69,14 @@ * <p> * <b>Note:</b> When any node in the document is serialized, the * entire document is serialized along with it. - * + * * @xerces.internal * * @author Arnaud Le Hors, IBM * @author Joe Kesselman, IBM * @author Andy Clark, IBM * @author Ralf Pfeiffer, IBM + * @version $Id: DocumentImpl.java,v 1.6 2010/07/20 20:25:24 joehw Exp $ * @since PR-DOM-Level-1-19980818. */ public class DocumentImpl @@ -160,7 +161,7 @@ // experimental newdoc.mutationEvents = mutationEvents; - return newdoc; + return newdoc; } // cloneNode(boolean):Node @@ -214,7 +215,7 @@ NodeFilter filter, boolean entityReferenceExpansion) { - + if (root == null) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null); throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); @@ -263,7 +264,7 @@ NodeFilter filter, boolean entityReferenceExpansion) { - if (root == null) { + if (root == null) { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null); throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); } @@ -403,17 +404,17 @@ * @since WD-DOM-Level-2-19990923 */ public Event createEvent(String type) - throws DOMException { - if (type.equalsIgnoreCase("Events") || "Event".equals(type)) - return new EventImpl(); - if (type.equalsIgnoreCase("MutationEvents") || + throws DOMException { + if (type.equalsIgnoreCase("Events") || "Event".equals(type)) + return new EventImpl(); + if (type.equalsIgnoreCase("MutationEvents") || "MutationEvent".equals(type)) - return new MutationEventImpl(); - else { + return new MutationEventImpl(); + else { String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "NOT_SUPPORTED_ERR", null); - throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); + throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); } - } + } /** * Sets whether the DOM implementation generates mutation events @@ -477,18 +478,18 @@ * are hung from the nodeListeners Vector. * <p> * I considered using two vectors -- one for capture, - * one for bubble -- but decided that since the list of listeners + * one for bubble -- but decided that since the list of listeners * is probably short in most cases, it might not be worth spending * the space. ***** REVISIT WHEN WE HAVE MORE EXPERIENCE. */ class LEntry implements Serializable { - private static final long serialVersionUID = 3258416144514626360L; + private static final long serialVersionUID = -8426757059492421631L; String type; EventListener listener; boolean useCapture; - - /** NON-DOM INTERNAL: Constructor for Listener list Entry + + /** NON-DOM INTERNAL: Constructor for Listener list Entry * @param type Event name (NOT event group!) to listen for. * @param listener Who gets called when event is dispatched * @param useCaptue True iff listener is registered on @@ -502,7 +503,7 @@ } } // LEntry - + /** * Introduced in DOM Level 2. <p> Register an event listener with this * Node. A listener may be independently registered as both Capturing and @@ -521,18 +522,18 @@ // a listener to dispatch to if (type == null || type.equals("") || listener == null) return; - + // Each listener may be registered only once per type per phase. // Simplest way to code that is to zap the previous entry, if any. removeEventListener(node, type, listener, useCapture); - + Vector nodeListeners = getEventListeners(node); if(nodeListeners == null) { nodeListeners = new Vector(); setEventListeners(node, nodeListeners); } nodeListeners.addElement(new LEntry(type, listener, useCapture)); - + // Record active listener LCount lc = LCount.lookup(type); if (useCapture) { @@ -545,7 +546,7 @@ } } // addEventListener(NodeImpl,String,EventListener,boolean) :void - + /** * Introduced in DOM Level 2. <p> Deregister an event listener previously * registered with this Node. A listener must be independently removed @@ -568,12 +569,12 @@ if (nodeListeners == null) return; - // Note that addListener has previously ensured that + // Note that addListener has previously ensured that // each listener may be registered only once per type per phase. // count-down is OK for deletions! for (int i = nodeListeners.size() - 1; i >= 0; --i) { LEntry le = (LEntry) nodeListeners.elementAt(i); - if (le.useCapture == useCapture && le.listener == listener && + if (le.useCapture == useCapture && le.listener == listener && le.type.equals(type)) { nodeListeners.removeElementAt(i); // Storage management: Discard empty listener lists @@ -598,35 +599,35 @@ protected void copyEventListeners(NodeImpl src, NodeImpl tgt) { Vector nodeListeners = getEventListeners(src); - if (nodeListeners == null) { - return; - } - setEventListeners(tgt, (Vector) nodeListeners.clone()); + if (nodeListeners == null) { + return; + } + setEventListeners(tgt, (Vector) nodeListeners.clone()); } /** * Introduced in DOM Level 2. <p> - * Distribution engine for DOM Level 2 Events. + * Distribution engine for DOM Level 2 Events. * <p> * Event propagation runs as follows: * <ol> * <li>Event is dispatched to a particular target node, which invokes * this code. Note that the event's stopPropagation flag is - * cleared when dispatch begins; thereafter, if it has + * cleared when dispatch begins; thereafter, if it has * been set before processing of a node commences, we instead * immediately advance to the DEFAULT phase. * <li>The node's ancestors are established as destinations for events. - * For capture and bubble purposes, node ancestry is determined at - * the time dispatch starts. If an event handler alters the document - * tree, that does not change which nodes will be informed of the event. - * <li>CAPTURING_PHASE: Ancestors are scanned, root to target, for - * Capturing listeners. If found, they are invoked (see below). - * <li>AT_TARGET: + * For capture and bubble purposes, node ancestry is determined at + * the time dispatch starts. If an event handler alters the document + * tree, that does not change which nodes will be informed of the event. + * <li>CAPTURING_PHASE: Ancestors are scanned, root to target, for + * Capturing listeners. If found, they are invoked (see below). + * <li>AT_TARGET: * Event is dispatched to NON-CAPTURING listeners on the * target node. Note that capturing listeners on this node are _not_ * invoked. * <li>BUBBLING_PHASE: Ancestors are scanned, target to root, for - * non-capturing listeners. + * non-capturing listeners. * <li>Default processing: Some DOMs have default behaviors bound to * specific nodes. If this DOM does, and if the event's preventDefault * flag has not been set, we now return to the target node and process @@ -640,7 +641,7 @@ * <p> * If an event handler itself causes events to be dispatched, they are * processed synchronously, before processing resumes - * on the event which triggered them. Please be aware that this may + * on the event which triggered them. Please be aware that this may * result in events arriving at listeners "out of order" relative * to the actual sequence of requests. * <p> @@ -649,14 +650,14 @@ * I believe the DOM's intent is that event objects be redispatchable, * though it isn't stated in those terms. * @param node node to dispatch to - * @param event the event object to be dispatched to + * @param event the event object to be dispatched to * registered EventListeners * @return true if the event's <code>preventDefault()</code> * method was invoked by an EventListener; otherwise false. */ protected boolean dispatchEvent(NodeImpl node, Event event) { if (event == null) return false; - + // Can't use anyone else's implementation, since there's no public // API for setting the event's processing-state fields. EventImpl evt = (EventImpl)event; @@ -667,7 +668,7 @@ String msg = DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "UNSPECIFIED_EVENT_TYPE_ERR", null); throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR, msg); } - + // If nobody is listening for this event, discard immediately LCount lc = LCount.lookup(evt.getType()); if (lc.total == 0) @@ -680,12 +681,12 @@ evt.target = node; evt.stopPropagation = false; evt.preventDefault = false; - + // Capture pre-event parentage chain, not including target; // use pre-event-dispatch ancestors even if event handlers mutate // document and change the target's context. // Note that this is parents ONLY; events do not - // cross the Attr/Element "blood/brain barrier". + // cross the Attr/Element "blood/brain barrier". // DOMAttrModified. which looks like an exception, // is issued to the Element rather than the Attr // and causes a _second_ DOMSubtreeModified in the Element's @@ -698,11 +699,11 @@ p = n; n = n.getParentNode(); } - + // CAPTURING_PHASE: if (lc.captures > 0) { evt.eventPhase = Event.CAPTURING_PHASE; - // Ancestors are scanned, root to target, for + // Ancestors are scanned, root to target, for // Capturing listeners. for (int j = pv.size() - 1; j >= 0; --j) { if (evt.stopPropagation) @@ -731,8 +732,8 @@ } } } - - + + // Both AT_TARGET and BUBBLE use non-capturing listeners. if (lc.bubbles > 0) { // AT_TARGET PHASE: Event is dispatched to NON-CAPTURING listeners @@ -795,7 +796,7 @@ } } } - + // DEFAULT PHASE: Some DOMs have default behaviors bound to specific // nodes. If this DOM does, and if the event's preventDefault flag has // not been set, we now return to the target node and process its @@ -807,7 +808,7 @@ // DO_DEFAULT_OPERATION } - return evt.preventDefault; + return evt.preventDefault; } // dispatchEvent(NodeImpl,Event) :boolean /** @@ -817,7 +818,7 @@ * <p> * Similar to code in dispatchingEventToSubtree however this method * is only used on the target node and does not start a dispatching chain - * on the sibling of the target node as this is not part of the subtree + * on the sibling of the target node as this is not part of the subtree * ***** At the moment I'm being sloppy and using the normal * capture dispatcher on every node. This could be optimized hugely * by writing a capture engine that tracks our position in the tree to @@ -826,7 +827,7 @@ * @param e event to be sent to that node and its subtree */ protected void dispatchEventToSubtree(Node n, Event e) { - + ((NodeImpl) n).dispatchEvent(e); if (n.getNodeType() == Node.ELEMENT_NODE) { NamedNodeMap a = n.getAttributes(); @@ -834,40 +835,40 @@ dispatchingEventToSubtree(a.item(i), e); } dispatchingEventToSubtree(n.getFirstChild(), e); - + } // dispatchEventToSubtree(NodeImpl,Node,Event) :void /** * Dispatches event to the target node's descendents recursively - * + * * @param n node to dispatch to * @param e event to be sent to that node and its subtree */ protected void dispatchingEventToSubtree(Node n, Event e) { - if (n==null) - return; - - // ***** Recursive implementation. This is excessively expensive, + if (n==null) + return; + + // ***** Recursive implementation. This is excessively expensive, // and should be replaced in conjunction with optimization // mentioned above. - ((NodeImpl) n).dispatchEvent(e); + ((NodeImpl) n).dispatchEvent(e); if (n.getNodeType() == Node.ELEMENT_NODE) { NamedNodeMap a = n.getAttributes(); for (int i = a.getLength() - 1; i >= 0; --i) dispatchingEventToSubtree(a.item(i), e); } - dispatchingEventToSubtree(n.getFirstChild(), e); + dispatchingEventToSubtree(n.getFirstChild(), e); dispatchingEventToSubtree(n.getNextSibling(), e); } - + /** * NON-DOM INTERNAL: Return object for getEnclosingAttr. Carries - * (two values, the Attr node affected (if any) and its previous + * (two values, the Attr node affected (if any) and its previous * string value. Simple struct, no methods. */ class EnclosingAttr implements Serializable { - private static final long serialVersionUID = 3257001077260759859L; + private static final long serialVersionUID = 5208387723391647216L; AttrImpl node; String oldvalue; } @@ -887,7 +888,7 @@ MutationEvent.MODIFICATION); else dispatchAggregateEvents(node, null, null, (short) 0); - + } // dispatchAggregateEvents(NodeImpl,EnclosingAttr) :void /** @@ -897,10 +898,10 @@ * mutation operation, even if that involves multiple changes to * the DOM. * For example, if a DOM operation makes multiple changes to a single - * Attr before returning, it would be nice to generate only one + * Attr before returning, it would be nice to generate only one * DOMAttrModified, and multiple changes over larger scope but within - * a recognizable single subtree might want to generate only one - * DOMSubtreeModified, sent to their lowest common ancestor. + * a recognizable single subtree might want to generate only one + * DOMSubtreeModified, sent to their lowest common ancestor. * <p> * To manage this, use the "internal" versions of insert and remove * with MUTATION_LOCAL, then make an explicit call to this routine @@ -936,7 +937,7 @@ } } // DOMSubtreeModified gets sent to the lowest common root of a - // set of changes. + // set of changes. // "This event is dispatched after all other events caused by the // mutation have been fired." LCount lc = LCount.lookup(MutationEventImpl.DOM_SUBTREE_MODIFIED); @@ -964,12 +965,12 @@ * preparation for later generating DOMAttrModified events. * Determines whether this node is within an Attr * @param node node to get enclosing attribute for - * @return either a description of that Attr, or null if none such. + * @return either a description of that Attr, or null if none such. */ protected void saveEnclosingAttr(NodeImpl node) { savedEnclosingAttr = null; // MUTATION PREPROCESSING AND PRE-EVENTS: - // If we're within the scope of an Attr and DOMAttrModified + // If we're within the scope of an Attr and DOMAttrModified // was requested, we need to preserve its previous value for // that event. LCount lc = LCount.lookup(MutationEventImpl.DOM_ATTR_MODIFIED); @@ -1002,9 +1003,9 @@ */ void modifyingCharacterData(NodeImpl node, boolean replace) { if (mutationEvents) { - if (!replace) { - saveEnclosingAttr(node); - } + if (!replace) { + saveEnclosingAttr(node); + } } } @@ -1013,38 +1014,38 @@ */ void modifiedCharacterData(NodeImpl node, String oldvalue, String value, boolean replace) { if (mutationEvents) { - if (!replace) { - // MUTATION POST-EVENTS: - LCount lc = - LCount.lookup(MutationEventImpl.DOM_CHARACTER_DATA_MODIFIED); - if (lc.total > 0) { - MutationEvent me = new MutationEventImpl(); - me.initMutationEvent( - MutationEventImpl.DOM_CHARACTER_DATA_MODIFIED, - true, false, null, - oldvalue, value, null, (short) 0); - dispatchEvent(node, me); - } - - // Subroutine: Transmit DOMAttrModified and DOMSubtreeModified, - // if required. (Common to most kinds of mutation) - dispatchAggregateEvents(node, savedEnclosingAttr); - } // End mutation postprocessing + if (!replace) { + // MUTATION POST-EVENTS: + LCount lc = + LCount.lookup(MutationEventImpl.DOM_CHARACTER_DATA_MODIFIED); + if (lc.total > 0) { + MutationEvent me = new MutationEventImpl(); + me.initMutationEvent( + MutationEventImpl.DOM_CHARACTER_DATA_MODIFIED, + true, false, null, + oldvalue, value, null, (short) 0); + dispatchEvent(node, me); + } + + // Subroutine: Transmit DOMAttrModified and DOMSubtreeModified, + // if required. (Common to most kinds of mutation) + dispatchAggregateEvents(node, savedEnclosingAttr); + } // End mutation postprocessing } } - + /** * A method to be called when a character data node has been replaced */ void replacedCharacterData(NodeImpl node, String oldvalue, String value) { - //now that we have finished replacing data, we need to perform the same actions - //that are required after a character data node has been modified - //send the value of false for replace parameter so that mutation - //events if appropriate will be initiated - modifiedCharacterData(node, oldvalue, value, false); + //now that we have finished replacing data, we need to perform the same actions + //that are required after a character data node has been modified + //send the value of false for replace parameter so that mutation + //events if appropriate will be initiated + modifiedCharacterData(node, oldvalue, value, false); } - - + + /** * A method to be called when a node is about to be inserted in the tree. @@ -1112,14 +1113,14 @@ dispatchAggregateEvents(node, savedEnclosingAttr); } } - + // notify the range of insertions if (ranges != null) { int size = ranges.size(); for (int i = 0; i != size; i++) { ((RangeImpl)ranges.elementAt(i)).insertedNodeFromDOM(newInternal); } - } + } } /** @@ -1146,7 +1147,7 @@ // mutation events if (mutationEvents) { // MUTATION PREPROCESSING AND PRE-EVENTS: - // If we're within the scope of an Attr and DOMAttrModified + // If we're within the scope of an Attr and DOMAttrModified // was requested, we need to preserve its previous value for // that event. if (!replace) { @@ -1211,14 +1212,14 @@ saveEnclosingAttr(node); } } - + /** * A method to be called when character data is about to be replaced in the tree. */ void replacingData (NodeImpl node) { - if (mutationEvents) { - saveEnclosingAttr(node); - } + if (mutationEvents) { + saveEnclosingAttr(node); + } } /** @@ -1267,7 +1268,7 @@ // that the Attr is still attached to an owner. This code is // similar but dispatches to the previous owner, "element". if (mutationEvents) { - // If we have to send DOMAttrModified (determined earlier), + // If we have to send DOMAttrModified (determined earlier), // do so. LCount lc = LCount.lookup(MutationEventImpl.DOM_ATTR_MODIFIED); if (lc.total > 0) { @@ -1285,20 +1286,20 @@ dispatchAggregateEvents(oldOwner, null, null, (short) 0); } } - + /** * A method to be called when an attribute node has been renamed */ void renamedAttrNode(Attr oldAt, Attr newAt) { - // REVISIT: To be implemented!!! + // REVISIT: To be implemented!!! } /** * A method to be called when an element has been renamed */ void renamedElement(Element oldEl, Element newEl) { - // REVISIT: To be implemented!!! + // REVISIT: To be implemented!!! } } // class DocumentImpl
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/NodeListCache.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/NodeListCache.java Wed Sep 28 17:10:18 2011 +0100 @@ -25,16 +25,17 @@ /** * This class is used, via a pool managed on CoreDocumentImpl, in ParentNode to * improve performance of the NodeList accessors, getLength() and item(i). - * + * * @xerces.internal - * + * * @author Arnaud Le Hors, IBM * + * @version $Id: NodeListCache.java,v 1.6 2010/07/20 20:25:25 joehw Exp $ */ class NodeListCache implements Serializable { /** Serialization version. */ - private static final long serialVersionUID = 3258135743263224377L; + private static final long serialVersionUID = -7927529254918631002L; /** Cached node list length. */ int fLength = -1; @@ -56,3 +57,4 @@ fOwner = owner; } } +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/PSVIElementNSImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/dom/PSVIElementNSImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -30,45 +30,46 @@ /** * Element namespace implementation; stores PSVI element items. - * + * * @xerces.internal - * + * * @author Sandy Gao, IBM - * + * + * @version $Id: PSVIElementNSImpl.java,v 1.6 2010/08/20 18:51:54 joehw Exp $ */ public class PSVIElementNSImpl extends ElementNSImpl implements ElementPSVI { /** Serialization version. */ static final long serialVersionUID = 6815489624636016068L; - + /** * Construct an element node. */ - public PSVIElementNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI, + public PSVIElementNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI, String qualifiedName, String localName) { super(ownerDocument, namespaceURI, qualifiedName, localName); } - + /** * Construct an element node. */ - public PSVIElementNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI, + public PSVIElementNSImpl(CoreDocumentImpl ownerDocument, String namespaceURI, String qualifiedName) { super(ownerDocument, namespaceURI, qualifiedName); } - + /** element declaration */ protected XSElementDeclaration fDeclaration = null; /** type of element, could be xsi:type */ protected XSTypeDefinition fTypeDecl = null; - /** true if clause 3.2 of Element Locally Valid (Element) (3.3.4) - * is satisfied, otherwise false + /** true if clause 3.2 of Element Locally Valid (Element) (3.3.4) + * is satisfied, otherwise false */ protected boolean fNil = false; - /** false if the element value was provided by the schema; true otherwise. + /** false if the element value was provided by the schema; true otherwise. */ protected boolean fSpecified = true; @@ -104,7 +105,7 @@ /** the schema information property */ protected XSModel fSchemaInformation = null; - + // // ElementPSVI methods // @@ -131,7 +132,7 @@ } /** - * [schema specified] + * [schema specified] * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-schema_specified">XML Schema Part 1: Structures [schema specified]</a> * @return false value was specified in schema, true value comes from the infoset */ @@ -186,9 +187,9 @@ } /** - * [notation] + * [notation] * @see <a href="http://www.w3.org/TR/xmlschema-1/#e-notation>XML Schema Part 1: Structures [notation]</a> - * @return The notation declaration. + * @return The notation declaration. */ public XSNotationDeclaration getNotation() { return fNotation; @@ -196,20 +197,20 @@ /** * An item isomorphic to the type definition used to validate this element. - * + * * @return a type declaration */ public XSTypeDefinition getTypeDefinition() { return fTypeDecl; } - + /** * If and only if that type definition is a simple type definition * with {variety} union, or a complex type definition whose {content type} * is a simple thype definition with {variety} union, then an item isomorphic * to that member of the union's {member type definitions} which actually * validated the element item's normalized value. - * + * * @return a simple type declaration */ public XSSimpleTypeDefinition getMemberTypeDefinition() { @@ -219,7 +220,7 @@ /** * An item isomorphic to the element declaration used to validate * this element. - * + * * @return an element declaration */ public XSElementDeclaration getElementDeclaration() { @@ -235,10 +236,10 @@ public XSModel getSchemaInformation() { return fSchemaInformation; } - + /** * Copy PSVI properties from another psvi item. - * + * * @param attr the source of attribute PSVI items */ public void setPSVI(ElementPSVI elem) { @@ -256,6 +257,7 @@ this.fItemValueTypes = elem.getItemValueTypes(); this.fMemberType = elem.getMemberTypeDefinition(); this.fSpecified = elem.getIsSchemaSpecified(); + this.fNil = elem.getNil(); } /* (non-Javadoc) @@ -278,16 +280,16 @@ public ShortList getItemValueTypes() { return this.fItemValueTypes; } - + // REVISIT: Forbid serialization of PSVI DOM until // we support object serialization of grammars -- mrglavas - + private void writeObject(ObjectOutputStream out) throws IOException { throw new NotSerializableException(getClass().getName()); } - private void readObject(ObjectInputStream in) + private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { throw new NotSerializableException(getClass().getName()); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/Constants.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/Constants.java Wed Sep 28 17:10:18 2011 +0100 @@ -30,7 +30,7 @@ * * @author Andy Clark, IBM * - * @version $Id: Constants.java,v 1.10 2009/08/04 05:07:19 joehw Exp $ + * @version $Id: Constants.java,v 1.12 2010/08/11 07:18:39 joehw Exp $ */ public final class Constants { @@ -289,7 +289,10 @@ /** Validate datatypes feature ("validation/validate-datatypes"). */ public static final String VALIDATE_DATATYPES_FEATURE = "validation/validate-datatypes"; - + + /** Balance syntax trees feature ("validation/balance-syntax-trees"). */ + public static final String BALANCE_SYNTAX_TREES = "validation/balance-syntax-trees"; + /** Notify character references feature (scanner/notify-char-refs"). */ public static final String NOTIFY_CHAR_REFS_FEATURE = "scanner/notify-char-refs"; @@ -380,6 +383,8 @@ /** Security manager property ("security-manager"). */ public static final String SECURITY_MANAGER_PROPERTY = "security-manager"; + /** Locale property ("locale"). */ + public static final String LOCALE_PROPERTY = "locale"; /** property identifier: security manager. */ protected static final String SECURITY_MANAGER = @@ -437,7 +442,7 @@ /** Element PSVI is stored in augmentations using string "ELEMENT_PSVI" */ public final static String ELEMENT_PSVI = "ELEMENT_PSVI"; - /* Attribute PSVI is stored in augmentations using string "ATTRIBUTE_PSVI" */ + /** Attribute PSVI is stored in augmentations using string "ATTRIBUTE_PSVI" */ public final static String ATTRIBUTE_PSVI = "ATTRIBUTE_PSVI"; /** @@ -499,7 +504,8 @@ */ public final static String LAST_ENTITY = "LAST_ENTITY"; - // XML version constants + // XML version constants + public final static short XML_VERSION_ERROR = -1; public final static short XML_VERSION_1_0 = 1; public final static short XML_VERSION_1_1 = 2; @@ -555,6 +561,7 @@ DEFAULT_ATTRIBUTE_VALUES_FEATURE, VALIDATE_CONTENT_MODELS_FEATURE, VALIDATE_DATATYPES_FEATURE, + BALANCE_SYNTAX_TREES, NOTIFY_CHAR_REFS_FEATURE, NOTIFY_BUILTIN_REFS_FEATURE, DISALLOW_DOCTYPE_DECL_FEATURE, @@ -586,7 +593,8 @@ SCHEMA_NONS_LOCATION, VALIDATION_MANAGER_PROPERTY, BUFFER_SIZE_PROPERTY, - SECURITY_MANAGER_PROPERTY + SECURITY_MANAGER_PROPERTY, + LOCALE_PROPERTY }; /** Empty enumeration. */
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/XML11DocumentScannerImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -96,19 +96,16 @@ * @author Arnaud Le Hors, IBM * @author Eric Ye, IBM * + * @version $Id: XML11DocumentScannerImpl.java,v 1.5 2010/08/04 20:59:09 joehw Exp $ */ public class XML11DocumentScannerImpl extends XMLDocumentScannerImpl { - - /** Array of 3 strings. */ - private String[] fStrings = new String[3]; - - + /** String buffer. */ - private XMLStringBuffer fStringBuffer = new XMLStringBuffer(); - private XMLStringBuffer fStringBuffer2 = new XMLStringBuffer(); - private XMLStringBuffer fStringBuffer3 = new XMLStringBuffer(); + private final XMLStringBuffer fStringBuffer = new XMLStringBuffer(); + private final XMLStringBuffer fStringBuffer2 = new XMLStringBuffer(); + private final XMLStringBuffer fStringBuffer3 = new XMLStringBuffer(); // // Constructors @@ -129,11 +126,11 @@ * @return Returns the next character on the stream. */ protected int scanContent(XMLStringBuffer content) throws IOException, XNIException { - + fTempString.length = 0; int c = fEntityScanner.scanContent(fTempString); content.append(fTempString); - + if (c == '\r' || c == 0x85 || c == 0x2028) { // happens when there is the character reference // but scanContent doesn't do entity expansions... @@ -157,9 +154,9 @@ // ']]]>' which we might otherwise miss. // if (fEntityScanner.skipChar(']')) { - content.append(']'); + content.append(']'); while (fEntityScanner.skipChar(']')) { - content.append(']'); + content.append(']'); } if (fEntityScanner.skipChar('>')) { reportFatalError("CDEndInContent", null); @@ -178,23 +175,23 @@ /** * Scans an attribute value and normalizes whitespace converting all * whitespace characters to space characters. - * + * * [10] AttValue ::= '"' ([^<&"] | Reference)* '"' | "'" ([^<&'] | Reference)* "'" * * @param value The XMLString to fill in with the value. - * @param nonNormalizedValue The XMLString to fill in with the + * @param nonNormalizedValue The XMLString to fill in with the * non-normalized value. * @param atName The name of the attribute being parsed (for error msgs). - * @param checkEntities true if undeclared entities should be reported as VC violation, + * @param checkEntities true if undeclared entities should be reported as VC violation, * false if undeclared entities should be reported as WFC violation. * @param eleName The name of element to which this attribute belongs. * * @return true if the non-normalized and normalized value are the same - * + * * <strong>Note:</strong> This method uses fStringBuffer2, anything in it * at the time of calling is lost. **/ - protected boolean scanAttributeValue(XMLString value, + protected boolean scanAttributeValue(XMLString value, XMLString nonNormalizedValue, String atName, boolean checkEntities,String eleName) @@ -214,7 +211,7 @@ System.out.println("** scanLiteral -> \"" + value.toString() + "\""); } - + int fromIndex = 0; if (c == quote && (fromIndex = isUnchangedByNormalization(value)) == -1) { /** Both the non-normalized and normalized attribute values are equal. **/ @@ -383,7 +380,7 @@ } } } - else if (c != -1 && XML11Char.isXML11Invalid(c)) { + else if (c != -1 && isInvalidLiteral(c)) { reportFatalError("InvalidCharInAttValue", new Object[] {eleName, atName, Integer.toString(c, 16)}); fEntityScanner.scanChar(); @@ -419,12 +416,12 @@ // XMLScanner methods // // NOTE: this is a carbon copy of the code in XML11DTDScannerImpl; - // we need to override these methods in both places. + // we need to override these methods in both places. // this needs to be refactored!!! - NG /** * Scans public ID literal. * - * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" + * [12] PubidLiteral ::= '"' PubidChar* '"' | "'" (PubidChar - "'")* "'" * [13] PubidChar::= #x20 | #xD | #xA | [a-zA-Z0-9] | [-'()+,./:=?;!*#@$_%] * * The returned string is normalized according to the following rule, @@ -487,21 +484,21 @@ } return dataok; } - + /** * Normalize whitespace in an XMLString converting all whitespace * characters to space characters. */ protected void normalizeWhitespace(XMLString value) { int end = value.offset + value.length; - for (int i = value.offset; i < end; ++i) { + for (int i = value.offset; i < end; ++i) { int c = value.ch[i]; if (XMLChar.isSpace(c)) { value.ch[i] = ' '; } } } - + /** * Normalize whitespace in an XMLString converting all whitespace * characters to space characters. @@ -515,10 +512,10 @@ } } } - + /** * Checks whether this string would be unchanged by normalization. - * + * * @return -1 if the value would be unchanged by normalization, * otherwise the index of the first whitespace character which * would be transformed. @@ -538,49 +535,49 @@ // valid with respect to the version of // XML understood by this scanner. protected boolean isInvalid(int value) { - return (XML11Char.isXML11Invalid(value)); - } // isInvalid(int): boolean + return (XML11Char.isXML11Invalid(value)); + } // isInvalid(int): boolean // returns true if the given character is not - // valid or may not be used outside a character reference + // valid or may not be used outside a character reference // with respect to the version of XML understood by this scanner. protected boolean isInvalidLiteral(int value) { - return (!XML11Char.isXML11ValidLiteral(value)); + return (!XML11Char.isXML11ValidLiteral(value)); } // isInvalidLiteral(int): boolean - // returns true if the given character is + // returns true if the given character is // a valid nameChar with respect to the version of // XML understood by this scanner. protected boolean isValidNameChar(int value) { - return (XML11Char.isXML11Name(value)); + return (XML11Char.isXML11Name(value)); } // isValidNameChar(int): boolean - // returns true if the given character is + // returns true if the given character is // a valid nameStartChar with respect to the version of // XML understood by this scanner. protected boolean isValidNameStartChar(int value) { - return (XML11Char.isXML11NameStart(value)); + return (XML11Char.isXML11NameStart(value)); } // isValidNameStartChar(int): boolean - + // returns true if the given character is // a valid NCName character with respect to the version of // XML understood by this scanner. protected boolean isValidNCName(int value) { return (XML11Char.isXML11NCName(value)); } // isValidNCName(int): boolean - - // returns true if the given character is - // a valid high surrogate for a nameStartChar - // with respect to the version of XML understood + + // returns true if the given character is + // a valid high surrogate for a nameStartChar + // with respect to the version of XML understood // by this scanner. protected boolean isValidNameStartHighSurrogate(int value) { - return XML11Char.isXML11NameHighSurrogate(value); + return XML11Char.isXML11NameHighSurrogate(value); } // isValidNameStartHighSurrogate(int): boolean protected boolean versionSupported(String version) { return (version.equals("1.1") || version.equals("1.0")); } // versionSupported(String): boolean - + // returns the error message key for unsupported // versions of XML with respect to the version of // XML understood by this scanner.
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/XMLStreamReaderImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/XMLStreamReaderImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -58,6 +58,7 @@ import com.sun.org.apache.xerces.internal.util.XMLChar; import com.sun.org.apache.xerces.internal.util.XMLStringBuffer; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; +import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.xml.internal.stream.dtd.DTDGrammarUtil; @@ -803,7 +804,14 @@ public String getAttributeValue(String namespaceURI, String localName) { //State should be either START_ELEMENT or ATTRIBUTE if( fEventType == XMLEvent.START_ELEMENT || fEventType == XMLEvent.ATTRIBUTE) { - return fScanner.getAttributeIterator().getValue(namespaceURI, localName) ; + XMLAttributesImpl attributes = fScanner.getAttributeIterator(); + if (namespaceURI == null) { //sjsxp issue 70 + return attributes.getValue(attributes.getIndexByLocalName(localName)) ; + } else { + return fScanner.getAttributeIterator().getValue( + namespaceURI.length() == 0 ? null : namespaceURI, localName) ; + } + } else{ throw new java.lang.IllegalStateException("Current state is not among the states " + getEventTypeString(XMLEvent.START_ELEMENT) + " , "
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/BalancedDTDGrammar.java Wed Sep 28 17:10:18 2011 +0100 @@ -0,0 +1,289 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.impl.dtd; + +import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.xni.Augmentations; +import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; +import com.sun.org.apache.xerces.internal.xni.XNIException; + +/** + * <p>A DTD grammar that produces balanced syntax trees.</p> + * + * @xerces.internal + * + * @author Michael Glavassevich, IBM + * @version $Id: BalancedDTDGrammar.java,v 1.1 2010/08/11 07:18:38 joehw Exp $ + */ +final class BalancedDTDGrammar extends DTDGrammar { + + // + // Data + // + + /** Mixed. */ + private boolean fMixed; + + /** Stack depth */ + private int fDepth = 0; + + /** Children content model operation stack. */ + private short [] fOpStack = null; + + /** Holder for choice/sequence/leaf groups at each depth. */ + private int [][] fGroupIndexStack; + + /** Sizes of the allocated portions of each int[] in fGroupIndexStack. */ + private int [] fGroupIndexStackSizes; + + // + // Constructors + // + + /** Default constructor. */ + public BalancedDTDGrammar(SymbolTable symbolTable, XMLDTDDescription desc) { + super(symbolTable, desc); + } // BalancedDTDGrammar(SymbolTable,XMLDTDDescription) + + // + // Public methods + // + + /** + * The start of a content model. Depending on the type of the content + * model, specific methods may be called between the call to the + * startContentModel method and the call to the endContentModel method. + * + * @param elementName The name of the element. + * @param augs Additional information that may include infoset + * augmentations. + * @throws XNIException Thrown by handler to signal an error. + */ + public final void startContentModel(String elementName, Augmentations augs) + throws XNIException { + fDepth = 0; + initializeContentModelStacks(); + super.startContentModel(elementName, augs); + } // startContentModel(String) + + /** + * A start of either a mixed or children content model. A mixed + * content model will immediately be followed by a call to the + * <code>pcdata()</code> method. A children content model will + * contain additional groups and/or elements. + * + * @param augs Additional information that may include infoset + * augmentations. + * @throws XNIException Thrown by handler to signal an error. + * + * @see #any + * @see #empty + */ + public final void startGroup(Augmentations augs) throws XNIException { + ++fDepth; + initializeContentModelStacks(); + fMixed = false; + } // startGroup() + + /** + * The appearance of "#PCDATA" within a group signifying a + * mixed content model. This method will be the first called + * following the content model's <code>startGroup()</code>. + * + *@param augs Additional information that may include infoset + * augmentations. + * + * @throws XNIException Thrown by handler to signal an error. + * + * @see #startGroup + */ + public final void pcdata(Augmentations augs) throws XNIException { + fMixed = true; + } // pcdata() + + /** + * A referenced element in a mixed or children content model. + * + * @param elementName The name of the referenced element. + * @param augs Additional information that may include infoset + * augmentations. + * + * @throws XNIException Thrown by handler to signal an error. + */ + public final void element(String elementName, Augmentations augs) throws XNIException { + addToCurrentGroup(addUniqueLeafNode(elementName)); + } // element(String) + + /** + * The separator between choices or sequences of a mixed or children + * content model. + * + * @param separator The type of children separator. + * @param augs Additional information that may include infoset + * augmentations. + * @throws XNIException Thrown by handler to signal an error. + * + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE + */ + public final void separator(short separator, Augmentations augs) throws XNIException { + if (separator == XMLDTDContentModelHandler.SEPARATOR_CHOICE) { + fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_CHOICE; + } + else if (separator == XMLDTDContentModelHandler.SEPARATOR_SEQUENCE) { + fOpStack[fDepth] = XMLContentSpec.CONTENTSPECNODE_SEQ; + } + } // separator(short) + + /** + * The occurrence count for a child in a children content model or + * for the mixed content model group. + * + * @param occurrence The occurrence count for the last element + * or group. + * @param augs Additional information that may include infoset + * augmentations. + * @throws XNIException Thrown by handler to signal an error. + * + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE + */ + public final void occurrence(short occurrence, Augmentations augs) throws XNIException { + if (!fMixed) { + int currentIndex = fGroupIndexStackSizes[fDepth] - 1; + if (occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_ONE) { + fGroupIndexStack[fDepth][currentIndex] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE, fGroupIndexStack[fDepth][currentIndex], -1); + } + else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ZERO_OR_MORE) { + fGroupIndexStack[fDepth][currentIndex] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE, fGroupIndexStack[fDepth][currentIndex], -1); + } + else if ( occurrence == XMLDTDContentModelHandler.OCCURS_ONE_OR_MORE) { + fGroupIndexStack[fDepth][currentIndex] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE, fGroupIndexStack[fDepth][currentIndex], -1); + } + } + } // occurrence(short) + + /** + * The end of a group for mixed or children content models. + * + * @param augs Additional information that may include infoset + * augmentations. + * @throws XNIException Thrown by handler to signal an error. + */ + public final void endGroup(Augmentations augs) throws XNIException { + final int length = fGroupIndexStackSizes[fDepth]; + final int group = length > 0 ? addContentSpecNodes(0, length - 1) : addUniqueLeafNode(null); + --fDepth; + addToCurrentGroup(group); + } // endGroup() + + /** + * The end of the DTD. + * + * @param augs Additional information that may include infoset + * augmentations. + * @throws XNIException Thrown by handler to signal an error. + */ + public final void endDTD(Augmentations augs) throws XNIException { + super.endDTD(augs); + fOpStack = null; + fGroupIndexStack = null; + fGroupIndexStackSizes = null; + } // endDTD() + + // + // Protected methods + // + + /** + * Adds the content spec to the given element declaration. + */ + protected final void addContentSpecToElement(XMLElementDecl elementDecl) { + int contentSpec = fGroupIndexStackSizes[0] > 0 ? fGroupIndexStack[0][0] : -1; + setContentSpecIndex(fCurrentElementIndex, contentSpec); + } + + // + // Private methods + // + + /** + * Creates a subtree from the leaf nodes at the current depth. + */ + private int addContentSpecNodes(int begin, int end) { + if (begin == end) { + return fGroupIndexStack[fDepth][begin]; + } + final int middle = (begin + end) >>> 1; + return addContentSpecNode(fOpStack[fDepth], + addContentSpecNodes(begin, middle), + addContentSpecNodes(middle + 1, end)); + } // addContentSpecNodes(int,int) + + /** + * Initialize the stacks which temporarily hold content models. + */ + private void initializeContentModelStacks() { + if (fOpStack == null) { + fOpStack = new short[8]; + fGroupIndexStack = new int [8][]; + fGroupIndexStackSizes = new int [8]; + } + else if (fDepth == fOpStack.length) { + short [] newOpStack = new short[fDepth * 2]; + System.arraycopy(fOpStack, 0, newOpStack, 0, fDepth); + fOpStack = newOpStack; + int [][] newGroupIndexStack = new int[fDepth * 2][]; + System.arraycopy(fGroupIndexStack, 0, newGroupIndexStack, 0, fDepth); + fGroupIndexStack = newGroupIndexStack; + int [] newGroupIndexStackLengths = new int[fDepth * 2]; + System.arraycopy(fGroupIndexStackSizes, 0, newGroupIndexStackLengths, 0, fDepth); + fGroupIndexStackSizes = newGroupIndexStackLengths; + } + fOpStack[fDepth] = -1; + fGroupIndexStackSizes[fDepth] = 0; + } // initializeContentModelStacks() + + /** + * Add XMLContentSpec to the current group. + * + * @param contentSpec handle to the XMLContentSpec to add to the current group + */ + private void addToCurrentGroup(int contentSpec) { + int [] currentGroup = fGroupIndexStack[fDepth]; + int length = fGroupIndexStackSizes[fDepth]++; + if (currentGroup == null) { + currentGroup = new int[8]; + fGroupIndexStack[fDepth] = currentGroup; + } + else if (length == currentGroup.length) { + int [] newGroup = new int[currentGroup.length * 2]; + System.arraycopy(currentGroup, 0, newGroup, 0, currentGroup.length); + currentGroup = newGroup; + fGroupIndexStack[fDepth] = currentGroup; + } + currentGroup[length] = contentSpec; + } // addToCurrentGroup(int) + +} // class BalancedDTDGrammar +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/DTDGrammar.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/DTDGrammar.java Wed Sep 28 17:10:18 2011 +0100 @@ -61,8 +61,8 @@ package com.sun.org.apache.xerces.internal.impl.dtd; +import java.util.ArrayList; import java.util.Hashtable; -import java.util.Vector; import com.sun.org.apache.xerces.internal.impl.dtd.models.CMAny; import com.sun.org.apache.xerces.internal.impl.dtd.models.CMBinOp; @@ -93,7 +93,7 @@ * A DTD grammar. This class implements the XNI handler interfaces * for DTD information so that it can build the approprate validation * structures automatically from the callbacks. - * + * * @xerces.internal * * @author Eric Ye, IBM @@ -101,6 +101,7 @@ * @author Andy Clark, IBM * @author Neil Graham, IBM * + * @version $Id: DTDGrammar.java,v 1.4 2010/08/11 07:18:37 joehw Exp $ */ public class DTDGrammar implements XMLDTDHandler, XMLDTDContentModelHandler, EntityState, Grammar { @@ -264,13 +265,13 @@ private boolean fMixed; /** Temporary qualified name. */ - private QName fQName = new QName(); + private final QName fQName = new QName(); /** Temporary qualified name. */ - private QName fQName2 = new QName(); + private final QName fQName2 = new QName(); /** Temporary Attribute decl. */ - protected XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl(); + protected final XMLAttributeDecl fAttributeDecl = new XMLAttributeDecl(); // for buildSyntaxTree method @@ -558,23 +559,8 @@ //add(or set) this elementDecl to the local cache this.fElementDeclTab.put(name, elementDecl ); - fElementDecl = elementDecl; - - if ((fDepth == 0 || - (fDepth == 1 && elementDecl.type == XMLElementDecl.TYPE_MIXED)) && - fNodeIndexStack != null) { - if (elementDecl.type == XMLElementDecl.TYPE_MIXED) { - int pcdata = addUniqueLeafNode(null); - if (fNodeIndexStack[0] == -1) { - fNodeIndexStack[0] = pcdata; - } - else { - fNodeIndexStack[0] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, - pcdata, fNodeIndexStack[0]); - } - } - setContentSpecIndex(fCurrentElementIndex, fNodeIndexStack[fDepth]); - } + fElementDecl = elementDecl; + addContentSpecToElement(elementDecl); if ( DEBUG ) { System.out.println( "name = " + fElementDecl.name.localpart ); @@ -586,7 +572,7 @@ int chunk = fCurrentElementIndex >> CHUNK_SHIFT; int index = fCurrentElementIndex & CHUNK_MASK; ensureElementDeclCapacity(chunk); - fElementDeclIsExternal[chunk][index] = fReadingExternalDTD? 1 : 0; + fElementDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1 : 0; } // elementDecl(String,String) @@ -716,7 +702,7 @@ int chunk = fCurrentAttributeIndex >> CHUNK_SHIFT; int index = fCurrentAttributeIndex & CHUNK_MASK; ensureAttributeDeclCapacity(chunk); - fAttributeDeclIsExternal[chunk][index] = fReadingExternalDTD ? 1 : 0; + fAttributeDeclIsExternal[chunk][index] = (fReadingExternalDTD || fPEDepth > 0) ? 1 : 0; } // attributeDecl(String,String,String,String[],String,XMLString,XMLString, Augmentations) @@ -743,7 +729,7 @@ if( entityIndex == -1){ entityIndex = createEntityDecl(); boolean isPE = name.startsWith("%"); - boolean inExternal = fReadingExternalDTD; + boolean inExternal = (fReadingExternalDTD || fPEDepth > 0); XMLEntityDecl entityDecl = new XMLEntityDecl(); entityDecl.setValues(name,null,null, null, null, text.toString(), isPE, inExternal); @@ -773,7 +759,7 @@ if( entityIndex == -1){ entityIndex = createEntityDecl(); boolean isPE = name.startsWith("%"); - boolean inExternal = fReadingExternalDTD; + boolean inExternal = (fReadingExternalDTD || fPEDepth > 0); XMLEntityDecl entityDecl = new XMLEntityDecl(); entityDecl.setValues(name, identifier.getPublicId(), identifier.getLiteralSystemId(), @@ -801,7 +787,7 @@ XMLEntityDecl entityDecl = new XMLEntityDecl(); boolean isPE = name.startsWith("%"); - boolean inExternal = fReadingExternalDTD; + boolean inExternal = (fReadingExternalDTD || fPEDepth > 0); entityDecl.setValues(name,identifier.getPublicId(),identifier.getLiteralSystemId(), identifier.getBaseSystemId(), notation, @@ -848,16 +834,17 @@ public void endDTD(Augmentations augs) throws XNIException { fIsImmutable = true; // make sure our description contains useful stuff... - if(fGrammarDescription.getRootName() == null) { + if (fGrammarDescription.getRootName() == null) { // we don't know what the root is; so use possibleRoots... int chunk, index = 0; String currName = null; - Vector elements = new Vector(); - for (int i=0; i < fElementDeclCount; i++) { + final int size = fElementDeclCount; + ArrayList elements = new ArrayList(size); + for (int i = 0; i < size; ++i) { chunk = i >> CHUNK_SHIFT; index = i & CHUNK_MASK; currName = fElementDeclName[chunk][index].rawname; - elements.addElement(currName); + elements.add(currName); } fGrammarDescription.setPossibleRoots(elements); } @@ -1080,8 +1067,8 @@ * augmentations. * @throws XNIException Thrown by handler to signal an error. * - * @see com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE - * @see com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_CHOICE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#SEPARATOR_SEQUENCE */ public void separator(short separator, Augmentations augs) throws XNIException { @@ -1113,9 +1100,9 @@ * augmentations. * @throws XNIException Thrown by handler to signal an error. * - * @see com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE - * @see com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE - * @see com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_ONE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ZERO_OR_MORE + * @see org.apache.xerces.xni.XMLDTDContentModelHandler#OCCURS_ONE_OR_MORE */ public void occurrence(short occurrence, Augmentations augs) throws XNIException { @@ -1241,11 +1228,11 @@ return getElementDeclIndex(elementDeclQName.rawname); } // getElementDeclIndex(QName):int - /** make separate function for getting contentSpecType of element. + /** make separate function for getting contentSpecType of element. * we can avoid setting of the element values. - */ - - public short getContentSpecType(int elementIndex){ + */ + + public short getContentSpecType(int elementIndex){ if (elementIndex < 0 || elementIndex >= fElementDeclCount) { return -1 ; } @@ -1255,12 +1242,12 @@ if(fElementDeclType[chunk][index] == -1){ return -1 ; - } + } else{ - return (short) (fElementDeclType[chunk][index] & LIST_MASK); - } - - }//getContentSpecType + return (short) (fElementDeclType[chunk][index] & LIST_MASK); + } + + }//getContentSpecType /** * getElementDecl @@ -1303,6 +1290,15 @@ } // getElementDecl(int,XMLElementDecl):boolean + QName getElementDeclName(int elementDeclIndex) { + if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { + return null; + } + int chunk = elementDeclIndex >> CHUNK_SHIFT; + int index = elementDeclIndex & CHUNK_MASK; + return fElementDeclName[chunk][index]; + } + // REVISIT: Make this getAttributeDeclCount/getAttributeDeclAt. -Ac /** @@ -1382,7 +1378,6 @@ */ public boolean isCDATAAttribute(QName elName, QName atName) { int elDeclIdx = getElementDeclIndex(elName); - int atDeclIdx = getAttributeDeclIndex(elDeclIdx, atName.rawname); if (getAttributeDecl(elDeclIdx, fAttributeDecl) && fAttributeDecl.simpleType.type != XMLSimpleType.TYPE_CDATA){ return false; @@ -1495,6 +1490,20 @@ } /** + * Returns the index to the content spec for the given element + * declaration, or <code>-1</code> if the element declaration + * index was invalid. + */ + public int getContentSpecIndex(int elementDeclIndex) { + if (elementDeclIndex < 0 || elementDeclIndex >= fElementDeclCount) { + return -1; + } + final int chunk = elementDeclIndex >> CHUNK_SHIFT; + final int index = elementDeclIndex & CHUNK_MASK; + return fElementDeclContentSpecIndex[chunk][index]; + } + + /** * getContentSpecAsString * * @param elementDeclIndex @@ -1565,7 +1574,7 @@ str.append("#PCDATA"); } else if (contentSpec.otherValue != null) { - str.append("##any:uri="+contentSpec.otherValue); + str.append("##any:uri=").append(contentSpec.otherValue); } else if (contentSpec.value == null) { str.append("##any"); @@ -1599,7 +1608,7 @@ str.append("#PCDATA"); } else if (contentSpec.otherValue != null) { - str.append("##any:uri="+contentSpec.otherValue); + str.append("##any:uri=").append(contentSpec.otherValue); } else if (contentSpec.value == null) { str.append("##any"); @@ -1695,6 +1704,26 @@ // /** + * Adds the content spec to the given element declaration. + */ + protected void addContentSpecToElement(XMLElementDecl elementDecl) { + if ((fDepth == 0 || (fDepth == 1 && elementDecl.type == XMLElementDecl.TYPE_MIXED)) && + fNodeIndexStack != null) { + if (elementDecl.type == XMLElementDecl.TYPE_MIXED) { + int pcdata = addUniqueLeafNode(null); + if (fNodeIndexStack[0] == -1) { + fNodeIndexStack[0] = pcdata; + } + else { + fNodeIndexStack[0] = addContentSpecNode(XMLContentSpec.CONTENTSPECNODE_CHOICE, + pcdata, fNodeIndexStack[0]); + } + } + setContentSpecIndex(fCurrentElementIndex, fNodeIndexStack[fDepth]); + } + } + + /** * getElementContentModelValidator * * @param elementDeclIndex @@ -1780,15 +1809,11 @@ int chunk = elementDeclIndex >> CHUNK_SHIFT; int index = elementDeclIndex & CHUNK_MASK; - int scope = elementDecl.scope; - - fElementDeclName[chunk][index].setValues(elementDecl.name); fElementDeclType[chunk][index] = elementDecl.type; fElementDeclContentModelValidator[chunk][index] = elementDecl.contentModelValidator; - if (elementDecl.simpleType.list == true ) { fElementDeclType[chunk][index] |= LIST_FLAG; } @@ -1935,13 +1960,9 @@ fEntityIndexMap.put(entityDecl.name, entityDeclIndex); } - protected int createNotationDecl() { int chunk = fNotationCount >> CHUNK_SHIFT; - int index = fNotationCount & CHUNK_MASK; - ensureNotationDeclCapacity(chunk); - return fNotationCount++; } @@ -2070,7 +2091,7 @@ str.append("#PCDATA"); } else if (contentSpec.value == null && contentSpec.otherValue != null) { - str.append("##any:uri="+contentSpec.otherValue); + str.append("##any:uri=").append(contentSpec.otherValue); } else if (contentSpec.value == null) { str.append("##any"); @@ -2198,7 +2219,7 @@ * models and creates SimpleContentModel objects for those. For the rest * it creates the standard DFA style model. */ - private ContentModelValidator createChildModel(int contentSpecIndex) { + private synchronized ContentModelValidator createChildModel(int contentSpecIndex) { // // Get the content spec node for the element we are working on.
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XML11DTDProcessor.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XML11DTDProcessor.java Wed Sep 28 17:10:18 2011 +0100 @@ -61,20 +61,23 @@ package com.sun.org.apache.xerces.internal.impl.dtd; +import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; +import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl; +import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XML11Char; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; - /** * This class extends XMLDTDProcessor by giving it * the ability to parse XML 1.1 documents correctly. It can also be used * as a DTD loader, so that XML 1.1 external subsets can * be processed correctly (hence it's rather anomalous-appearing * derivation from XMLDTDLoader). - * + * * @xerces.internal * * @author Neil Graham, IBM @@ -113,4 +116,13 @@ return XML11Char.isXML11ValidName(name); } // isValidNmtoken(String): boolean + protected XMLDTDScannerImpl createDTDScanner(SymbolTable symbolTable, + XMLErrorReporter errorReporter, XMLEntityManager entityManager) { + return new XML11DTDScannerImpl(symbolTable, errorReporter, entityManager); + } // createDTDScanner(SymbolTable, XMLErrorReporter, XMLEntityManager) : XMLDTDScannerImpl + + protected short getScannerVersion() { + return Constants.XML_VERSION_1_1; + } // getScannerVersion() : short + } // class XML11DTDProcessor
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDDescription.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDDescription.java Wed Sep 28 17:10:18 2011 +0100 @@ -61,19 +61,21 @@ package com.sun.org.apache.xerces.internal.impl.dtd; +import java.util.ArrayList; +import java.util.Vector; + import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; - import com.sun.org.apache.xerces.internal.util.XMLResourceIdentifierImpl; -import java.util.Vector; /** - * All information specific to DTD grammars. - * + * All information specific to DTD grammars. + * * @xerces.internal - * + * * @author Neil Graham, IBM + * @version $Id: XMLDTDDescription.java,v 1.4 2010/08/11 07:18:38 joehw Exp $ */ public class XMLDTDDescription extends XMLResourceIdentifierImpl implements com.sun.org.apache.xerces.internal.xni.grammars.XMLDTDDescription { @@ -86,7 +88,7 @@ // if we don't know the root name, this stores all elements that // could serve; fPossibleRoots and fRootName cannot both be non-null - protected Vector fPossibleRoots = null; + protected ArrayList fPossibleRoots = null; // Constructors: public XMLDTDDescription(XMLResourceIdentifier id, String rootName) { @@ -130,8 +132,13 @@ } /** Set possible roots **/ + public void setPossibleRoots(ArrayList possibleRoots) { + fPossibleRoots = possibleRoots; + } + + /** Set possible roots **/ public void setPossibleRoots(Vector possibleRoots) { - fPossibleRoots = possibleRoots; + fPossibleRoots = (possibleRoots != null) ? new ArrayList(possibleRoots) : null; } /** @@ -148,50 +155,59 @@ * @return True if they are equal, else false */ public boolean equals(Object desc) { - if(!(desc instanceof XMLGrammarDescription)) return false; - if (!getGrammarType().equals(((XMLGrammarDescription)desc).getGrammarType())) { - return false; - } + if (!(desc instanceof XMLGrammarDescription)) return false; + if (!getGrammarType().equals(((XMLGrammarDescription)desc).getGrammarType())) { + return false; + } // assume it's a DTDDescription XMLDTDDescription dtdDesc = (XMLDTDDescription)desc; - if(fRootName != null) { - if((dtdDesc.fRootName) != null && !dtdDesc.fRootName.equals(fRootName)) { + if (fRootName != null) { + if ((dtdDesc.fRootName) != null && !dtdDesc.fRootName.equals(fRootName)) { return false; - } else if(dtdDesc.fPossibleRoots != null && !dtdDesc.fPossibleRoots.contains(fRootName)) { + } + else if (dtdDesc.fPossibleRoots != null && !dtdDesc.fPossibleRoots.contains(fRootName)) { return false; } - } else if(fPossibleRoots != null) { - if(dtdDesc.fRootName != null) { - if(!fPossibleRoots.contains(dtdDesc.fRootName)) { + } + else if (fPossibleRoots != null) { + if (dtdDesc.fRootName != null) { + if (!fPossibleRoots.contains(dtdDesc.fRootName)) { return false; } - } else if(dtdDesc.fPossibleRoots == null) { + } + else if (dtdDesc.fPossibleRoots == null) { return false; - } else { + } + else { boolean found = false; - for(int i = 0; i<fPossibleRoots.size(); i++) { - String root = (String)fPossibleRoots.elementAt(i); + final int size = fPossibleRoots.size(); + for (int i = 0; i < size; ++i) { + String root = (String) fPossibleRoots.get(i); found = dtdDesc.fPossibleRoots.contains(root); - if(found) break; + if (found) break; } - if(!found) return false; + if (!found) return false; } } // if we got this far we've got a root match... try other two fields, // since so many different DTD's have roots in common: - if(fExpandedSystemId != null) { - if(!fExpandedSystemId.equals(dtdDesc.fExpandedSystemId)) + if (fExpandedSystemId != null) { + if (!fExpandedSystemId.equals(dtdDesc.fExpandedSystemId)) { return false; + } } - else if(dtdDesc.fExpandedSystemId != null) + else if (dtdDesc.fExpandedSystemId != null) { return false; - if(fPublicId != null) { - if(!fPublicId.equals(dtdDesc.fPublicId)) - return false; } - else if(dtdDesc.fPublicId != null) + if (fPublicId != null) { + if (!fPublicId.equals(dtdDesc.fPublicId)) { + return false; + } + } + else if (dtdDesc.fPublicId != null) { return false; - return true; + } + return true; } /** @@ -201,11 +217,14 @@ * @return The hash code */ public int hashCode() { - if(fExpandedSystemId != null) + if (fExpandedSystemId != null) { return fExpandedSystemId.hashCode(); - if(fPublicId != null) + } + if (fPublicId != null) { return fPublicId.hashCode(); + } // give up; hope .equals can handle it: return 0; } } // class XMLDTDDescription +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDLoader.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDLoader.java Wed Sep 28 17:10:18 2011 +0100 @@ -61,6 +61,11 @@ package com.sun.org.apache.xerces.internal.impl.dtd; +import java.io.EOFException; +import java.io.IOException; +import java.io.StringReader; +import java.util.Locale; + import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; @@ -79,9 +84,6 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLEntityResolver; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; -import java.util.Locale; -import java.io.IOException; -import java.io.EOFException; /** * The DTD loader. The loader knows how to build grammars from XMLInputSources. @@ -99,11 +101,13 @@ * <li>http://apache.org/xml/properties/internal/grammar-pool</li> * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li> * </ul> - * + * * @xerces.internal * * @author Neil Graham, IBM + * @author Michael Glavassevich, IBM * + * @version $Id: XMLDTDLoader.java,v 1.5 2010/08/11 07:18:37 joehw Exp $ */ public class XMLDTDLoader extends XMLDTDProcessor @@ -119,12 +123,18 @@ protected static final String STANDARD_URI_CONFORMANT_FEATURE = Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE; + /** Feature identifier: balance syntax trees. */ + protected static final String BALANCE_SYNTAX_TREES = + Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES; + // recognized features: - private static final String[] RECOGNIZED_FEATURES = { + private static final String[] LOADER_RECOGNIZED_FEATURES = { VALIDATION, WARN_ON_DUPLICATE_ATTDEF, + WARN_ON_UNDECLARED_ELEMDEF, NOTIFY_CHAR_REFS, - STANDARD_URI_CONFORMANT_FEATURE + STANDARD_URI_CONFORMANT_FEATURE, + BALANCE_SYNTAX_TREES }; // property identifiers @@ -137,6 +147,10 @@ public static final String ENTITY_RESOLVER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; + /** Property identifier: locale. */ + public static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Recognized properties. */ private static final String[] LOADER_RECOGNIZED_PROPERTIES = { SYMBOL_TABLE, @@ -145,11 +159,15 @@ ENTITY_RESOLVER, GRAMMAR_POOL, DTD_VALIDATOR, + LOCALE }; // enforcing strict uri? private boolean fStrictURI = false; + /** Controls whether the DTD grammar produces balanced syntax trees. */ + private boolean fBalanceSyntaxTrees = false; + /** Entity resolver . */ protected XMLEntityResolver fEntityResolver; @@ -203,7 +221,7 @@ fEntityManager = new XMLEntityManager(); } fEntityManager.setProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY, errorReporter); - fDTDScanner = new XMLDTDScannerImpl(fSymbolTable, fErrorReporter, fEntityManager); + fDTDScanner = createDTDScanner(fSymbolTable, fErrorReporter, fEntityManager); fDTDScanner.setDTDHandler(this); fDTDScanner.setDTDContentModelHandler(this); reset(); @@ -212,6 +230,15 @@ // XMLGrammarLoader methods /** + * Returns a list of feature identifiers that are recognized by + * this component. This method may return null if no features + * are recognized by this component. + */ + public String[] getRecognizedFeatures() { + return (String[])(LOADER_RECOGNIZED_FEATURES.clone()); + } // getRecognizedFeatures():String[] + + /** * Sets the state of a feature. This method is called by the component * manager any time after reset when a feature changes state. * <p> @@ -228,15 +255,25 @@ */ public void setFeature(String featureId, boolean state) throws XMLConfigurationException { - if(featureId.equals(VALIDATION)) { + if (featureId.equals(VALIDATION)) { fValidation = state; - } else if(featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) { + } + else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) { fWarnDuplicateAttdef = state; - } else if(featureId.equals(NOTIFY_CHAR_REFS)) { + } + else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) { + fWarnOnUndeclaredElemdef = state; + } + else if (featureId.equals(NOTIFY_CHAR_REFS)) { fDTDScanner.setFeature(featureId, state); - } else if(featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) { + } + else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) { fStrictURI = state; - } else { + } + else if (featureId.equals(BALANCE_SYNTAX_TREES)) { + fBalanceSyntaxTrees = state; + } + else { throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, featureId); } } // setFeature(String,boolean) @@ -259,17 +296,25 @@ */ public Object getProperty(String propertyId) throws XMLConfigurationException { - if(propertyId.equals( SYMBOL_TABLE)) { + if (propertyId.equals(SYMBOL_TABLE)) { return fSymbolTable; - } else if(propertyId.equals( ERROR_REPORTER)) { + } + else if (propertyId.equals(ERROR_REPORTER)) { return fErrorReporter; - } else if(propertyId.equals( ERROR_HANDLER)) { + } + else if (propertyId.equals(ERROR_HANDLER)) { return fErrorReporter.getErrorHandler(); - } else if(propertyId.equals( ENTITY_RESOLVER)) { + } + else if (propertyId.equals(ENTITY_RESOLVER)) { return fEntityResolver; - } else if(propertyId.equals( GRAMMAR_POOL)) { + } + else if (propertyId.equals(LOCALE)) { + return getLocale(); + } + else if (propertyId.equals(GRAMMAR_POOL)) { return fGrammarPool; - } else if(propertyId.equals( DTD_VALIDATOR)) { + } + else if (propertyId.equals(DTD_VALIDATOR)) { return fValidator; } throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, propertyId); @@ -292,11 +337,12 @@ */ public void setProperty(String propertyId, Object value) throws XMLConfigurationException { - if(propertyId.equals( SYMBOL_TABLE)) { + if (propertyId.equals(SYMBOL_TABLE)) { fSymbolTable = (SymbolTable)value; fDTDScanner.setProperty(propertyId, value); fEntityManager.setProperty(propertyId, value); - } else if(propertyId.equals( ERROR_REPORTER)) { + } + else if(propertyId.equals(ERROR_REPORTER)) { fErrorReporter = (XMLErrorReporter)value; // Add XML message formatter if there isn't one. if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { @@ -306,13 +352,21 @@ } fDTDScanner.setProperty(propertyId, value); fEntityManager.setProperty(propertyId, value); - } else if(propertyId.equals( ERROR_HANDLER)) { + } + else if (propertyId.equals(ERROR_HANDLER)) { fErrorReporter.setProperty(propertyId, value); - } else if(propertyId.equals( ENTITY_RESOLVER)) { + } + else if (propertyId.equals(ENTITY_RESOLVER)) { fEntityResolver = (XMLEntityResolver)value; - } else if(propertyId.equals( GRAMMAR_POOL)) { + fEntityManager.setProperty(propertyId, value); + } + else if (propertyId.equals(LOCALE)) { + setLocale((Locale) value); + } + else if(propertyId.equals(GRAMMAR_POOL)) { fGrammarPool = (XMLGrammarPool)value; - } else { + } + else { throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, propertyId); } } // setProperty(String,Object) @@ -326,13 +380,24 @@ */ public boolean getFeature(String featureId) throws XMLConfigurationException { - if(featureId.equals( VALIDATION)) { + if (featureId.equals(VALIDATION)) { return fValidation; - } else if(featureId.equals( WARN_ON_DUPLICATE_ATTDEF)) { + } + else if (featureId.equals(WARN_ON_DUPLICATE_ATTDEF)) { return fWarnDuplicateAttdef; - } else if(featureId.equals( NOTIFY_CHAR_REFS)) { + } + else if (featureId.equals(WARN_ON_UNDECLARED_ELEMDEF)) { + return fWarnOnUndeclaredElemdef; + } + else if (featureId.equals(NOTIFY_CHAR_REFS)) { return fDTDScanner.getFeature(featureId); } + else if (featureId.equals(STANDARD_URI_CONFORMANT_FEATURE)) { + return fStrictURI; + } + else if (featureId.equals(BALANCE_SYNTAX_TREES)) { + return fBalanceSyntaxTrees; + } throw new XMLConfigurationException(XMLConfigurationException.NOT_RECOGNIZED, featureId); } //getFeature(String): boolean @@ -346,6 +411,7 @@ */ public void setLocale(Locale locale) { fLocale = locale; + fErrorReporter.setLocale(locale); } // setLocale(Locale) /** Return the Locale the XMLGrammarLoader is using. */ @@ -375,6 +441,7 @@ */ public void setEntityResolver(XMLEntityResolver entityResolver) { fEntityResolver = entityResolver; + fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver); } // setEntityResolver(XMLEntityResolver) /** Returns the registered entity resolver. */ @@ -397,7 +464,13 @@ reset(); // First chance checking strict URI String eid = XMLEntityManager.expandSystemId(source.getSystemId(), source.getBaseSystemId(), fStrictURI); - fDTDGrammar = new DTDGrammar(fSymbolTable, new XMLDTDDescription(source.getPublicId(), source.getSystemId(), source.getBaseSystemId(), eid, null)); + XMLDTDDescription desc = new XMLDTDDescription(source.getPublicId(), source.getSystemId(), source.getBaseSystemId(), eid, null); + if (!fBalanceSyntaxTrees) { + fDTDGrammar = new DTDGrammar(fSymbolTable, desc); + } + else { + fDTDGrammar = new BalancedDTDGrammar(fSymbolTable, desc); + } fGrammarBucket = new DTDGrammarBucket(); fGrammarBucket.setStandalone(false); fGrammarBucket.setActiveGrammar(fDTDGrammar); @@ -421,6 +494,50 @@ return fDTDGrammar; } // loadGrammar(XMLInputSource): Grammar + /** + * Parse a DTD internal and/or external subset and insert the content + * into the existing DTD grammar owned by the given DTDValidator. + */ + public void loadGrammarWithContext(XMLDTDValidator validator, String rootName, + String publicId, String systemId, String baseSystemId, String internalSubset) + throws IOException, XNIException { + final DTDGrammarBucket grammarBucket = validator.getGrammarBucket(); + final DTDGrammar activeGrammar = grammarBucket.getActiveGrammar(); + if (activeGrammar != null && !activeGrammar.isImmutable()) { + fGrammarBucket = grammarBucket; + fEntityManager.setScannerVersion(getScannerVersion()); + reset(); + try { + // process internal subset + if (internalSubset != null) { + // To get the DTD scanner to end at the right place we have to fool + // it into thinking that it reached the end of the internal subset + // in a real document. + StringBuffer buffer = new StringBuffer(internalSubset.length() + 2); + buffer.append(internalSubset).append("]>"); + XMLInputSource is = new XMLInputSource(null, baseSystemId, + null, new StringReader(buffer.toString()), null); + fEntityManager.startDocumentEntity(is); + fDTDScanner.scanDTDInternalSubset(true, false, systemId != null); + } + // process external subset + if (systemId != null) { + XMLDTDDescription desc = new XMLDTDDescription(publicId, systemId, baseSystemId, null, rootName); + XMLInputSource source = fEntityManager.resolveEntity(desc); + fDTDScanner.setInputSource(source); + fDTDScanner.scanDTDExternalSubset(true); + } + } + catch (EOFException e) { + // expected behaviour... + } + finally { + // Close all streams opened by the parser. + fEntityManager.closeReaders(); + } + } + } // loadGrammarWithContext(XMLDTDValidator, String, String, String, String, String) + // reset all the components that we rely upon protected void reset() { super.reset(); @@ -429,4 +546,13 @@ fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); } + protected XMLDTDScannerImpl createDTDScanner(SymbolTable symbolTable, + XMLErrorReporter errorReporter, XMLEntityManager entityManager) { + return new XMLDTDScannerImpl(symbolTable, errorReporter, entityManager); + } // createDTDScanner(SymbolTable, XMLErrorReporter, XMLEntityManager) : XMLDTDScannerImpl + + protected short getScannerVersion() { + return Constants.XML_VERSION_1_0; + } // getScannerVersion() : short + } // class XMLDTDLoader
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDProcessor.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDProcessor.java Wed Sep 28 17:10:18 2011 +0100 @@ -61,11 +61,12 @@ package com.sun.org.apache.xerces.internal.impl.dtd; -import java.util.Enumeration; -import java.util.Hashtable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; import java.util.Locale; +import java.util.Map; import java.util.StringTokenizer; -import java.util.Vector; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; @@ -107,11 +108,12 @@ * <li>http://apache.org/xml/properties/internal/grammar-pool</li> * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li> * </ul> - * + * * @xerces.internal * * @author Neil Graham, IBM * + * @version $Id: XMLDTDProcessor.java,v 1.4 2010/08/11 07:18:38 joehw Exp $ */ public class XMLDTDProcessor implements XMLComponent, XMLDTDFilter, XMLDTDContentModelFilter { @@ -137,8 +139,12 @@ protected static final String WARN_ON_DUPLICATE_ATTDEF = Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; - protected static final String PARSER_SETTINGS = - Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; + /** Feature identifier: warn on undeclared element referenced in content model. */ + protected static final String WARN_ON_UNDECLARED_ELEMDEF = + Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE; + + protected static final String PARSER_SETTINGS = + Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; // property identifiers @@ -164,6 +170,7 @@ private static final String[] RECOGNIZED_FEATURES = { VALIDATION, WARN_ON_DUPLICATE_ATTDEF, + WARN_ON_UNDECLARED_ELEMDEF, NOTIFY_CHAR_REFS, }; @@ -171,6 +178,7 @@ private static final Boolean[] FEATURE_DEFAULTS = { null, Boolean.FALSE, + Boolean.FALSE, null, }; @@ -207,6 +215,9 @@ /** warn on duplicate attribute definition, this feature works only when validation is true */ protected boolean fWarnDuplicateAttdef; + /** warn on undeclared element referenced in content model, this feature only works when valiation is true */ + protected boolean fWarnOnUndeclaredElemdef; + // properties /** Symbol table. */ @@ -266,31 +277,31 @@ // temporary variables /** Temporary entity declaration. */ - private XMLEntityDecl fEntityDecl = new XMLEntityDecl(); + private final XMLEntityDecl fEntityDecl = new XMLEntityDecl(); /** Notation declaration hash. */ - private Hashtable fNDataDeclNotations = new Hashtable(); + private final HashMap fNDataDeclNotations = new HashMap(); /** DTD element declaration name. */ private String fDTDElementDeclName = null; /** Mixed element type "hash". */ - private Vector fMixedElementTypes = new Vector(); + private final ArrayList fMixedElementTypes = new ArrayList(); /** Element declarations in DTD. */ - private Vector fDTDElementDecls = new Vector(); + private final ArrayList fDTDElementDecls = new ArrayList(); // to check for duplicate ID or ANNOTATION attribute declare in // ATTLIST, and misc VCs /** ID attribute names. */ - private Hashtable fTableOfIDAttributeNames; + private HashMap fTableOfIDAttributeNames; /** NOTATION attribute names. */ - private Hashtable fTableOfNOTATIONAttributeNames; + private HashMap fTableOfNOTATIONAttributeNames; /** NOTATION enumeration values. */ - private Hashtable fNotationEnumVals; + private HashMap fNotationEnumVals; // // Constructors @@ -356,9 +367,16 @@ try { fWarnDuplicateAttdef = componentManager.getFeature(WARN_ON_DUPLICATE_ATTDEF); - } catch (XMLConfigurationException e) { + } + catch (XMLConfigurationException e) { fWarnDuplicateAttdef = false; } + try { + fWarnOnUndeclaredElemdef = componentManager.getFeature(WARN_ON_UNDECLARED_ELEMDEF); + } + catch (XMLConfigurationException e) { + fWarnOnUndeclaredElemdef = false; + } // get needed components fErrorReporter = @@ -401,12 +419,12 @@ if (fValidation) { if (fNotationEnumVals == null) { - fNotationEnumVals = new Hashtable(); + fNotationEnumVals = new HashMap(); } fNotationEnumVals.clear(); - fTableOfIDAttributeNames = new Hashtable(); - fTableOfNOTATIONAttributeNames = new Hashtable(); + fTableOfIDAttributeNames = new HashMap(); + fTableOfNOTATIONAttributeNames = new HashMap(); } } @@ -679,7 +697,7 @@ // initialize state fNDataDeclNotations.clear(); - fDTDElementDecls.removeAllElements(); + fDTDElementDecls.clear(); // the grammar bucket's DTDGrammar will now be the // one we want, whether we're constructing it or not. @@ -815,7 +833,7 @@ XMLErrorReporter.SEVERITY_ERROR); } else { - fDTDElementDecls.addElement(name); + fDTDElementDecls.add(name); } } @@ -886,7 +904,7 @@ if (fValidation) { - boolean duplicateAttributeDef = false ; + boolean duplicateAttributeDef = false ; //Get Grammar index to grammar array DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar:fGrammarBucket.getActiveGrammar()); @@ -965,7 +983,7 @@ //we should not report an error, when there is duplicate attribute definition for given element type //according to XML 1.0 spec, When more than one definition is provided for the same attribute of a given //element type, the first declaration is binding and later declaration are *ignored*. So processor should - //ignore the second declarations, however an application would be warned of the duplicate attribute defintion + //ignore the second declarations, however an application would be warned of the duplicate attribute definition // if http://apache.org/xml/features/validation/warn-on-duplicate-attdef feature is set to true, Application behavior may differ on the basis of error or //warning thrown. - nb. @@ -1321,16 +1339,16 @@ if(fGrammarPool != null) fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_DTD, new Grammar[] {fDTDGrammar}); } - // check VC: Notation declared, in the production of NDataDecl if (fValidation) { DTDGrammar grammar = (fDTDGrammar != null? fDTDGrammar: fGrammarBucket.getActiveGrammar()); // VC : Notation Declared. for external entity declaration [Production 76]. - Enumeration entities = fNDataDeclNotations.keys(); - while (entities.hasMoreElements()) { - String entity = (String) entities.nextElement(); - String notation = (String) fNDataDeclNotations.get(entity); + Iterator entities = fNDataDeclNotations.entrySet().iterator(); + while (entities.hasNext()) { + Map.Entry entry = (Map.Entry) entities.next(); + String notation = (String) entry.getValue(); if (grammar.getNotationDeclIndex(notation) == -1) { + String entity = (String) entry.getKey(); fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "MSG_NOTATION_NOT_DECLARED_FOR_UNPARSED_ENTITYDECL", new Object[]{entity, notation}, @@ -1340,11 +1358,12 @@ // VC: Notation Attributes: // all notation names in the (attribute) declaration must be declared. - Enumeration notationVals = fNotationEnumVals.keys(); - while (notationVals.hasMoreElements()) { - String notation = (String) notationVals.nextElement(); - String attributeName = (String) fNotationEnumVals.get(notation); + Iterator notationVals = fNotationEnumVals.entrySet().iterator(); + while (notationVals.hasNext()) { + Map.Entry entry = (Map.Entry) notationVals.next(); + String notation = (String) entry.getKey(); if (grammar.getNotationDeclIndex(notation) == -1) { + String attributeName = (String) entry.getValue(); fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "MSG_NOTATION_NOT_DECLARED_FOR_NOTATIONTYPE_ATTRIBUTE", new Object[]{attributeName, notation}, @@ -1354,12 +1373,13 @@ // VC: No Notation on Empty Element // An attribute of type NOTATION must not be declared on an element declared EMPTY. - Enumeration elementsWithNotations = fTableOfNOTATIONAttributeNames.keys(); - while (elementsWithNotations.hasMoreElements()) { - String elementName = (String) elementsWithNotations.nextElement(); + Iterator elementsWithNotations = fTableOfNOTATIONAttributeNames.entrySet().iterator(); + while (elementsWithNotations.hasNext()) { + Map.Entry entry = (Map.Entry) elementsWithNotations.next(); + String elementName = (String) entry.getKey(); int elementIndex = grammar.getElementDeclIndex(elementName); if (grammar.getContentSpecType(elementIndex) == XMLElementDecl.TYPE_EMPTY) { - String attributeName = (String) fTableOfNOTATIONAttributeNames.get(elementName); + String attributeName = (String) entry.getValue(); fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "NoNotationOnEmptyElement", new Object[]{elementName, attributeName}, @@ -1367,8 +1387,14 @@ } } - fTableOfIDAttributeNames = null;//should be safe to release these references + // should be safe to release these references + fTableOfIDAttributeNames = null; fTableOfNOTATIONAttributeNames = null; + + // check whether each element referenced in a content model is declared + if (fWarnOnUndeclaredElemdef) { + checkDeclaredElements(grammar); + } } // call handlers @@ -1419,7 +1445,7 @@ if (fValidation) { fDTDElementDeclName = elementName; - fMixedElementTypes.removeAllElements(); + fMixedElementTypes.clear(); } // call handlers @@ -1536,7 +1562,7 @@ XMLErrorReporter.SEVERITY_ERROR); } else { - fMixedElementTypes.addElement(elementName); + fMixedElementTypes.add(elementName); } } @@ -1652,8 +1678,6 @@ */ private boolean normalizeDefaultAttrValue(XMLString value) { - int oldLength = value.length; - boolean skipSpace = true; // skip leading spaces int current = value.offset; int end = value.offset + value.length; @@ -1689,7 +1713,6 @@ return false; } - protected boolean isValidNmtoken(String nmtoken) { return XMLChar.isValidNmtoken(nmtoken); } // isValidNmtoken(String): boolean @@ -1697,4 +1720,60 @@ protected boolean isValidName(String name) { return XMLChar.isValidName(name); } // isValidName(String): boolean + + /** + * Checks that all elements referenced in content models have + * been declared. This method calls out to the error handler + * to indicate warnings. + */ + private void checkDeclaredElements(DTDGrammar grammar) { + int elementIndex = grammar.getFirstElementDeclIndex(); + XMLContentSpec contentSpec = new XMLContentSpec(); + while (elementIndex >= 0) { + int type = grammar.getContentSpecType(elementIndex); + if (type == XMLElementDecl.TYPE_CHILDREN || type == XMLElementDecl.TYPE_MIXED) { + checkDeclaredElements(grammar, + elementIndex, + grammar.getContentSpecIndex(elementIndex), + contentSpec); + } + elementIndex = grammar.getNextElementDeclIndex(elementIndex); + } + } + + /** + * Does a recursive (if necessary) check on the specified element's + * content spec to make sure that all children refer to declared + * elements. + */ + private void checkDeclaredElements(DTDGrammar grammar, int elementIndex, + int contentSpecIndex, XMLContentSpec contentSpec) { + grammar.getContentSpec(contentSpecIndex, contentSpec); + if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_LEAF) { + String value = (String) contentSpec.value; + if (value != null && grammar.getElementDeclIndex(value) == -1) { + fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, + "UndeclaredElementInContentSpec", + new Object[]{grammar.getElementDeclName(elementIndex).rawname, value}, + XMLErrorReporter.SEVERITY_WARNING); + } + } + // It's not a leaf, so we have to recurse its left and maybe right + // nodes. Save both values before we recurse and trash the node. + else if ((contentSpec.type == XMLContentSpec.CONTENTSPECNODE_CHOICE) + || (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_SEQ)) { + final int leftNode = ((int[])contentSpec.value)[0]; + final int rightNode = ((int[])contentSpec.otherValue)[0]; + // Recurse on both children. + checkDeclaredElements(grammar, elementIndex, leftNode, contentSpec); + checkDeclaredElements(grammar, elementIndex, rightNode, contentSpec); + } + else if (contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE + || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE + || contentSpec.type == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) { + final int leftNode = ((int[])contentSpec.value)[0]; + checkDeclaredElements(grammar, elementIndex, leftNode, contentSpec); + } + } + } // class XMLDTDProcessor
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/XMLDTDValidator.java Wed Sep 28 17:10:18 2011 +0100 @@ -75,7 +75,7 @@ * <li>http://apache.org/xml/properties/internal/grammar-pool</li> * <li>http://apache.org/xml/properties/internal/datatype-validator-factory</li> * </ul> - * + * * @xerces.internal * * @author Eric Ye, IBM @@ -83,6 +83,7 @@ * @author Jeffrey Rodriguez IBM * @author Neil Graham, IBM * + * @version $Id: XMLDTDValidator.java,v 1.7 2010/08/11 07:18:38 joehw Exp $ */ public class XMLDTDValidator implements XMLComponent, XMLDocumentFilter, XMLDTDValidatorFilter, RevalidationHandler { @@ -100,22 +101,26 @@ /** Feature identifier: namespaces. */ protected static final String NAMESPACES = - Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; + Constants.SAX_FEATURE_PREFIX + Constants.NAMESPACES_FEATURE; /** Feature identifier: validation. */ protected static final String VALIDATION = - Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE; + Constants.SAX_FEATURE_PREFIX + Constants.VALIDATION_FEATURE; /** Feature identifier: dynamic validation. */ protected static final String DYNAMIC_VALIDATION = - Constants.XERCES_FEATURE_PREFIX + Constants.DYNAMIC_VALIDATION_FEATURE; + Constants.XERCES_FEATURE_PREFIX + Constants.DYNAMIC_VALIDATION_FEATURE; + + /** Feature identifier: balance syntax trees. */ + protected static final String BALANCE_SYNTAX_TREES = + Constants.XERCES_FEATURE_PREFIX + Constants.BALANCE_SYNTAX_TREES; /** Feature identifier: warn on duplicate attdef */ protected static final String WARN_ON_DUPLICATE_ATTDEF = - Constants.XERCES_FEATURE_PREFIX +Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; + Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ATTDEF_FEATURE; - protected static final String PARSER_SETTINGS = - Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; + protected static final String PARSER_SETTINGS = + Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; @@ -147,7 +152,8 @@ private static final String[] RECOGNIZED_FEATURES = { NAMESPACES, VALIDATION, - DYNAMIC_VALIDATION + DYNAMIC_VALIDATION, + BALANCE_SYNTAX_TREES }; /** Feature defaults. */ @@ -155,6 +161,7 @@ null, null, Boolean.FALSE, + Boolean.FALSE, }; /** Recognized properties. */ @@ -191,7 +198,7 @@ protected ValidationManager fValidationManager = null; // validation state - protected ValidationState fValidationState = new ValidationState(); + protected final ValidationState fValidationState = new ValidationState(); // features @@ -210,6 +217,9 @@ */ protected boolean fDynamicValidation; + /** Controls whether the DTD grammar produces balanced syntax trees. */ + protected boolean fBalanceSyntaxTrees; + /** warn on duplicate attribute definition, this feature works only when validation is true */ protected boolean fWarnDuplicateAttdef; @@ -328,16 +338,16 @@ private XMLElementDecl fTempElementDecl = new XMLElementDecl(); /** Temporary atribute declaration. */ - private XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl(); + private final XMLAttributeDecl fTempAttDecl = new XMLAttributeDecl(); /** Temporary entity declaration. */ - private XMLEntityDecl fEntityDecl = new XMLEntityDecl(); + private final XMLEntityDecl fEntityDecl = new XMLEntityDecl(); /** Temporary qualified name. */ - private QName fTempQName = new QName(); + private final QName fTempQName = new QName(); /** Temporary string buffers. */ - private StringBuffer fBuffer = new StringBuffer(); + private final StringBuffer fBuffer = new StringBuffer(); // symbols: general @@ -422,24 +432,24 @@ fRootElement.clear(); - fValidationState.resetIDTables(); + fValidationState.resetIDTables(); - fGrammarBucket.clear(); - fElementDepth = -1; - fElementChildrenLength = 0; + fGrammarBucket.clear(); + fElementDepth = -1; + fElementChildrenLength = 0; boolean parser_settings; try { - parser_settings = componentManager.getFeature(PARSER_SETTINGS); + parser_settings = componentManager.getFeature(PARSER_SETTINGS); } catch (XMLConfigurationException e){ - parser_settings = true; + parser_settings = true; } if (!parser_settings){ - // parser settings have not been changed - fValidationManager.addValidationState(fValidationState); - return; + // parser settings have not been changed + fValidationManager.addValidationState(fValidationState); + return; } // sax features @@ -472,6 +482,13 @@ } try { + fBalanceSyntaxTrees = componentManager.getFeature(BALANCE_SYNTAX_TREES); + } + catch (XMLConfigurationException e) { + fBalanceSyntaxTrees = false; + } + + try { fWarnDuplicateAttdef = componentManager.getFeature(WARN_ON_DUPLICATE_ATTDEF); } catch (XMLConfigurationException e) { @@ -500,7 +517,7 @@ } fDatatypeValidatorFactory = (DTDDVFactory)componentManager.getProperty(Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY); - init(); + init(); } // reset(XMLComponentManager) @@ -653,9 +670,10 @@ // call handlers // get initial grammars - if(fGrammarPool != null) { + if (fGrammarPool != null) { Grammar [] grammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_DTD); - for(int i = 0; i<grammars.length; i++) { + final int length = (grammars != null) ? grammars.length : 0; + for (int i = 0; i < length; ++i) { fGrammarBucket.putGrammar((DTDGrammar)grammars[i]); } } @@ -736,7 +754,12 @@ } if(fDTDGrammar == null) { // we'll have to create it... - fDTDGrammar = new DTDGrammar(fSymbolTable, grammarDesc); + if (!fBalanceSyntaxTrees) { + fDTDGrammar = new DTDGrammar(fSymbolTable, grammarDesc); + } + else { + fDTDGrammar = new BalancedDTDGrammar(fSymbolTable, grammarDesc); + } } else { // we've found a cached one;so let's make sure not to read // any external subset! @@ -1782,7 +1805,7 @@ buffer.append('('); for (int i=0; i<attrDecl.simpleType.enumeration.length ; i++) { if (i > 0) { - buffer.append("|"); + buffer.append('|'); } buffer.append(attrDecl.simpleType.enumeration[i]); } @@ -1834,13 +1857,12 @@ } // init() /** ensure element stack capacity */ - private void ensureStackCapacity ( int newElementDepth) { + private void ensureStackCapacity (int newElementDepth) { if (newElementDepth == fElementQNamePartsStack.length) { - int[] newStack = new int[newElementDepth * 2]; QName[] newStackOfQueue = new QName[newElementDepth * 2]; System.arraycopy(this.fElementQNamePartsStack, 0, newStackOfQueue, 0, newElementDepth ); - fElementQNamePartsStack = newStackOfQueue; + fElementQNamePartsStack = newStackOfQueue; QName qname = fElementQNamePartsStack[newElementDepth]; if (qname == null) { @@ -1849,7 +1871,7 @@ } } - newStack = new int[newElementDepth * 2]; + int[] newStack = new int[newElementDepth * 2]; System.arraycopy(fElementIndexStack, 0, newStack, 0, newElementDepth); fElementIndexStack = newStack;
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/models/DFAContentModel.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dtd/models/DFAContentModel.java Wed Sep 28 17:10:18 2011 +0100 @@ -61,24 +61,28 @@ package com.sun.org.apache.xerces.internal.impl.dtd.models; +import java.util.HashMap; + +import com.sun.org.apache.xerces.internal.impl.dtd.XMLContentSpec; import com.sun.org.apache.xerces.internal.xni.QName; -import com.sun.org.apache.xerces.internal.impl.dtd.XMLContentSpec; /** + * @version $Id: DFAContentModel.java,v 1.4 2010/08/06 23:49:43 joehw Exp $ * DFAContentModel is the derivative of ContentModel that does - * all of the non-trivial element content validation. This class does - * the conversion from the regular expression to the DFA that + * all of the non-trivial element content validation. This class does + * the conversion from the regular expression to the DFA that * it then uses in its validation algorithm. * <p> * <b>Note:</b> Upstream work insures that this class will never see - * a content model with PCDATA in it. Any model with PCDATA is 'mixed' - * and is handled via the MixedContentModel class since mixed models - * are very constrained in form and easily handled via a special case. + * a content model with PCDATA in it. Any model with PCDATA is 'mixed' + * and is handled via the MixedContentModel class since mixed models + * are very constrained in form and easily handled via a special case. * This also makes implementation of this class much easier. - * + * * @xerces.internal - * + * + * @version $Id: DFAContentModel.java,v 1.4 2010/08/06 23:49:43 joehw Exp $ */ public class DFAContentModel implements ContentModelValidator { @@ -217,7 +221,7 @@ // temp variables /** Temporary qualified name. */ - private QName fQName = new QName(); + private final QName fQName = new QName(); // // Constructors @@ -454,17 +458,17 @@ // for that matter.) // - /* MODIFIED (Jan, 2001) - * - * Use following rules. - * nullable(x+) := nullable(x), first(x+) := first(x), last(x+) := last(x) - * nullable(x?) := true, first(x?) := first(x), last(x?) := last(x) - * - * The same computation of follow as x* is applied to x+ - * - * The modification drastically reduces computation time of - * "(a, (b, a+, (c, (b, a+)+, a+, (d, (c, (b, a+)+, a+)+, (b, a+)+, a+)+)+)+)+" - */ + /* MODIFIED (Jan, 2001) + * + * Use following rules. + * nullable(x+) := nullable(x), first(x+) := first(x), last(x+) := last(x) + * nullable(x?) := true, first(x?) := first(x), last(x?) := last(x) + * + * The same computation of follow as x* is applied to x+ + * + * The modification drastically reduces computation time of + * "(a, (b, a+, (c, (b, a+)+, a+, (d, (c, (b, a+)+, a+)+, (b, a+)+, a+)+)+)+)+" + */ fQName.setValues(null, fEOCString, fEOCString, null); CMLeaf nodeEOC = new CMLeaf(fQName); @@ -563,27 +567,27 @@ fLeafNameTypeVector.setValues(fElemMap, fElemMapType, fElemMapSize); } - /*** - * Optimization(Jan, 2001); We sort fLeafList according to - * elemIndex which is *uniquely* associated to each leaf. - * We are *assuming* that each element appears in at least one leaf. - **/ + /*** + * Optimization(Jan, 2001); We sort fLeafList according to + * elemIndex which is *uniquely* associated to each leaf. + * We are *assuming* that each element appears in at least one leaf. + **/ - int[] fLeafSorter = new int[fLeafCount + fElemMapSize]; - int fSortCount = 0; + int[] fLeafSorter = new int[fLeafCount + fElemMapSize]; + int fSortCount = 0; - for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { - for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++) { - final QName leaf = fLeafList[leafIndex].getElement(); - final QName element = fElemMap[elemIndex]; - if (leaf.rawname == element.rawname) { - fLeafSorter[fSortCount++] = leafIndex; - } - } - fLeafSorter[fSortCount++] = -1; - } + for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { + for (int leafIndex = 0; leafIndex < fLeafCount; leafIndex++) { + final QName leaf = fLeafList[leafIndex].getElement(); + final QName element = fElemMap[elemIndex]; + if (leaf.rawname == element.rawname) { + fLeafSorter[fSortCount++] = leafIndex; + } + } + fLeafSorter[fSortCount++] = -1; + } - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ // // Next lets create some arrays, some that that hold transient @@ -629,13 +633,13 @@ statesToDo[curState] = setT; curState++; - /* Optimization(Jan, 2001); This is faster for - * a large content model such as, "(t001+|t002+|.... |t500+)". - */ + /* Optimization(Jan, 2001); This is faster for + * a large content model such as, "(t001+|t002+|.... |t500+)". + */ - java.util.Hashtable stateTable = new java.util.Hashtable(); + HashMap stateTable = new HashMap(); - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ // // Ok, almost done with the algorithm... We now enter the @@ -659,9 +663,9 @@ // Loop through each possible input symbol in the element map CMStateSet newSet = null; - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ int sorterIndex = 0; - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { // @@ -675,11 +679,11 @@ else newSet.zeroBits(); - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ int leafIndex = fLeafSorter[sorterIndex++]; while (leafIndex != -1) { - // If this leaf index (DFA position) is in the current set... + // If this leaf index (DFA position) is in the current set... if (setT.getBit(leafIndex)) { // @@ -691,8 +695,8 @@ } leafIndex = fLeafSorter[sorterIndex++]; - } - /* Optimization(Jan, 2001) */ + } + /* Optimization(Jan, 2001) */ // // If this new set is not empty, then see if its in the list @@ -705,10 +709,10 @@ // state set is already in there. // - /* Optimization(Jan, 2001) */ - Integer stateObj = (Integer)stateTable.get(newSet); - int stateIndex = (stateObj == null ? curState : stateObj.intValue()); - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ + Integer stateObj = (Integer)stateTable.get(newSet); + int stateIndex = (stateObj == null ? curState : stateObj.intValue()); + /* Optimization(Jan, 2001) */ // If we did not find it, then add it if (stateIndex == curState) @@ -721,9 +725,9 @@ statesToDo[curState] = newSet; fTransTable[curState] = makeDefStateList(); - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ stateTable.put(newSet, new Integer(curState)); - /* Optimization(Jan, 2001) */ + /* Optimization(Jan, 2001) */ // We now have a new state to do so bump the count curState++; @@ -758,12 +762,9 @@ int[][] newTransTable = new int[newSize][]; // Copy over all of the existing content - for (int expIndex = 0; expIndex < curArraySize; expIndex++) - { - newToDo[expIndex] = statesToDo[expIndex]; - newFinalFlags[expIndex] = fFinalStateFlags[expIndex]; - newTransTable[expIndex] = fTransTable[expIndex]; - } + System.arraycopy(statesToDo, 0, newToDo, 0, curArraySize); + System.arraycopy(fFinalStateFlags, 0, newFinalFlags, 0, curArraySize); + System.arraycopy(fTransTable, 0, newTransTable, 0, curArraySize); // Store the new array size curArraySize = newSize; @@ -862,7 +863,7 @@ } /***/ else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE - || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) + || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE) { // Recurse first calcFollowList(((CMUniOp)nodeCur).getChild()); @@ -1004,8 +1005,8 @@ curIndex = postTreeBuildInit(((CMBinOp)nodeCur).getRight(), curIndex); } else if (nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_MORE - || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE - || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) + || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ONE_OR_MORE + || nodeCur.type() == XMLContentSpec.CONTENTSPECNODE_ZERO_OR_ONE) { curIndex = postTreeBuildInit(((CMUniOp)nodeCur).getChild(), curIndex); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dv/ValidationContext.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dv/ValidationContext.java Wed Sep 28 17:10:18 2011 +0100 @@ -20,13 +20,16 @@ package com.sun.org.apache.xerces.internal.impl.dv; +import java.util.Locale; + /** * ValidationContext has all the information required for the * validation of: id, idref, entity, notation, qname - * - * @xerces.internal + * + * @xerces.internal * * @author Sandy Gao, IBM + * @version $Id: ValidationContext.java,v 1.6 2010/07/23 02:09:29 joehw Exp $ */ public interface ValidationContext { // whether to validate against facets @@ -57,4 +60,8 @@ // qname public String getURI(String prefix); + + // Locale + public Locale getLocale(); + }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/dv/xs/XSSimpleTypeDecl.java Wed Sep 28 17:10:18 2011 +0100 @@ -20,6 +20,7 @@ package com.sun.org.apache.xerces.internal.impl.dv.xs; +import java.util.Locale; import java.util.StringTokenizer; import java.util.Vector; @@ -54,516 +55,520 @@ /** * @xerces.internal - * + * * @author Sandy Gao, IBM * @author Neeraj Bajaj, Sun Microsystems, inc. * + * @version $Id: XSSimpleTypeDecl.java,v 1.9 2010/07/23 02:09:28 joehw Exp $ */ public class XSSimpleTypeDecl implements XSSimpleType, TypeInfo { - - static final short DV_STRING = PRIMITIVE_STRING; - static final short DV_BOOLEAN = PRIMITIVE_BOOLEAN; - static final short DV_DECIMAL = PRIMITIVE_DECIMAL; - static final short DV_FLOAT = PRIMITIVE_FLOAT; - static final short DV_DOUBLE = PRIMITIVE_DOUBLE; - static final short DV_DURATION = PRIMITIVE_DURATION; - static final short DV_DATETIME = PRIMITIVE_DATETIME; - static final short DV_TIME = PRIMITIVE_TIME; - static final short DV_DATE = PRIMITIVE_DATE; - static final short DV_GYEARMONTH = PRIMITIVE_GYEARMONTH; - static final short DV_GYEAR = PRIMITIVE_GYEAR; - static final short DV_GMONTHDAY = PRIMITIVE_GMONTHDAY; - static final short DV_GDAY = PRIMITIVE_GDAY; - static final short DV_GMONTH = PRIMITIVE_GMONTH; - static final short DV_HEXBINARY = PRIMITIVE_HEXBINARY; - static final short DV_BASE64BINARY = PRIMITIVE_BASE64BINARY; - static final short DV_ANYURI = PRIMITIVE_ANYURI; - static final short DV_QNAME = PRIMITIVE_QNAME; - static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL; - static final short DV_NOTATION = PRIMITIVE_NOTATION; - - static final short DV_ANYSIMPLETYPE = 0; - static final short DV_ID = DV_NOTATION + 1; - static final short DV_IDREF = DV_NOTATION + 2; - static final short DV_ENTITY = DV_NOTATION + 3; - static final short DV_INTEGER = DV_NOTATION + 4; - static final short DV_LIST = DV_NOTATION + 5; - static final short DV_UNION = DV_NOTATION + 6; - static final short DV_YEARMONTHDURATION = DV_NOTATION + 7; - static final short DV_DAYTIMEDURATION = DV_NOTATION + 8; - static final short DV_ANYATOMICTYPE = DV_NOTATION + 9; - - static final TypeValidator[] fDVs = { - new AnySimpleDV(), - new StringDV(), - new BooleanDV(), - new DecimalDV(), - new FloatDV(), - new DoubleDV(), - new DurationDV(), - new DateTimeDV(), - new TimeDV(), - new DateDV(), - new YearMonthDV(), - new YearDV(), - new MonthDayDV(), - new DayDV(), - new MonthDV(), - new HexBinaryDV(), - new Base64BinaryDV(), - new AnyURIDV(), - new QNameDV(), - new PrecisionDecimalDV(), // XML Schema 1.1 type - new QNameDV(), // notation use the same one as qname - new IDDV(), - new IDREFDV(), - new EntityDV(), - new IntegerDV(), - new ListDV(), - new UnionDV(), - new YearMonthDurationDV(), // XML Schema 1.1 type - new DayTimeDurationDV(), // XML Schema 1.1 type - new AnyAtomicDV() // XML Schema 1.1 type - }; - - static final short NORMALIZE_NONE = 0; - static final short NORMALIZE_TRIM = 1; - static final short NORMALIZE_FULL = 2; - static final short[] fDVNormalizeType = { - NORMALIZE_NONE, //AnySimpleDV(), - NORMALIZE_FULL, //StringDV(), - NORMALIZE_TRIM, //BooleanDV(), - NORMALIZE_TRIM, //DecimalDV(), - NORMALIZE_TRIM, //FloatDV(), - NORMALIZE_TRIM, //DoubleDV(), - NORMALIZE_TRIM, //DurationDV(), - NORMALIZE_TRIM, //DateTimeDV(), - NORMALIZE_TRIM, //TimeDV(), - NORMALIZE_TRIM, //DateDV(), - NORMALIZE_TRIM, //YearMonthDV(), - NORMALIZE_TRIM, //YearDV(), - NORMALIZE_TRIM, //MonthDayDV(), - NORMALIZE_TRIM, //DayDV(), - NORMALIZE_TRIM, //MonthDV(), - NORMALIZE_TRIM, //HexBinaryDV(), - NORMALIZE_NONE, //Base64BinaryDV(), // Base64 know how to deal with spaces - NORMALIZE_TRIM, //AnyURIDV(), - NORMALIZE_TRIM, //QNameDV(), - NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1) - NORMALIZE_TRIM, //QNameDV(), // notation - NORMALIZE_TRIM, //IDDV(), - NORMALIZE_TRIM, //IDREFDV(), - NORMALIZE_TRIM, //EntityDV(), - NORMALIZE_TRIM, //IntegerDV(), - NORMALIZE_FULL, //ListDV(), - NORMALIZE_NONE, //UnionDV(), - NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1) - NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1) - NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1) - }; - - static final short SPECIAL_PATTERN_NONE = 0; - static final short SPECIAL_PATTERN_NMTOKEN = 1; - static final short SPECIAL_PATTERN_NAME = 2; - static final short SPECIAL_PATTERN_NCNAME = 3; - - static final String[] SPECIAL_PATTERN_STRING = { - "NONE", "NMTOKEN", "Name", "NCName" - }; - - static final String[] WS_FACET_STRING = { - "preserve", "replace", "collapse" - }; - - static final String URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema"; - static final String ANY_TYPE = "anyType"; - + + static final short DV_STRING = PRIMITIVE_STRING; + static final short DV_BOOLEAN = PRIMITIVE_BOOLEAN; + static final short DV_DECIMAL = PRIMITIVE_DECIMAL; + static final short DV_FLOAT = PRIMITIVE_FLOAT; + static final short DV_DOUBLE = PRIMITIVE_DOUBLE; + static final short DV_DURATION = PRIMITIVE_DURATION; + static final short DV_DATETIME = PRIMITIVE_DATETIME; + static final short DV_TIME = PRIMITIVE_TIME; + static final short DV_DATE = PRIMITIVE_DATE; + static final short DV_GYEARMONTH = PRIMITIVE_GYEARMONTH; + static final short DV_GYEAR = PRIMITIVE_GYEAR; + static final short DV_GMONTHDAY = PRIMITIVE_GMONTHDAY; + static final short DV_GDAY = PRIMITIVE_GDAY; + static final short DV_GMONTH = PRIMITIVE_GMONTH; + static final short DV_HEXBINARY = PRIMITIVE_HEXBINARY; + static final short DV_BASE64BINARY = PRIMITIVE_BASE64BINARY; + static final short DV_ANYURI = PRIMITIVE_ANYURI; + static final short DV_QNAME = PRIMITIVE_QNAME; + static final short DV_PRECISIONDECIMAL = PRIMITIVE_PRECISIONDECIMAL; + static final short DV_NOTATION = PRIMITIVE_NOTATION; + + static final short DV_ANYSIMPLETYPE = 0; + static final short DV_ID = DV_NOTATION + 1; + static final short DV_IDREF = DV_NOTATION + 2; + static final short DV_ENTITY = DV_NOTATION + 3; + static final short DV_INTEGER = DV_NOTATION + 4; + static final short DV_LIST = DV_NOTATION + 5; + static final short DV_UNION = DV_NOTATION + 6; + static final short DV_YEARMONTHDURATION = DV_NOTATION + 7; + static final short DV_DAYTIMEDURATION = DV_NOTATION + 8; + static final short DV_ANYATOMICTYPE = DV_NOTATION + 9; + + static final TypeValidator[] fDVs = { + new AnySimpleDV(), + new StringDV(), + new BooleanDV(), + new DecimalDV(), + new FloatDV(), + new DoubleDV(), + new DurationDV(), + new DateTimeDV(), + new TimeDV(), + new DateDV(), + new YearMonthDV(), + new YearDV(), + new MonthDayDV(), + new DayDV(), + new MonthDV(), + new HexBinaryDV(), + new Base64BinaryDV(), + new AnyURIDV(), + new QNameDV(), + new PrecisionDecimalDV(), // XML Schema 1.1 type + new QNameDV(), // notation use the same one as qname + new IDDV(), + new IDREFDV(), + new EntityDV(), + new IntegerDV(), + new ListDV(), + new UnionDV(), + new YearMonthDurationDV(), // XML Schema 1.1 type + new DayTimeDurationDV(), // XML Schema 1.1 type + new AnyAtomicDV() // XML Schema 1.1 type + }; + + static final short NORMALIZE_NONE = 0; + static final short NORMALIZE_TRIM = 1; + static final short NORMALIZE_FULL = 2; + static final short[] fDVNormalizeType = { + NORMALIZE_NONE, //AnySimpleDV(), + NORMALIZE_FULL, //StringDV(), + NORMALIZE_TRIM, //BooleanDV(), + NORMALIZE_TRIM, //DecimalDV(), + NORMALIZE_TRIM, //FloatDV(), + NORMALIZE_TRIM, //DoubleDV(), + NORMALIZE_TRIM, //DurationDV(), + NORMALIZE_TRIM, //DateTimeDV(), + NORMALIZE_TRIM, //TimeDV(), + NORMALIZE_TRIM, //DateDV(), + NORMALIZE_TRIM, //YearMonthDV(), + NORMALIZE_TRIM, //YearDV(), + NORMALIZE_TRIM, //MonthDayDV(), + NORMALIZE_TRIM, //DayDV(), + NORMALIZE_TRIM, //MonthDV(), + NORMALIZE_TRIM, //HexBinaryDV(), + NORMALIZE_NONE, //Base64BinaryDV(), // Base64 know how to deal with spaces + NORMALIZE_TRIM, //AnyURIDV(), + NORMALIZE_TRIM, //QNameDV(), + NORMALIZE_TRIM, //PrecisionDecimalDV() (Schema 1.1) + NORMALIZE_TRIM, //QNameDV(), // notation + NORMALIZE_TRIM, //IDDV(), + NORMALIZE_TRIM, //IDREFDV(), + NORMALIZE_TRIM, //EntityDV(), + NORMALIZE_TRIM, //IntegerDV(), + NORMALIZE_FULL, //ListDV(), + NORMALIZE_NONE, //UnionDV(), + NORMALIZE_TRIM, //YearMonthDurationDV() (Schema 1.1) + NORMALIZE_TRIM, //DayTimeDurationDV() (Schema 1.1) + NORMALIZE_NONE, //AnyAtomicDV() (Schema 1.1) + }; + + static final short SPECIAL_PATTERN_NONE = 0; + static final short SPECIAL_PATTERN_NMTOKEN = 1; + static final short SPECIAL_PATTERN_NAME = 2; + static final short SPECIAL_PATTERN_NCNAME = 3; + + static final String[] SPECIAL_PATTERN_STRING = { + "NONE", "NMTOKEN", "Name", "NCName" + }; + + static final String[] WS_FACET_STRING = { + "preserve", "replace", "collapse" + }; + + static final String URI_SCHEMAFORSCHEMA = "http://www.w3.org/2001/XMLSchema"; + static final String ANY_TYPE = "anyType"; + // XML Schema 1.1 type constants public static final short YEARMONTHDURATION_DT = 46; - public static final short DAYTIMEDURATION_DT = 47; + public static final short DAYTIMEDURATION_DT = 47; public static final short PRECISIONDECIMAL_DT = 48; public static final short ANYATOMICTYPE_DT = 49; - - // DOM Level 3 TypeInfo Derivation Method constants - static final int DERIVATION_ANY = 0; - static final int DERIVATION_RESTRICTION = 1; - static final int DERIVATION_EXTENSION = 2; - static final int DERIVATION_UNION = 4; - static final int DERIVATION_LIST = 8; - - static final ValidationContext fEmptyContext = new ValidationContext() { - public boolean needFacetChecking() { - return true; - } - public boolean needExtraChecking() { - return false; - } - public boolean needToNormalize() { - return true; - } - public boolean useNamespaces () { - return true; - } - public boolean isEntityDeclared (String name) { - return false; - } - public boolean isEntityUnparsed (String name) { - return false; - } - public boolean isIdDeclared (String name) { - return false; - } - public void addId(String name) { - } - public void addIdRef(String name) { - } - public String getSymbol (String symbol) { - return symbol.intern(); + + // DOM Level 3 TypeInfo Derivation Method constants + static final int DERIVATION_ANY = 0; + static final int DERIVATION_RESTRICTION = 1; + static final int DERIVATION_EXTENSION = 2; + static final int DERIVATION_UNION = 4; + static final int DERIVATION_LIST = 8; + + static final ValidationContext fEmptyContext = new ValidationContext() { + public boolean needFacetChecking() { + return true; + } + public boolean needExtraChecking() { + return false; + } + public boolean needToNormalize() { + return true; + } + public boolean useNamespaces () { + return true; + } + public boolean isEntityDeclared (String name) { + return false; + } + public boolean isEntityUnparsed (String name) { + return false; + } + public boolean isIdDeclared (String name) { + return false; + } + public void addId(String name) { + } + public void addIdRef(String name) { + } + public String getSymbol (String symbol) { + return symbol.intern(); + } + public String getURI(String prefix) { + return null; + } + public Locale getLocale() { + return Locale.getDefault(); } - public String getURI(String prefix) { - return null; - } - }; - - // this will be true if this is a static XSSimpleTypeDecl - // and hence must remain immutable (i.e., applyFacets - // may not be permitted to have any effect). - private boolean fIsImmutable = false; - - private XSSimpleTypeDecl fItemType; - private XSSimpleTypeDecl[] fMemberTypes; - // The most specific built-in type kind. - private short fBuiltInKind; - - private String fTypeName; - private String fTargetNamespace; - private short fFinalSet = 0; - private XSSimpleTypeDecl fBase; - private short fVariety = -1; - private short fValidationDV = -1; - - private short fFacetsDefined = 0; - private short fFixedFacet = 0; - - //for constraining facets - private short fWhiteSpace = 0; - private int fLength = -1; - private int fMinLength = -1; - private int fMaxLength = -1; - private int fTotalDigits = -1; - private int fFractionDigits = -1; - private Vector fPattern; - private Vector fPatternStr; - private Vector fEnumeration; - private short[] fEnumerationType; - private ShortList[] fEnumerationItemType; // used in case fenumerationType value is LIST or LISTOFUNION + }; + + // this will be true if this is a static XSSimpleTypeDecl + // and hence must remain immutable (i.e., applyFacets + // may not be permitted to have any effect). + private boolean fIsImmutable = false; + + private XSSimpleTypeDecl fItemType; + private XSSimpleTypeDecl[] fMemberTypes; + // The most specific built-in type kind. + private short fBuiltInKind; + + private String fTypeName; + private String fTargetNamespace; + private short fFinalSet = 0; + private XSSimpleTypeDecl fBase; + private short fVariety = -1; + private short fValidationDV = -1; + + private short fFacetsDefined = 0; + private short fFixedFacet = 0; + + //for constraining facets + private short fWhiteSpace = 0; + private int fLength = -1; + private int fMinLength = -1; + private int fMaxLength = -1; + private int fTotalDigits = -1; + private int fFractionDigits = -1; + private Vector fPattern; + private Vector fPatternStr; + private Vector fEnumeration; + private short[] fEnumerationType; + private ShortList[] fEnumerationItemType; // used in case fenumerationType value is LIST or LISTOFUNION private ShortList fEnumerationTypeList; private ObjectList fEnumerationItemTypeList; - private StringList fLexicalPattern; - private StringList fLexicalEnumeration; - private ObjectList fActualEnumeration; - private Object fMaxInclusive; - private Object fMaxExclusive; - private Object fMinExclusive; - private Object fMinInclusive; - - // annotations for constraining facets - public XSAnnotation lengthAnnotation; - public XSAnnotation minLengthAnnotation; - public XSAnnotation maxLengthAnnotation; - public XSAnnotation whiteSpaceAnnotation; - public XSAnnotation totalDigitsAnnotation; - public XSAnnotation fractionDigitsAnnotation; - public XSObjectListImpl patternAnnotations; - public XSObjectList enumerationAnnotations; - public XSAnnotation maxInclusiveAnnotation; - public XSAnnotation maxExclusiveAnnotation; - public XSAnnotation minInclusiveAnnotation; - public XSAnnotation minExclusiveAnnotation; - - // facets as objects - private XSObjectListImpl fFacets; - - // enumeration and pattern facets - private XSObjectListImpl fMultiValueFacets; - - // simpleType annotations - private XSObjectList fAnnotations = null; - - private short fPatternType = SPECIAL_PATTERN_NONE; - - // for fundamental facets - private short fOrdered; - private boolean fFinite; - private boolean fBounded; - private boolean fNumeric; - - // default constructor - public XSSimpleTypeDecl(){} - - //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration) - protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, short validateDV, - short ordered, boolean bounded, boolean finite, - boolean numeric, boolean isImmutable, short builtInKind) { - fIsImmutable = isImmutable; - fBase = base; - fTypeName = name; - fTargetNamespace = URI_SCHEMAFORSCHEMA; - // To simplify the code for anySimpleType, we treat it as an atomic type - fVariety = VARIETY_ATOMIC; - fValidationDV = validateDV; - fFacetsDefined = FACET_WHITESPACE; - if (validateDV == DV_STRING) { - fWhiteSpace = WS_PRESERVE; - } else { - fWhiteSpace = WS_COLLAPSE; - fFixedFacet = FACET_WHITESPACE; - } - this.fOrdered = ordered; - this.fBounded = bounded; - this.fFinite = finite; - this.fNumeric = numeric; - fAnnotations = null; - - // Specify the build in kind for this primitive type - fBuiltInKind = builtInKind; - } - - //Create a new simple type for restriction for built-in types - protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable, - XSObjectList annotations, short builtInKind) { - this(base, name, uri, finalSet, isImmutable, annotations); - // Specify the build in kind for this built-in type - fBuiltInKind = builtInKind; - } - - //Create a new simple type for restriction. - protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable, - XSObjectList annotations) { - fBase = base; - fTypeName = name; - fTargetNamespace = uri; - fFinalSet = finalSet; - fAnnotations = annotations; - - fVariety = fBase.fVariety; - fValidationDV = fBase.fValidationDV; - switch (fVariety) { - case VARIETY_ATOMIC: - break; - case VARIETY_LIST: - fItemType = fBase.fItemType; - break; - case VARIETY_UNION: - fMemberTypes = fBase.fMemberTypes; - break; - } - - // always inherit facets from the base. - // in case a type is created, but applyFacets is not called - fLength = fBase.fLength; - fMinLength = fBase.fMinLength; - fMaxLength = fBase.fMaxLength; - fPattern = fBase.fPattern; - fPatternStr = fBase.fPatternStr; - fEnumeration = fBase.fEnumeration; - fEnumerationType = fBase.fEnumerationType; + private StringList fLexicalPattern; + private StringList fLexicalEnumeration; + private ObjectList fActualEnumeration; + private Object fMaxInclusive; + private Object fMaxExclusive; + private Object fMinExclusive; + private Object fMinInclusive; + + // annotations for constraining facets + public XSAnnotation lengthAnnotation; + public XSAnnotation minLengthAnnotation; + public XSAnnotation maxLengthAnnotation; + public XSAnnotation whiteSpaceAnnotation; + public XSAnnotation totalDigitsAnnotation; + public XSAnnotation fractionDigitsAnnotation; + public XSObjectListImpl patternAnnotations; + public XSObjectList enumerationAnnotations; + public XSAnnotation maxInclusiveAnnotation; + public XSAnnotation maxExclusiveAnnotation; + public XSAnnotation minInclusiveAnnotation; + public XSAnnotation minExclusiveAnnotation; + + // facets as objects + private XSObjectListImpl fFacets; + + // enumeration and pattern facets + private XSObjectListImpl fMultiValueFacets; + + // simpleType annotations + private XSObjectList fAnnotations = null; + + private short fPatternType = SPECIAL_PATTERN_NONE; + + // for fundamental facets + private short fOrdered; + private boolean fFinite; + private boolean fBounded; + private boolean fNumeric; + + // default constructor + public XSSimpleTypeDecl(){} + + //Create a new built-in primitive types (and id/idref/entity/integer/yearMonthDuration) + protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, short validateDV, + short ordered, boolean bounded, boolean finite, + boolean numeric, boolean isImmutable, short builtInKind) { + fIsImmutable = isImmutable; + fBase = base; + fTypeName = name; + fTargetNamespace = URI_SCHEMAFORSCHEMA; + // To simplify the code for anySimpleType, we treat it as an atomic type + fVariety = VARIETY_ATOMIC; + fValidationDV = validateDV; + fFacetsDefined = FACET_WHITESPACE; + if (validateDV == DV_STRING) { + fWhiteSpace = WS_PRESERVE; + } else { + fWhiteSpace = WS_COLLAPSE; + fFixedFacet = FACET_WHITESPACE; + } + this.fOrdered = ordered; + this.fBounded = bounded; + this.fFinite = finite; + this.fNumeric = numeric; + fAnnotations = null; + + // Specify the build in kind for this primitive type + fBuiltInKind = builtInKind; + } + + //Create a new simple type for restriction for built-in types + protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable, + XSObjectList annotations, short builtInKind) { + this(base, name, uri, finalSet, isImmutable, annotations); + // Specify the build in kind for this built-in type + fBuiltInKind = builtInKind; + } + + //Create a new simple type for restriction. + protected XSSimpleTypeDecl(XSSimpleTypeDecl base, String name, String uri, short finalSet, boolean isImmutable, + XSObjectList annotations) { + fBase = base; + fTypeName = name; + fTargetNamespace = uri; + fFinalSet = finalSet; + fAnnotations = annotations; + + fVariety = fBase.fVariety; + fValidationDV = fBase.fValidationDV; + switch (fVariety) { + case VARIETY_ATOMIC: + break; + case VARIETY_LIST: + fItemType = fBase.fItemType; + break; + case VARIETY_UNION: + fMemberTypes = fBase.fMemberTypes; + break; + } + + // always inherit facets from the base. + // in case a type is created, but applyFacets is not called + fLength = fBase.fLength; + fMinLength = fBase.fMinLength; + fMaxLength = fBase.fMaxLength; + fPattern = fBase.fPattern; + fPatternStr = fBase.fPatternStr; + fEnumeration = fBase.fEnumeration; + fEnumerationType = fBase.fEnumerationType; fEnumerationItemType = fBase.fEnumerationItemType; - fWhiteSpace = fBase.fWhiteSpace; - fMaxExclusive = fBase.fMaxExclusive; - fMaxInclusive = fBase.fMaxInclusive; - fMinExclusive = fBase.fMinExclusive; - fMinInclusive = fBase.fMinInclusive; - fTotalDigits = fBase.fTotalDigits; - fFractionDigits = fBase.fFractionDigits; - fPatternType = fBase.fPatternType; - fFixedFacet = fBase.fFixedFacet; - fFacetsDefined = fBase.fFacetsDefined; - - //we also set fundamental facets information in case applyFacets is not called. - caclFundamentalFacets(); - fIsImmutable = isImmutable; - - // Inherit from the base type - fBuiltInKind = base.fBuiltInKind; - } - - //Create a new simple type for list. - protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, boolean isImmutable, - XSObjectList annotations) { - fBase = fAnySimpleType; - fTypeName = name; - fTargetNamespace = uri; - fFinalSet = finalSet; - fAnnotations = annotations; - - fVariety = VARIETY_LIST; - fItemType = (XSSimpleTypeDecl)itemType; - fValidationDV = DV_LIST; - fFacetsDefined = FACET_WHITESPACE; - fFixedFacet = FACET_WHITESPACE; - fWhiteSpace = WS_COLLAPSE; - - //setting fundamental facets - caclFundamentalFacets(); - fIsImmutable = isImmutable; - - // Values of this type are lists - fBuiltInKind = XSConstants.LIST_DT; - } - - //Create a new simple type for union. - protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes, - XSObjectList annotations) { - fBase = fAnySimpleType; - fTypeName = name; - fTargetNamespace = uri; - fFinalSet = finalSet; - fAnnotations = annotations; - - fVariety = VARIETY_UNION; - fMemberTypes = memberTypes; - fValidationDV = DV_UNION; - // even for union, we set whitespace to something - // this will never be used, but we can use fFacetsDefined to check - // whether applyFacets() is allwwed: it's not allowed - // if fFacetsDefined != 0 - fFacetsDefined = FACET_WHITESPACE; - fWhiteSpace = WS_COLLAPSE; - - //setting fundamental facets - caclFundamentalFacets(); - // none of the schema-defined types are unions, so just set - // fIsImmutable to false. - fIsImmutable = false; - - // No value can be of this type, so it's unavailable. - fBuiltInKind = XSConstants.UNAVAILABLE_DT; - } - - //set values for restriction. - protected XSSimpleTypeDecl setRestrictionValues(XSSimpleTypeDecl base, String name, String uri, short finalSet, - XSObjectList annotations) { - //decline to do anything if the object is immutable. - if(fIsImmutable) return null; - fBase = base; - fTypeName = name; - fTargetNamespace = uri; - fFinalSet = finalSet; - fAnnotations = annotations; - - fVariety = fBase.fVariety; - fValidationDV = fBase.fValidationDV; - switch (fVariety) { - case VARIETY_ATOMIC: - break; - case VARIETY_LIST: - fItemType = fBase.fItemType; - break; - case VARIETY_UNION: - fMemberTypes = fBase.fMemberTypes; - break; - } - - // always inherit facets from the base. - // in case a type is created, but applyFacets is not called - fLength = fBase.fLength; - fMinLength = fBase.fMinLength; - fMaxLength = fBase.fMaxLength; - fPattern = fBase.fPattern; - fPatternStr = fBase.fPatternStr; - fEnumeration = fBase.fEnumeration; - fEnumerationType = fBase.fEnumerationType; + fWhiteSpace = fBase.fWhiteSpace; + fMaxExclusive = fBase.fMaxExclusive; + fMaxInclusive = fBase.fMaxInclusive; + fMinExclusive = fBase.fMinExclusive; + fMinInclusive = fBase.fMinInclusive; + fTotalDigits = fBase.fTotalDigits; + fFractionDigits = fBase.fFractionDigits; + fPatternType = fBase.fPatternType; + fFixedFacet = fBase.fFixedFacet; + fFacetsDefined = fBase.fFacetsDefined; + + //we also set fundamental facets information in case applyFacets is not called. + caclFundamentalFacets(); + fIsImmutable = isImmutable; + + // Inherit from the base type + fBuiltInKind = base.fBuiltInKind; + } + + //Create a new simple type for list. + protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, boolean isImmutable, + XSObjectList annotations) { + fBase = fAnySimpleType; + fTypeName = name; + fTargetNamespace = uri; + fFinalSet = finalSet; + fAnnotations = annotations; + + fVariety = VARIETY_LIST; + fItemType = (XSSimpleTypeDecl)itemType; + fValidationDV = DV_LIST; + fFacetsDefined = FACET_WHITESPACE; + fFixedFacet = FACET_WHITESPACE; + fWhiteSpace = WS_COLLAPSE; + + //setting fundamental facets + caclFundamentalFacets(); + fIsImmutable = isImmutable; + + // Values of this type are lists + fBuiltInKind = XSConstants.LIST_DT; + } + + //Create a new simple type for union. + protected XSSimpleTypeDecl(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes, + XSObjectList annotations) { + fBase = fAnySimpleType; + fTypeName = name; + fTargetNamespace = uri; + fFinalSet = finalSet; + fAnnotations = annotations; + + fVariety = VARIETY_UNION; + fMemberTypes = memberTypes; + fValidationDV = DV_UNION; + // even for union, we set whitespace to something + // this will never be used, but we can use fFacetsDefined to check + // whether applyFacets() is allwwed: it's not allowed + // if fFacetsDefined != 0 + fFacetsDefined = FACET_WHITESPACE; + fWhiteSpace = WS_COLLAPSE; + + //setting fundamental facets + caclFundamentalFacets(); + // none of the schema-defined types are unions, so just set + // fIsImmutable to false. + fIsImmutable = false; + + // No value can be of this type, so it's unavailable. + fBuiltInKind = XSConstants.UNAVAILABLE_DT; + } + + //set values for restriction. + protected XSSimpleTypeDecl setRestrictionValues(XSSimpleTypeDecl base, String name, String uri, short finalSet, + XSObjectList annotations) { + //decline to do anything if the object is immutable. + if(fIsImmutable) return null; + fBase = base; + fTypeName = name; + fTargetNamespace = uri; + fFinalSet = finalSet; + fAnnotations = annotations; + + fVariety = fBase.fVariety; + fValidationDV = fBase.fValidationDV; + switch (fVariety) { + case VARIETY_ATOMIC: + break; + case VARIETY_LIST: + fItemType = fBase.fItemType; + break; + case VARIETY_UNION: + fMemberTypes = fBase.fMemberTypes; + break; + } + + // always inherit facets from the base. + // in case a type is created, but applyFacets is not called + fLength = fBase.fLength; + fMinLength = fBase.fMinLength; + fMaxLength = fBase.fMaxLength; + fPattern = fBase.fPattern; + fPatternStr = fBase.fPatternStr; + fEnumeration = fBase.fEnumeration; + fEnumerationType = fBase.fEnumerationType; fEnumerationItemType = fBase.fEnumerationItemType; - fWhiteSpace = fBase.fWhiteSpace; - fMaxExclusive = fBase.fMaxExclusive; - fMaxInclusive = fBase.fMaxInclusive; - fMinExclusive = fBase.fMinExclusive; - fMinInclusive = fBase.fMinInclusive; - fTotalDigits = fBase.fTotalDigits; - fFractionDigits = fBase.fFractionDigits; - fPatternType = fBase.fPatternType; - fFixedFacet = fBase.fFixedFacet; - fFacetsDefined = fBase.fFacetsDefined; - - //we also set fundamental facets information in case applyFacets is not called. - caclFundamentalFacets(); - + fWhiteSpace = fBase.fWhiteSpace; + fMaxExclusive = fBase.fMaxExclusive; + fMaxInclusive = fBase.fMaxInclusive; + fMinExclusive = fBase.fMinExclusive; + fMinInclusive = fBase.fMinInclusive; + fTotalDigits = fBase.fTotalDigits; + fFractionDigits = fBase.fFractionDigits; + fPatternType = fBase.fPatternType; + fFixedFacet = fBase.fFixedFacet; + fFacetsDefined = fBase.fFacetsDefined; + + //we also set fundamental facets information in case applyFacets is not called. + caclFundamentalFacets(); + // Inherit from the base type fBuiltInKind = base.fBuiltInKind; - - return this; - } - - //set values for list. - protected XSSimpleTypeDecl setListValues(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, - XSObjectList annotations) { - //decline to do anything if the object is immutable. - if(fIsImmutable) return null; - fBase = fAnySimpleType; - fTypeName = name; - fTargetNamespace = uri; - fFinalSet = finalSet; - fAnnotations = annotations; - - fVariety = VARIETY_LIST; - fItemType = (XSSimpleTypeDecl)itemType; - fValidationDV = DV_LIST; - fFacetsDefined = FACET_WHITESPACE; - fFixedFacet = FACET_WHITESPACE; - fWhiteSpace = WS_COLLAPSE; - - //setting fundamental facets - caclFundamentalFacets(); - + + return this; + } + + //set values for list. + protected XSSimpleTypeDecl setListValues(String name, String uri, short finalSet, XSSimpleTypeDecl itemType, + XSObjectList annotations) { + //decline to do anything if the object is immutable. + if(fIsImmutable) return null; + fBase = fAnySimpleType; + fTypeName = name; + fTargetNamespace = uri; + fFinalSet = finalSet; + fAnnotations = annotations; + + fVariety = VARIETY_LIST; + fItemType = (XSSimpleTypeDecl)itemType; + fValidationDV = DV_LIST; + fFacetsDefined = FACET_WHITESPACE; + fFixedFacet = FACET_WHITESPACE; + fWhiteSpace = WS_COLLAPSE; + + //setting fundamental facets + caclFundamentalFacets(); + // Values of this type are lists fBuiltInKind = XSConstants.LIST_DT; - - return this; - } - - //set values for union. - protected XSSimpleTypeDecl setUnionValues(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes, - XSObjectList annotations) { - //decline to do anything if the object is immutable. - if(fIsImmutable) return null; - fBase = fAnySimpleType; - fTypeName = name; - fTargetNamespace = uri; - fFinalSet = finalSet; - fAnnotations = annotations; - - fVariety = VARIETY_UNION; - fMemberTypes = memberTypes; - fValidationDV = DV_UNION; - // even for union, we set whitespace to something - // this will never be used, but we can use fFacetsDefined to check - // whether applyFacets() is allwwed: it's not allowed - // if fFacetsDefined != 0 - fFacetsDefined = FACET_WHITESPACE; - fWhiteSpace = WS_COLLAPSE; - - //setting fundamental facets - caclFundamentalFacets(); - + + return this; + } + + //set values for union. + protected XSSimpleTypeDecl setUnionValues(String name, String uri, short finalSet, XSSimpleTypeDecl[] memberTypes, + XSObjectList annotations) { + //decline to do anything if the object is immutable. + if(fIsImmutable) return null; + fBase = fAnySimpleType; + fTypeName = name; + fTargetNamespace = uri; + fFinalSet = finalSet; + fAnnotations = annotations; + + fVariety = VARIETY_UNION; + fMemberTypes = memberTypes; + fValidationDV = DV_UNION; + // even for union, we set whitespace to something + // this will never be used, but we can use fFacetsDefined to check + // whether applyFacets() is allwwed: it's not allowed + // if fFacetsDefined != 0 + fFacetsDefined = FACET_WHITESPACE; + fWhiteSpace = WS_COLLAPSE; + + //setting fundamental facets + caclFundamentalFacets(); + // No value can be of this type, so it's unavailable. fBuiltInKind = XSConstants.UNAVAILABLE_DT; - - return this; - } - - public short getType () { - return XSConstants.TYPE_DEFINITION; - } - - public short getTypeCategory () { - return SIMPLE_TYPE; - } - - public String getName() { - return getAnonymous()?null:fTypeName; - } - + + return this; + } + + public short getType () { + return XSConstants.TYPE_DEFINITION; + } + + public short getTypeCategory () { + return SIMPLE_TYPE; + } + + public String getName() { + return getAnonymous()?null:fTypeName; + } + public String getTypeName() { return fTypeName; } @@ -635,7 +640,7 @@ return (short)0; } } - + /** * Returns the closest built-in type category this type represents or * derived from. For example, if this simple type is a built-in derived @@ -801,7 +806,7 @@ patternAnnotations = facets.patternAnnotations; RegularExpression regex = null; try { - regex = new RegularExpression(facets.pattern, "X"); + regex = new RegularExpression(facets.pattern, "X", context.getLocale()); } catch (ParseException e) { reportError("InvalidRegex", new Object[]{facets.pattern, e.getLocalizedMessage(), new Integer(e.getLocation())}); } @@ -1414,7 +1419,7 @@ else { for (int i = fBase.fPattern.size()-1; i >= 0; i--) { fPattern.addElement(fBase.fPattern.elementAt(i)); - fPatternStr.addElement(fBase.fPatternStr.elementAt(i)); + fPatternStr.addElement(fBase.fPatternStr.elementAt(i)); } if (fBase.patternAnnotations != null){ for (int i = fBase.patternAnnotations.getLength()-1;i>=0;i--){ @@ -1512,7 +1517,7 @@ return ob; } - + /** * validate a value, and return the compiled form */ @@ -1535,7 +1540,7 @@ return validatedInfo; } - + /** * validate a value, and return the compiled form */ @@ -1590,7 +1595,7 @@ String content = validatedInfo.normalizedValue; short type = validatedInfo.actualValueType; ShortList itemType = validatedInfo.itemValueTypes; - + // For QName and NOTATION types, we don't check length facets if (fValidationDV != DV_QNAME && fValidationDV != DV_NOTATION) { int length = fDVs[fValidationDV].getDataLength(ob); @@ -1665,215 +1670,215 @@ new Object [] {content, fEnumeration.toString()}); } } - - //fractionDigits - if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) { - int scale = fDVs[fValidationDV].getFractionDigits(ob); - if (scale > fFractionDigits) { - throw new InvalidDatatypeValueException("cvc-fractionDigits-valid", - new Object[] {content, Integer.toString(scale), Integer.toString(fFractionDigits)}); - } - } - - //totalDigits - if ((fFacetsDefined & FACET_TOTALDIGITS)!=0) { - int totalDigits = fDVs[fValidationDV].getTotalDigits(ob); - if (totalDigits > fTotalDigits) { - throw new InvalidDatatypeValueException("cvc-totalDigits-valid", - new Object[] {content, Integer.toString(totalDigits), Integer.toString(fTotalDigits)}); - } - } - - int compare; - - //maxinclusive - if ( (fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) { - compare = fDVs[fValidationDV].compare(ob, fMaxInclusive); - if (compare != -1 && compare != 0) { - throw new InvalidDatatypeValueException("cvc-maxInclusive-valid", - new Object[] {content, fMaxInclusive, fTypeName}); - } - } - - //maxExclusive - if ( (fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 ) { - compare = fDVs[fValidationDV].compare(ob, fMaxExclusive ); - if (compare != -1) { - throw new InvalidDatatypeValueException("cvc-maxExclusive-valid", - new Object[] {content, fMaxExclusive, fTypeName}); - } - } - - //minInclusive - if ( (fFacetsDefined & FACET_MININCLUSIVE) != 0 ) { - compare = fDVs[fValidationDV].compare(ob, fMinInclusive); - if (compare != 1 && compare != 0) { - throw new InvalidDatatypeValueException("cvc-minInclusive-valid", - new Object[] {content, fMinInclusive, fTypeName}); - } - } - - //minExclusive - if ( (fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ) { - compare = fDVs[fValidationDV].compare(ob, fMinExclusive); - if (compare != 1) { - throw new InvalidDatatypeValueException("cvc-minExclusive-valid", - new Object[] {content, fMinExclusive, fTypeName}); - } - } - - } - - private void checkExtraRules(ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException { - - Object ob = validatedInfo.actualValue; - - if (fVariety == VARIETY_ATOMIC) { - - fDVs[fValidationDV].checkExtraRules(ob, context); - - } else if (fVariety == VARIETY_LIST) { - - ListDV.ListData values = (ListDV.ListData)ob; - int len = values.getLength(); - if (fItemType.fVariety == VARIETY_UNION) { - XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[])validatedInfo.memberTypes; - XSSimpleType memberType = validatedInfo.memberType; - for (int i = len-1; i >= 0; i--) { - validatedInfo.actualValue = values.item(i); - validatedInfo.memberType = memberTypes[i]; - fItemType.checkExtraRules(context, validatedInfo); - } - validatedInfo.memberType = memberType; - } else { // (fVariety == VARIETY_ATOMIC) - for (int i = len-1; i >= 0; i--) { - validatedInfo.actualValue = values.item(i); - fItemType.checkExtraRules(context, validatedInfo); - } - } - validatedInfo.actualValue = values; - - } else { // (fVariety == VARIETY_UNION) - - ((XSSimpleTypeDecl)validatedInfo.memberType).checkExtraRules(context, validatedInfo); - - } - - }// checkExtraRules() - - //we can still return object for internal use. - private Object getActualValue(Object content, ValidationContext context, - ValidatedInfo validatedInfo, boolean needNormalize) - throws InvalidDatatypeValueException{ - - String nvalue; - if (needNormalize) { - nvalue = normalize(content, fWhiteSpace); - } else { - nvalue = content.toString(); - } - if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) { - RegularExpression regex; - for (int idx = fPattern.size()-1; idx >= 0; idx--) { - regex = (RegularExpression)fPattern.elementAt(idx); - if (!regex.matches(nvalue)){ - throw new InvalidDatatypeValueException("cvc-pattern-valid", - new Object[]{content, - fPatternStr.elementAt(idx), - - fTypeName}); - } - } - } - - if (fVariety == VARIETY_ATOMIC) { - - // validate special kinds of token, in place of old pattern matching - if (fPatternType != SPECIAL_PATTERN_NONE) { - - boolean seenErr = false; - if (fPatternType == SPECIAL_PATTERN_NMTOKEN) { - // PATTERN "\\c+" - seenErr = !XMLChar.isValidNmtoken(nvalue); - } - else if (fPatternType == SPECIAL_PATTERN_NAME) { - // PATTERN "\\i\\c*" - seenErr = !XMLChar.isValidName(nvalue); - } - else if (fPatternType == SPECIAL_PATTERN_NCNAME) { - // PATTERN "[\\i-[:]][\\c-[:]]*" - seenErr = !XMLChar.isValidNCName(nvalue); - } - if (seenErr) { - throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", - new Object[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]}); - } - } - - validatedInfo.normalizedValue = nvalue; - Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context); - validatedInfo.actualValue = avalue; - validatedInfo.actualValueType = fBuiltInKind; - - return avalue; - - } else if (fVariety == VARIETY_LIST) { - - StringTokenizer parsedList = new StringTokenizer(nvalue, " "); - int countOfTokens = parsedList.countTokens() ; - Object[] avalue = new Object[countOfTokens]; - boolean isUnion = fItemType.getVariety() == VARIETY_UNION; - short[] itemTypes = new short[isUnion ? countOfTokens : 1]; - if (!isUnion) - itemTypes[0] = fItemType.fBuiltInKind; - XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens]; - for(int i = 0 ; i < countOfTokens ; i ++){ - // we can't call fItemType.validate(), otherwise checkExtraRules() - // will be called twice: once in fItemType.validate, once in - // validate method of this type. - // so we take two steps to get the actual value: - // 1. fItemType.getActualValue() - // 2. fItemType.chekcFacets() - avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo, false); - if (context.needFacetChecking() && - (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) { - fItemType.checkFacets(validatedInfo); - } - memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType; - if (isUnion) - itemTypes[i] = memberTypes[i].fBuiltInKind; - } - - ListDV.ListData v = new ListDV.ListData(avalue); - validatedInfo.actualValue = v; - validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT : XSConstants.LIST_DT; - validatedInfo.memberType = null; - validatedInfo.memberTypes = memberTypes; - validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length); - validatedInfo.normalizedValue = nvalue; - - return v; - - } else { // (fVariety == VARIETY_UNION) - for(int i = 0 ; i < fMemberTypes.length; i++) { - try { - // we can't call fMemberType[i].validate(), otherwise checkExtraRules() - // will be called twice: once in fMemberType[i].validate, once in - // validate method of this type. - // so we take two steps to get the actual value: - // 1. fMemberType[i].getActualValue() - // 2. fMemberType[i].chekcFacets() - Object aValue = fMemberTypes[i].getActualValue(content, context, validatedInfo, true); - if (context.needFacetChecking() && - (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) { - fMemberTypes[i].checkFacets(validatedInfo); - } - validatedInfo.memberType = fMemberTypes[i]; - return aValue; - } catch(InvalidDatatypeValueException invalidValue) { - } - } - StringBuffer typesBuffer = new StringBuffer(); + + //fractionDigits + if ((fFacetsDefined & FACET_FRACTIONDIGITS) != 0) { + int scale = fDVs[fValidationDV].getFractionDigits(ob); + if (scale > fFractionDigits) { + throw new InvalidDatatypeValueException("cvc-fractionDigits-valid", + new Object[] {content, Integer.toString(scale), Integer.toString(fFractionDigits)}); + } + } + + //totalDigits + if ((fFacetsDefined & FACET_TOTALDIGITS)!=0) { + int totalDigits = fDVs[fValidationDV].getTotalDigits(ob); + if (totalDigits > fTotalDigits) { + throw new InvalidDatatypeValueException("cvc-totalDigits-valid", + new Object[] {content, Integer.toString(totalDigits), Integer.toString(fTotalDigits)}); + } + } + + int compare; + + //maxinclusive + if ( (fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) { + compare = fDVs[fValidationDV].compare(ob, fMaxInclusive); + if (compare != -1 && compare != 0) { + throw new InvalidDatatypeValueException("cvc-maxInclusive-valid", + new Object[] {content, fMaxInclusive, fTypeName}); + } + } + + //maxExclusive + if ( (fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 ) { + compare = fDVs[fValidationDV].compare(ob, fMaxExclusive ); + if (compare != -1) { + throw new InvalidDatatypeValueException("cvc-maxExclusive-valid", + new Object[] {content, fMaxExclusive, fTypeName}); + } + } + + //minInclusive + if ( (fFacetsDefined & FACET_MININCLUSIVE) != 0 ) { + compare = fDVs[fValidationDV].compare(ob, fMinInclusive); + if (compare != 1 && compare != 0) { + throw new InvalidDatatypeValueException("cvc-minInclusive-valid", + new Object[] {content, fMinInclusive, fTypeName}); + } + } + + //minExclusive + if ( (fFacetsDefined & FACET_MINEXCLUSIVE) != 0 ) { + compare = fDVs[fValidationDV].compare(ob, fMinExclusive); + if (compare != 1) { + throw new InvalidDatatypeValueException("cvc-minExclusive-valid", + new Object[] {content, fMinExclusive, fTypeName}); + } + } + + } + + private void checkExtraRules(ValidationContext context, ValidatedInfo validatedInfo) throws InvalidDatatypeValueException { + + Object ob = validatedInfo.actualValue; + + if (fVariety == VARIETY_ATOMIC) { + + fDVs[fValidationDV].checkExtraRules(ob, context); + + } else if (fVariety == VARIETY_LIST) { + + ListDV.ListData values = (ListDV.ListData)ob; + int len = values.getLength(); + if (fItemType.fVariety == VARIETY_UNION) { + XSSimpleTypeDecl[] memberTypes = (XSSimpleTypeDecl[])validatedInfo.memberTypes; + XSSimpleType memberType = validatedInfo.memberType; + for (int i = len-1; i >= 0; i--) { + validatedInfo.actualValue = values.item(i); + validatedInfo.memberType = memberTypes[i]; + fItemType.checkExtraRules(context, validatedInfo); + } + validatedInfo.memberType = memberType; + } else { // (fVariety == VARIETY_ATOMIC) + for (int i = len-1; i >= 0; i--) { + validatedInfo.actualValue = values.item(i); + fItemType.checkExtraRules(context, validatedInfo); + } + } + validatedInfo.actualValue = values; + + } else { // (fVariety == VARIETY_UNION) + + ((XSSimpleTypeDecl)validatedInfo.memberType).checkExtraRules(context, validatedInfo); + + } + + }// checkExtraRules() + + //we can still return object for internal use. + private Object getActualValue(Object content, ValidationContext context, + ValidatedInfo validatedInfo, boolean needNormalize) + throws InvalidDatatypeValueException{ + + String nvalue; + if (needNormalize) { + nvalue = normalize(content, fWhiteSpace); + } else { + nvalue = content.toString(); + } + if ( (fFacetsDefined & FACET_PATTERN ) != 0 ) { + RegularExpression regex; + for (int idx = fPattern.size()-1; idx >= 0; idx--) { + regex = (RegularExpression)fPattern.elementAt(idx); + if (!regex.matches(nvalue)){ + throw new InvalidDatatypeValueException("cvc-pattern-valid", + new Object[]{content, + fPatternStr.elementAt(idx), + + fTypeName}); + } + } + } + + if (fVariety == VARIETY_ATOMIC) { + + // validate special kinds of token, in place of old pattern matching + if (fPatternType != SPECIAL_PATTERN_NONE) { + + boolean seenErr = false; + if (fPatternType == SPECIAL_PATTERN_NMTOKEN) { + // PATTERN "\\c+" + seenErr = !XMLChar.isValidNmtoken(nvalue); + } + else if (fPatternType == SPECIAL_PATTERN_NAME) { + // PATTERN "\\i\\c*" + seenErr = !XMLChar.isValidName(nvalue); + } + else if (fPatternType == SPECIAL_PATTERN_NCNAME) { + // PATTERN "[\\i-[:]][\\c-[:]]*" + seenErr = !XMLChar.isValidNCName(nvalue); + } + if (seenErr) { + throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", + new Object[]{nvalue, SPECIAL_PATTERN_STRING[fPatternType]}); + } + } + + validatedInfo.normalizedValue = nvalue; + Object avalue = fDVs[fValidationDV].getActualValue(nvalue, context); + validatedInfo.actualValue = avalue; + validatedInfo.actualValueType = fBuiltInKind; + + return avalue; + + } else if (fVariety == VARIETY_LIST) { + + StringTokenizer parsedList = new StringTokenizer(nvalue, " "); + int countOfTokens = parsedList.countTokens() ; + Object[] avalue = new Object[countOfTokens]; + boolean isUnion = fItemType.getVariety() == VARIETY_UNION; + short[] itemTypes = new short[isUnion ? countOfTokens : 1]; + if (!isUnion) + itemTypes[0] = fItemType.fBuiltInKind; + XSSimpleTypeDecl[] memberTypes = new XSSimpleTypeDecl[countOfTokens]; + for(int i = 0 ; i < countOfTokens ; i ++){ + // we can't call fItemType.validate(), otherwise checkExtraRules() + // will be called twice: once in fItemType.validate, once in + // validate method of this type. + // so we take two steps to get the actual value: + // 1. fItemType.getActualValue() + // 2. fItemType.chekcFacets() + avalue[i] = fItemType.getActualValue(parsedList.nextToken(), context, validatedInfo, false); + if (context.needFacetChecking() && + (fItemType.fFacetsDefined != 0 && fItemType.fFacetsDefined != FACET_WHITESPACE)) { + fItemType.checkFacets(validatedInfo); + } + memberTypes[i] = (XSSimpleTypeDecl)validatedInfo.memberType; + if (isUnion) + itemTypes[i] = memberTypes[i].fBuiltInKind; + } + + ListDV.ListData v = new ListDV.ListData(avalue); + validatedInfo.actualValue = v; + validatedInfo.actualValueType = isUnion ? XSConstants.LISTOFUNION_DT : XSConstants.LIST_DT; + validatedInfo.memberType = null; + validatedInfo.memberTypes = memberTypes; + validatedInfo.itemValueTypes = new ShortListImpl(itemTypes, itemTypes.length); + validatedInfo.normalizedValue = nvalue; + + return v; + + } else { // (fVariety == VARIETY_UNION) + for(int i = 0 ; i < fMemberTypes.length; i++) { + try { + // we can't call fMemberType[i].validate(), otherwise checkExtraRules() + // will be called twice: once in fMemberType[i].validate, once in + // validate method of this type. + // so we take two steps to get the actual value: + // 1. fMemberType[i].getActualValue() + // 2. fMemberType[i].chekcFacets() + Object aValue = fMemberTypes[i].getActualValue(content, context, validatedInfo, true); + if (context.needFacetChecking() && + (fMemberTypes[i].fFacetsDefined != 0 && fMemberTypes[i].fFacetsDefined != FACET_WHITESPACE)) { + fMemberTypes[i].checkFacets(validatedInfo); + } + validatedInfo.memberType = fMemberTypes[i]; + return aValue; + } catch(InvalidDatatypeValueException invalidValue) { + } + } + StringBuffer typesBuffer = new StringBuffer(); XSSimpleTypeDecl decl; for(int i = 0;i < fMemberTypes.length; i++) { if(i != 0) @@ -1894,312 +1899,312 @@ typesBuffer.append(v.elementAt(j)); } typesBuffer.append(']'); - } + } } - throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", - new Object[]{content, fTypeName, typesBuffer.toString()}); - } - - }//getActualValue() - - public boolean isEqual(Object value1, Object value2) { - if (value1 == null) { - return false; - } - return value1.equals(value2); - }//isEqual() - - // determine whether the two values are identical - public boolean isIdentical (Object value1, Object value2) { - if (value1 == null) { - return false; - } - return fDVs[fValidationDV].isIdentical(value1, value2); - }//isIdentical() - - // normalize the string according to the whiteSpace facet - public static String normalize(String content, short ws) { - int len = content == null ? 0 : content.length(); - if (len == 0 || ws == WS_PRESERVE) - return content; - - StringBuffer sb = new StringBuffer(); - if (ws == WS_REPLACE) { - char ch; - // when it's replace, just replace #x9, #xa, #xd by #x20 - for (int i = 0; i < len; i++) { - ch = content.charAt(i); - if (ch != 0x9 && ch != 0xa && ch != 0xd) - sb.append(ch); - else - sb.append((char)0x20); - } - } else { - char ch; - int i; - boolean isLeading = true; - // when it's collapse - for (i = 0; i < len; i++) { - ch = content.charAt(i); - // append real characters, so we passed leading ws - if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) { - sb.append(ch); - isLeading = false; - } - else { - // for whitespaces, we skip all following ws - for (; i < len-1; i++) { - ch = content.charAt(i+1); - if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) - break; - } - // if it's not a leading or tailing ws, then append a space - if (i < len - 1 && !isLeading) - sb.append((char)0x20); - } - } - } - - return sb.toString(); - } - - // normalize the string according to the whiteSpace facet - protected String normalize(Object content, short ws) { - if (content == null) - return null; - - // If pattern is not defined, we can skip some of the normalization. - // Otherwise we have to normalize the data for correct result of - // pattern validation. - if ( (fFacetsDefined & FACET_PATTERN ) == 0 ) { - short norm_type = fDVNormalizeType[fValidationDV]; - if (norm_type == NORMALIZE_NONE) { - return content.toString(); - } - else if (norm_type == NORMALIZE_TRIM) { - return content.toString().trim(); - } - } - - if (!(content instanceof StringBuffer)) { - String strContent = content.toString(); - return normalize(strContent, ws); - } - - StringBuffer sb = (StringBuffer)content; - int len = sb.length(); - if (len == 0) - return ""; - if (ws == WS_PRESERVE) - return sb.toString(); - - if (ws == WS_REPLACE) { - char ch; - // when it's replace, just replace #x9, #xa, #xd by #x20 - for (int i = 0; i < len; i++) { - ch = sb.charAt(i); - if (ch == 0x9 || ch == 0xa || ch == 0xd) - sb.setCharAt(i, (char)0x20); - } - } else { - char ch; - int i, j = 0; - boolean isLeading = true; - // when it's collapse - for (i = 0; i < len; i++) { - ch = sb.charAt(i); - // append real characters, so we passed leading ws - if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) { - sb.setCharAt(j++, ch); - isLeading = false; - } - else { - // for whitespaces, we skip all following ws - for (; i < len-1; i++) { - ch = sb.charAt(i+1); - if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) - break; - } - // if it's not a leading or tailing ws, then append a space - if (i < len - 1 && !isLeading) - sb.setCharAt(j++, (char)0x20); - } - } - sb.setLength(j); - } - - return sb.toString(); - } - - void reportError(String key, Object[] args) throws InvalidDatatypeFacetException { - throw new InvalidDatatypeFacetException(key, args); - } - - - private String whiteSpaceValue(short ws){ - return WS_FACET_STRING[ws]; - } - - /** - * Fundamental Facet: ordered. - */ - public short getOrdered() { - return fOrdered; - } - - /** - * Fundamental Facet: bounded. - */ - public boolean getBounded(){ - return fBounded; - } - - /** - * Fundamental Facet: cardinality. - */ - public boolean getFinite(){ - return fFinite; - } - - /** - * Fundamental Facet: numeric. - */ - public boolean getNumeric(){ - return fNumeric; - } - - /** - * Convenience method. [Facets]: check whether a facet is defined on this - * type. - * @param facetName The name of the facet. - * @return True if the facet is defined, false otherwise. - */ - public boolean isDefinedFacet(short facetName) { - if ((fFacetsDefined & facetName) != 0) - return true; - if (fPatternType != SPECIAL_PATTERN_NONE) - return facetName == FACET_PATTERN; - if (fValidationDV == DV_INTEGER) - return facetName == FACET_PATTERN || facetName == FACET_FRACTIONDIGITS; - return false; - } - - /** - * [facets]: all facets defined on this type. The value is a bit - * combination of FACET_XXX constants of all defined facets. - */ - public short getDefinedFacets() { - if (fPatternType != SPECIAL_PATTERN_NONE) - return (short)(fFacetsDefined | FACET_PATTERN); - if (fValidationDV == DV_INTEGER) - return (short)(fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS); - return fFacetsDefined; - } - - /** - * Convenience method. [Facets]: check whether a facet is defined and - * fixed on this type. - * @param facetName The name of the facet. - * @return True if the facet is fixed, false otherwise. - */ - public boolean isFixedFacet(short facetName) { - if ((fFixedFacet & facetName) != 0) - return true; - if (fValidationDV == DV_INTEGER) - return facetName == FACET_FRACTIONDIGITS; - return false; - } - - /** - * [facets]: all defined facets for this type which are fixed. - */ - public short getFixedFacets() { - if (fValidationDV == DV_INTEGER) - return (short)(fFixedFacet | FACET_FRACTIONDIGITS); - return fFixedFacet; - } - - /** - * Convenience method. Returns a value of a single constraining facet for - * this simple type definition. This method must not be used to retrieve - * values for <code>enumeration</code> and <code>pattern</code> facets. - * @param facetName The name of the facet, i.e. - * <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see - * <code>XSConstants</code>). To retrieve the value for a pattern or - * an enumeration, see <code>enumeration</code> and - * <code>pattern</code>. - * @return A value of the facet specified in <code>facetName</code> for - * this simple type definition or <code>null</code>. - */ - public String getLexicalFacetValue(short facetName) { - switch (facetName) { - case FACET_LENGTH: - return (fLength == -1)?null:Integer.toString(fLength); - case FACET_MINLENGTH: - return (fMinLength == -1)?null:Integer.toString(fMinLength); - case FACET_MAXLENGTH: - return (fMaxLength == -1)?null:Integer.toString(fMaxLength); - case FACET_WHITESPACE: - return WS_FACET_STRING[fWhiteSpace]; - case FACET_MAXINCLUSIVE: - return (fMaxInclusive == null)?null:fMaxInclusive.toString(); - case FACET_MAXEXCLUSIVE: - return (fMaxExclusive == null)?null:fMaxExclusive.toString(); - case FACET_MINEXCLUSIVE: - return (fMinExclusive == null)?null:fMinExclusive.toString(); - case FACET_MININCLUSIVE: - return (fMinInclusive == null)?null:fMinInclusive.toString(); - case FACET_TOTALDIGITS: - if (fValidationDV == DV_INTEGER) - return "0"; - return (fTotalDigits == -1)?null:Integer.toString(fTotalDigits); - case FACET_FRACTIONDIGITS: - return (fFractionDigits == -1)?null:Integer.toString(fFractionDigits); - } - return null; - } - - /** - * A list of enumeration values if it exists, otherwise an empty - * <code>StringList</code>. - */ - public StringList getLexicalEnumeration() { - if (fLexicalEnumeration == null){ - if (fEnumeration == null) - return StringListImpl.EMPTY_LIST; - int size = fEnumeration.size(); - String[] strs = new String[size]; - for (int i = 0; i < size; i++) - strs[i] = fEnumeration.elementAt(i).toString(); - fLexicalEnumeration = new StringListImpl(strs, size); - } - return fLexicalEnumeration; - } - - /** - * A list of actual enumeration values if it exists, otherwise an empty - * <code>ObjectList</code>. - */ - public ObjectList getActualEnumeration() { - if (fActualEnumeration == null) { - fActualEnumeration = new ObjectList () { - public int getLength() { - return (fEnumeration != null) ? fEnumeration.size() : 0; - } - public boolean contains(Object item) { - return (fEnumeration != null && fEnumeration.contains(item)); - } - public Object item(int index) { - if (index < 0 || index >= getLength()) { - return null; - } - return fEnumeration.elementAt(index); - } - }; - } - return fActualEnumeration; - } - + throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.3", + new Object[]{content, fTypeName, typesBuffer.toString()}); + } + + }//getActualValue() + + public boolean isEqual(Object value1, Object value2) { + if (value1 == null) { + return false; + } + return value1.equals(value2); + }//isEqual() + + // determine whether the two values are identical + public boolean isIdentical (Object value1, Object value2) { + if (value1 == null) { + return false; + } + return fDVs[fValidationDV].isIdentical(value1, value2); + }//isIdentical() + + // normalize the string according to the whiteSpace facet + public static String normalize(String content, short ws) { + int len = content == null ? 0 : content.length(); + if (len == 0 || ws == WS_PRESERVE) + return content; + + StringBuffer sb = new StringBuffer(); + if (ws == WS_REPLACE) { + char ch; + // when it's replace, just replace #x9, #xa, #xd by #x20 + for (int i = 0; i < len; i++) { + ch = content.charAt(i); + if (ch != 0x9 && ch != 0xa && ch != 0xd) + sb.append(ch); + else + sb.append((char)0x20); + } + } else { + char ch; + int i; + boolean isLeading = true; + // when it's collapse + for (i = 0; i < len; i++) { + ch = content.charAt(i); + // append real characters, so we passed leading ws + if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) { + sb.append(ch); + isLeading = false; + } + else { + // for whitespaces, we skip all following ws + for (; i < len-1; i++) { + ch = content.charAt(i+1); + if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) + break; + } + // if it's not a leading or tailing ws, then append a space + if (i < len - 1 && !isLeading) + sb.append((char)0x20); + } + } + } + + return sb.toString(); + } + + // normalize the string according to the whiteSpace facet + protected String normalize(Object content, short ws) { + if (content == null) + return null; + + // If pattern is not defined, we can skip some of the normalization. + // Otherwise we have to normalize the data for correct result of + // pattern validation. + if ( (fFacetsDefined & FACET_PATTERN ) == 0 ) { + short norm_type = fDVNormalizeType[fValidationDV]; + if (norm_type == NORMALIZE_NONE) { + return content.toString(); + } + else if (norm_type == NORMALIZE_TRIM) { + return content.toString().trim(); + } + } + + if (!(content instanceof StringBuffer)) { + String strContent = content.toString(); + return normalize(strContent, ws); + } + + StringBuffer sb = (StringBuffer)content; + int len = sb.length(); + if (len == 0) + return ""; + if (ws == WS_PRESERVE) + return sb.toString(); + + if (ws == WS_REPLACE) { + char ch; + // when it's replace, just replace #x9, #xa, #xd by #x20 + for (int i = 0; i < len; i++) { + ch = sb.charAt(i); + if (ch == 0x9 || ch == 0xa || ch == 0xd) + sb.setCharAt(i, (char)0x20); + } + } else { + char ch; + int i, j = 0; + boolean isLeading = true; + // when it's collapse + for (i = 0; i < len; i++) { + ch = sb.charAt(i); + // append real characters, so we passed leading ws + if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) { + sb.setCharAt(j++, ch); + isLeading = false; + } + else { + // for whitespaces, we skip all following ws + for (; i < len-1; i++) { + ch = sb.charAt(i+1); + if (ch != 0x9 && ch != 0xa && ch != 0xd && ch != 0x20) + break; + } + // if it's not a leading or tailing ws, then append a space + if (i < len - 1 && !isLeading) + sb.setCharAt(j++, (char)0x20); + } + } + sb.setLength(j); + } + + return sb.toString(); + } + + void reportError(String key, Object[] args) throws InvalidDatatypeFacetException { + throw new InvalidDatatypeFacetException(key, args); + } + + + private String whiteSpaceValue(short ws){ + return WS_FACET_STRING[ws]; + } + + /** + * Fundamental Facet: ordered. + */ + public short getOrdered() { + return fOrdered; + } + + /** + * Fundamental Facet: bounded. + */ + public boolean getBounded(){ + return fBounded; + } + + /** + * Fundamental Facet: cardinality. + */ + public boolean getFinite(){ + return fFinite; + } + + /** + * Fundamental Facet: numeric. + */ + public boolean getNumeric(){ + return fNumeric; + } + + /** + * Convenience method. [Facets]: check whether a facet is defined on this + * type. + * @param facetName The name of the facet. + * @return True if the facet is defined, false otherwise. + */ + public boolean isDefinedFacet(short facetName) { + if ((fFacetsDefined & facetName) != 0) + return true; + if (fPatternType != SPECIAL_PATTERN_NONE) + return facetName == FACET_PATTERN; + if (fValidationDV == DV_INTEGER) + return facetName == FACET_PATTERN || facetName == FACET_FRACTIONDIGITS; + return false; + } + + /** + * [facets]: all facets defined on this type. The value is a bit + * combination of FACET_XXX constants of all defined facets. + */ + public short getDefinedFacets() { + if (fPatternType != SPECIAL_PATTERN_NONE) + return (short)(fFacetsDefined | FACET_PATTERN); + if (fValidationDV == DV_INTEGER) + return (short)(fFacetsDefined | FACET_PATTERN | FACET_FRACTIONDIGITS); + return fFacetsDefined; + } + + /** + * Convenience method. [Facets]: check whether a facet is defined and + * fixed on this type. + * @param facetName The name of the facet. + * @return True if the facet is fixed, false otherwise. + */ + public boolean isFixedFacet(short facetName) { + if ((fFixedFacet & facetName) != 0) + return true; + if (fValidationDV == DV_INTEGER) + return facetName == FACET_FRACTIONDIGITS; + return false; + } + + /** + * [facets]: all defined facets for this type which are fixed. + */ + public short getFixedFacets() { + if (fValidationDV == DV_INTEGER) + return (short)(fFixedFacet | FACET_FRACTIONDIGITS); + return fFixedFacet; + } + + /** + * Convenience method. Returns a value of a single constraining facet for + * this simple type definition. This method must not be used to retrieve + * values for <code>enumeration</code> and <code>pattern</code> facets. + * @param facetName The name of the facet, i.e. + * <code>FACET_LENGTH, FACET_TOTALDIGITS </code> (see + * <code>XSConstants</code>). To retrieve the value for a pattern or + * an enumeration, see <code>enumeration</code> and + * <code>pattern</code>. + * @return A value of the facet specified in <code>facetName</code> for + * this simple type definition or <code>null</code>. + */ + public String getLexicalFacetValue(short facetName) { + switch (facetName) { + case FACET_LENGTH: + return (fLength == -1)?null:Integer.toString(fLength); + case FACET_MINLENGTH: + return (fMinLength == -1)?null:Integer.toString(fMinLength); + case FACET_MAXLENGTH: + return (fMaxLength == -1)?null:Integer.toString(fMaxLength); + case FACET_WHITESPACE: + return WS_FACET_STRING[fWhiteSpace]; + case FACET_MAXINCLUSIVE: + return (fMaxInclusive == null)?null:fMaxInclusive.toString(); + case FACET_MAXEXCLUSIVE: + return (fMaxExclusive == null)?null:fMaxExclusive.toString(); + case FACET_MINEXCLUSIVE: + return (fMinExclusive == null)?null:fMinExclusive.toString(); + case FACET_MININCLUSIVE: + return (fMinInclusive == null)?null:fMinInclusive.toString(); + case FACET_TOTALDIGITS: + if (fValidationDV == DV_INTEGER) + return "0"; + return (fTotalDigits == -1)?null:Integer.toString(fTotalDigits); + case FACET_FRACTIONDIGITS: + return (fFractionDigits == -1)?null:Integer.toString(fFractionDigits); + } + return null; + } + + /** + * A list of enumeration values if it exists, otherwise an empty + * <code>StringList</code>. + */ + public StringList getLexicalEnumeration() { + if (fLexicalEnumeration == null){ + if (fEnumeration == null) + return StringListImpl.EMPTY_LIST; + int size = fEnumeration.size(); + String[] strs = new String[size]; + for (int i = 0; i < size; i++) + strs[i] = fEnumeration.elementAt(i).toString(); + fLexicalEnumeration = new StringListImpl(strs, size); + } + return fLexicalEnumeration; + } + + /** + * A list of actual enumeration values if it exists, otherwise an empty + * <code>ObjectList</code>. + */ + public ObjectList getActualEnumeration() { + if (fActualEnumeration == null) { + fActualEnumeration = new ObjectList () { + public int getLength() { + return (fEnumeration != null) ? fEnumeration.size() : 0; + } + public boolean contains(Object item) { + return (fEnumeration != null && fEnumeration.contains(item)); + } + public Object item(int index) { + if (index < 0 || index >= getLength()) { + return null; + } + return fEnumeration.elementAt(index); + } + }; + } + return fActualEnumeration; + } + /** * A list of enumeration type values (as a list of ShortList objects) if it exists, otherwise returns * null @@ -2230,1007 +2235,1015 @@ } return fEnumerationItemTypeList; } - - public ShortList getEnumerationTypeList() { - if (fEnumerationTypeList == null) { + + public ShortList getEnumerationTypeList() { + if (fEnumerationTypeList == null) { if (fEnumerationType == null) return null; fEnumerationTypeList = new ShortListImpl (fEnumerationType, fEnumerationType.length); - } - return fEnumerationTypeList; - } - - /** - * A list of pattern values if it exists, otherwise an empty - * <code>StringList</code>. - */ - public StringList getLexicalPattern() { - if (fPatternType == SPECIAL_PATTERN_NONE && fValidationDV != DV_INTEGER && fPatternStr == null) - return StringListImpl.EMPTY_LIST; - if (fLexicalPattern == null){ - int size = fPatternStr == null ? 0 : fPatternStr.size(); - String[] strs; - if (fPatternType == SPECIAL_PATTERN_NMTOKEN) { - strs = new String[size+1]; - strs[size] = "\\c+"; - } - else if (fPatternType == SPECIAL_PATTERN_NAME) { - strs = new String[size+1]; - strs[size] = "\\i\\c*"; - } - else if (fPatternType == SPECIAL_PATTERN_NCNAME) { - strs = new String[size+2]; - strs[size] = "\\i\\c*"; - strs[size+1] = "[\\i-[:]][\\c-[:]]*"; - } - else if (fValidationDV == DV_INTEGER) { - strs = new String[size+1]; - strs[size] = "[\\-+]?[0-9]+"; - } - else { - strs = new String[size]; - } - for (int i = 0; i < size; i++) - strs[i] = (String)fPatternStr.elementAt(i); - fLexicalPattern = new StringListImpl(strs, strs.length); - } - return fLexicalPattern; - } - - /** - * [annotations]: a set of annotations for this simple type component if - * it exists, otherwise an empty <code>XSObjectList</code>. - */ - public XSObjectList getAnnotations() { - return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST; - } - - private void caclFundamentalFacets() { - setOrdered(); - setNumeric(); - setBounded(); - setCardinality(); - } - - private void setOrdered(){ - - // When {variety} is atomic, {value} is inherited from {value} of {base type definition}. For all "primitive" types {value} is as specified in the table in Fundamental Facets (C.1). - if(fVariety == VARIETY_ATOMIC){ - this.fOrdered = fBase.fOrdered; - } - - // When {variety} is list, {value} is false. - else if(fVariety == VARIETY_LIST){ - this.fOrdered = ORDERED_FALSE; - } - - // When {variety} is union, the {value} is partial unless one of the following: - // 1. If every member of {member type definitions} is derived from a common ancestor other than the simple ur-type, then {value} is the same as that ancestor's ordered facet. - // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false. - else if(fVariety == VARIETY_UNION){ - int length = fMemberTypes.length; - // REVISIT: is the length possible to be 0? - if (length == 0) { - this.fOrdered = ORDERED_PARTIAL; - return; - } - // we need to process the first member type before entering the loop - short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV); - boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE; - boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE; - // for the other member types, check whether the value is false - // and whether they have the same ancestor as the first one - for (int i = 1; i < fMemberTypes.length && (commonAnc || allFalse); i++) { - if (commonAnc) - commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV); - if (allFalse) - allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE; - } - if (commonAnc) { - // REVISIT: all member types should have the same ordered value - // just use the first one. Can we assume this? - this.fOrdered = fMemberTypes[0].fOrdered; - } else if (allFalse) { - this.fOrdered = ORDERED_FALSE; - } else { - this.fOrdered = ORDERED_PARTIAL; - } - } - - }//setOrdered - - private void setNumeric(){ - if(fVariety == VARIETY_ATOMIC){ - this.fNumeric = fBase.fNumeric; - } - else if(fVariety == VARIETY_LIST){ - this.fNumeric = false; - } - else if(fVariety == VARIETY_UNION){ - XSSimpleType[] memberTypes = fMemberTypes; - for(int i = 0 ; i < memberTypes.length ; i++){ - if(!memberTypes[i].getNumeric() ){ - this.fNumeric = false; - return; - } - } - this.fNumeric = true; - } - - }//setNumeric - - private void setBounded(){ - if(fVariety == VARIETY_ATOMIC){ - if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) - && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) ){ - this.fBounded = true; - } - else{ - this.fBounded = false; - } - } - else if(fVariety == VARIETY_LIST){ - if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 ) - && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){ - this.fBounded = true; - } - else{ - this.fBounded = false; - } - - } - else if(fVariety == VARIETY_UNION){ - - XSSimpleTypeDecl [] memberTypes = this.fMemberTypes; - short ancestorId = 0 ; - - if(memberTypes.length > 0){ - ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV); - } - - for(int i = 0 ; i < memberTypes.length ; i++){ - if(!memberTypes[i].getBounded() || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV)) ){ - this.fBounded = false; - return; - } - } - this.fBounded = true; - } - - }//setBounded - - private boolean specialCardinalityCheck(){ - if( (fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH) - || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY) - || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH) ){ - return true; - } - return false; - - } //specialCardinalityCheck() - - private void setCardinality(){ - if(fVariety == VARIETY_ATOMIC){ - if(fBase.fFinite){ - this.fFinite = true; - } - else {// (!fBase.fFinite) - if ( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 ) - || ((this.fFacetsDefined & FACET_TOTALDIGITS) != 0 ) ){ - this.fFinite = true; - } - else if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0 )) - && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 )) ){ - if( ((this.fFacetsDefined & FACET_FRACTIONDIGITS) != 0 ) || specialCardinalityCheck()){ - this.fFinite = true; - } - else{ - this.fFinite = false; - } - } - else{ - this.fFinite = false; - } - } - } - else if(fVariety == VARIETY_LIST){ - if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 ) - && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){ - this.fFinite = true; - } - else{ - this.fFinite = false; - } - - } - else if(fVariety == VARIETY_UNION){ - XSSimpleType [] memberTypes = fMemberTypes; - for(int i = 0 ; i < memberTypes.length ; i++){ - if(!(memberTypes[i].getFinite()) ){ - this.fFinite = false; - return; - } - } - this.fFinite = true; - } - - }//setCardinality - - private short getPrimitiveDV(short validationDV){ - - if (validationDV == DV_ID || validationDV == DV_IDREF || validationDV == DV_ENTITY){ - return DV_STRING; - } - else if (validationDV == DV_INTEGER) { - return DV_DECIMAL; - } - else if (Constants.SCHEMA_1_1_SUPPORT && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) { - return DV_DURATION; - } - else { - return validationDV; - } - - }//getPrimitiveDV() - - public boolean derivedFromType(XSTypeDefinition ancestor, short derivation) { - // REVISIT: implement according to derivation - - // ancestor is null, retur false - if (ancestor == null) - return false; - // ancestor is anyType, return true - // anyType is the only type whose base type is itself - if (ancestor.getBaseType() == ancestor) - return true; - // recursively get base, and compare it with ancestor - XSTypeDefinition type = this; - while (type != ancestor && // compare with ancestor - type != fAnySimpleType) { // reached anySimpleType - type = type.getBaseType(); - } - - return type == ancestor; - } - - public boolean derivedFrom(String ancestorNS, String ancestorName, short derivation) { - // REVISIT: implement according to derivation - - // ancestor is null, retur false - if (ancestorName == null) - return false; - // ancestor is anyType, return true - if (URI_SCHEMAFORSCHEMA.equals(ancestorNS) && - ANY_TYPE.equals(ancestorName)) { - return true; - } - - // recursively get base, and compare it with ancestor - XSTypeDefinition type = this; - while (!(ancestorName.equals(type.getName()) && - ((ancestorNS == null && type.getNamespace() == null) || - (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) && // compare with ancestor - type != fAnySimpleType) { // reached anySimpleType - type = (XSTypeDefinition)type.getBaseType(); - } - - return type != fAnySimpleType; - } - - /** - * Checks if a type is derived from another by restriction, given the name - * and namespace. See: - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * - * @param ancestorNS - * The namspace of the ancestor type declaration - * @param ancestorName - * The name of the ancestor type declaration - * @param derivationMethod - * The derivation method - * - * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method. - */ - public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName, int derivationMethod) { - - // ancestor is null, return false - if (ancestorName == null) - return false; - - // ancestor is anyType, return true - if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS) - && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName) - && (((derivationMethod & DERIVATION_RESTRICTION) != 0) - || (derivationMethod == DERIVATION_ANY))) { - return true; - } - - // restriction - if ((derivationMethod & DERIVATION_RESTRICTION) != 0) { - if (isDerivedByRestriction(ancestorNS, ancestorName, this)) { - return true; - } - } - - // list - if ((derivationMethod & DERIVATION_LIST) != 0) { - if (isDerivedByList(ancestorNS, ancestorName, this)) { - return true; - } - } - - // union - if ((derivationMethod & DERIVATION_UNION) != 0) { - if (isDerivedByUnion(ancestorNS, ancestorName, this)) { - return true; - } - } - - // extension - if (((derivationMethod & DERIVATION_EXTENSION) != 0) - && (((derivationMethod & DERIVATION_RESTRICTION) == 0) - && ((derivationMethod & DERIVATION_LIST) == 0) - && ((derivationMethod & DERIVATION_UNION) == 0))) { - return false; - } - - // If the value of the parameter is 0 i.e. no bit (corresponding to - // restriction, list, extension or union) is set to 1 for the - // derivationMethod parameter. - if (((derivationMethod & DERIVATION_EXTENSION) == 0) - && (((derivationMethod & DERIVATION_RESTRICTION) == 0) - && ((derivationMethod & DERIVATION_LIST) == 0) - && ((derivationMethod & DERIVATION_UNION) == 0))) { - return isDerivedByAny(ancestorNS, ancestorName, this); - } - - return false; - } - - - /** - * Checks if a type is derived from another by any combination of restriction, list ir union. See: - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * - * @param ancestorNS - * The namspace of the ancestor type declaration - * @param ancestorName - * The name of the ancestor type declaration - * @param type - * The reference type definition - * - * @return boolean True if the type is derived by restriciton for the reference type - */ - private boolean isDerivedByAny(String ancestorNS, String ancestorName, - XSTypeDefinition type) { - - boolean derivedFrom = false; - XSTypeDefinition oldType = null; - // for each base, item or member type - while (type != null && type != oldType) { - - // If the ancestor type is reached or is the same as this type. - if ((ancestorName.equals(type.getName())) - && ((ancestorNS == null && type.getNamespace() == null) - || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) { - derivedFrom = true; - break; - } - - // check if derived by restriction or list or union - if (isDerivedByRestriction(ancestorNS, ancestorName, type)) { - return true; - } else if (isDerivedByList(ancestorNS, ancestorName, type)) { - return true; - } else if (isDerivedByUnion(ancestorNS, ancestorName, type)) { - return true; - } - oldType = type; - // get the base, item or member type depending on the variety - if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT - || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) { - type = type.getBaseType(); - } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) { - for (int i = 0; i < ((XSSimpleTypeDecl) type).getMemberTypes().getLength(); i++) { - return isDerivedByAny(ancestorNS, ancestorName, - (XSTypeDefinition) ((XSSimpleTypeDecl) type) - .getMemberTypes().item(i)); - } - } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) { - type = ((XSSimpleTypeDecl) type).getItemType(); - } - } - - return derivedFrom; - } + } + return fEnumerationTypeList; + } + + /** + * A list of pattern values if it exists, otherwise an empty + * <code>StringList</code>. + */ + public StringList getLexicalPattern() { + if (fPatternType == SPECIAL_PATTERN_NONE && fValidationDV != DV_INTEGER && fPatternStr == null) + return StringListImpl.EMPTY_LIST; + if (fLexicalPattern == null){ + int size = fPatternStr == null ? 0 : fPatternStr.size(); + String[] strs; + if (fPatternType == SPECIAL_PATTERN_NMTOKEN) { + strs = new String[size+1]; + strs[size] = "\\c+"; + } + else if (fPatternType == SPECIAL_PATTERN_NAME) { + strs = new String[size+1]; + strs[size] = "\\i\\c*"; + } + else if (fPatternType == SPECIAL_PATTERN_NCNAME) { + strs = new String[size+2]; + strs[size] = "\\i\\c*"; + strs[size+1] = "[\\i-[:]][\\c-[:]]*"; + } + else if (fValidationDV == DV_INTEGER) { + strs = new String[size+1]; + strs[size] = "[\\-+]?[0-9]+"; + } + else { + strs = new String[size]; + } + for (int i = 0; i < size; i++) + strs[i] = (String)fPatternStr.elementAt(i); + fLexicalPattern = new StringListImpl(strs, strs.length); + } + return fLexicalPattern; + } + + /** + * [annotations]: a set of annotations for this simple type component if + * it exists, otherwise an empty <code>XSObjectList</code>. + */ + public XSObjectList getAnnotations() { + return (fAnnotations != null) ? fAnnotations : XSObjectListImpl.EMPTY_LIST; + } + + private void caclFundamentalFacets() { + setOrdered(); + setNumeric(); + setBounded(); + setCardinality(); + } + + private void setOrdered(){ + + // When {variety} is atomic, {value} is inherited from {value} of {base type definition}. For all "primitive" types {value} is as specified in the table in Fundamental Facets (C.1). + if(fVariety == VARIETY_ATOMIC){ + this.fOrdered = fBase.fOrdered; + } + + // When {variety} is list, {value} is false. + else if(fVariety == VARIETY_LIST){ + this.fOrdered = ORDERED_FALSE; + } + + // When {variety} is union, the {value} is partial unless one of the following: + // 1. If every member of {member type definitions} is derived from a common ancestor other than the simple ur-type, then {value} is the same as that ancestor's ordered facet. + // 2. If every member of {member type definitions} has a {value} of false for the ordered facet, then {value} is false. + else if(fVariety == VARIETY_UNION){ + int length = fMemberTypes.length; + // REVISIT: is the length possible to be 0? + if (length == 0) { + this.fOrdered = ORDERED_PARTIAL; + return; + } + // we need to process the first member type before entering the loop + short ancestorId = getPrimitiveDV(fMemberTypes[0].fValidationDV); + boolean commonAnc = ancestorId != DV_ANYSIMPLETYPE; + boolean allFalse = fMemberTypes[0].fOrdered == ORDERED_FALSE; + // for the other member types, check whether the value is false + // and whether they have the same ancestor as the first one + for (int i = 1; i < fMemberTypes.length && (commonAnc || allFalse); i++) { + if (commonAnc) + commonAnc = ancestorId == getPrimitiveDV(fMemberTypes[i].fValidationDV); + if (allFalse) + allFalse = fMemberTypes[i].fOrdered == ORDERED_FALSE; + } + if (commonAnc) { + // REVISIT: all member types should have the same ordered value + // just use the first one. Can we assume this? + this.fOrdered = fMemberTypes[0].fOrdered; + } else if (allFalse) { + this.fOrdered = ORDERED_FALSE; + } else { + this.fOrdered = ORDERED_PARTIAL; + } + } + + }//setOrdered + + private void setNumeric(){ + if(fVariety == VARIETY_ATOMIC){ + this.fNumeric = fBase.fNumeric; + } + else if(fVariety == VARIETY_LIST){ + this.fNumeric = false; + } + else if(fVariety == VARIETY_UNION){ + XSSimpleType[] memberTypes = fMemberTypes; + for(int i = 0 ; i < memberTypes.length ; i++){ + if(!memberTypes[i].getNumeric() ){ + this.fNumeric = false; + return; + } + } + this.fNumeric = true; + } + + }//setNumeric + + private void setBounded(){ + if(fVariety == VARIETY_ATOMIC){ + if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0)) + && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0)) ){ + this.fBounded = true; + } + else{ + this.fBounded = false; + } + } + else if(fVariety == VARIETY_LIST){ + if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 ) + && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){ + this.fBounded = true; + } + else{ + this.fBounded = false; + } + + } + else if(fVariety == VARIETY_UNION){ + + XSSimpleTypeDecl [] memberTypes = this.fMemberTypes; + short ancestorId = 0 ; + + if(memberTypes.length > 0){ + ancestorId = getPrimitiveDV(memberTypes[0].fValidationDV); + } + + for(int i = 0 ; i < memberTypes.length ; i++){ + if(!memberTypes[i].getBounded() || (ancestorId != getPrimitiveDV(memberTypes[i].fValidationDV)) ){ + this.fBounded = false; + return; + } + } + this.fBounded = true; + } + + }//setBounded + + private boolean specialCardinalityCheck(){ + if( (fBase.fValidationDV == XSSimpleTypeDecl.DV_DATE) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEARMONTH) + || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GYEAR) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTHDAY) + || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GDAY) || (fBase.fValidationDV == XSSimpleTypeDecl.DV_GMONTH) ){ + return true; + } + return false; + + } //specialCardinalityCheck() + + private void setCardinality(){ + if(fVariety == VARIETY_ATOMIC){ + if(fBase.fFinite){ + this.fFinite = true; + } + else {// (!fBase.fFinite) + if ( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 ) + || ((this.fFacetsDefined & FACET_TOTALDIGITS) != 0 ) ){ + this.fFinite = true; + } + else if( (((this.fFacetsDefined & FACET_MININCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MINEXCLUSIVE) != 0 )) + && (((this.fFacetsDefined & FACET_MAXINCLUSIVE) != 0 ) || ((this.fFacetsDefined & FACET_MAXEXCLUSIVE) != 0 )) ){ + if( ((this.fFacetsDefined & FACET_FRACTIONDIGITS) != 0 ) || specialCardinalityCheck()){ + this.fFinite = true; + } + else{ + this.fFinite = false; + } + } + else{ + this.fFinite = false; + } + } + } + else if(fVariety == VARIETY_LIST){ + if( ((this.fFacetsDefined & FACET_LENGTH) != 0 ) || ( ((this.fFacetsDefined & FACET_MINLENGTH) != 0 ) + && ((this.fFacetsDefined & FACET_MAXLENGTH) != 0 )) ){ + this.fFinite = true; + } + else{ + this.fFinite = false; + } + + } + else if(fVariety == VARIETY_UNION){ + XSSimpleType [] memberTypes = fMemberTypes; + for(int i = 0 ; i < memberTypes.length ; i++){ + if(!(memberTypes[i].getFinite()) ){ + this.fFinite = false; + return; + } + } + this.fFinite = true; + } + + }//setCardinality + + private short getPrimitiveDV(short validationDV){ + + if (validationDV == DV_ID || validationDV == DV_IDREF || validationDV == DV_ENTITY){ + return DV_STRING; + } + else if (validationDV == DV_INTEGER) { + return DV_DECIMAL; + } + else if (Constants.SCHEMA_1_1_SUPPORT && (validationDV == DV_YEARMONTHDURATION || validationDV == DV_DAYTIMEDURATION)) { + return DV_DURATION; + } + else { + return validationDV; + } + + }//getPrimitiveDV() + + public boolean derivedFromType(XSTypeDefinition ancestor, short derivation) { + // REVISIT: implement according to derivation + + // ancestor is null, retur false + if (ancestor == null) + return false; + // ancestor is anyType, return true + // anyType is the only type whose base type is itself + if (ancestor.getBaseType() == ancestor) + return true; + // recursively get base, and compare it with ancestor + XSTypeDefinition type = this; + while (type != ancestor && // compare with ancestor + type != fAnySimpleType) { // reached anySimpleType + type = type.getBaseType(); + } + + return type == ancestor; + } + + public boolean derivedFrom(String ancestorNS, String ancestorName, short derivation) { + // REVISIT: implement according to derivation + + // ancestor is null, retur false + if (ancestorName == null) + return false; + // ancestor is anyType, return true + if (URI_SCHEMAFORSCHEMA.equals(ancestorNS) && + ANY_TYPE.equals(ancestorName)) { + return true; + } + + // recursively get base, and compare it with ancestor + XSTypeDefinition type = this; + while (!(ancestorName.equals(type.getName()) && + ((ancestorNS == null && type.getNamespace() == null) || + (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) && // compare with ancestor + type != fAnySimpleType) { // reached anySimpleType + type = (XSTypeDefinition)type.getBaseType(); + } + + return type != fAnySimpleType; + } + + /** + * Checks if a type is derived from another by restriction, given the name + * and namespace. See: + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom + * + * @param ancestorNS + * The namspace of the ancestor type declaration + * @param ancestorName + * The name of the ancestor type declaration + * @param derivationMethod + * The derivation method + * + * @return boolean True if the ancestor type is derived from the reference type by the specifiied derivation method. + */ + public boolean isDOMDerivedFrom(String ancestorNS, String ancestorName, int derivationMethod) { + + // ancestor is null, return false + if (ancestorName == null) + return false; + + // ancestor is anyType, return true + if (SchemaSymbols.URI_SCHEMAFORSCHEMA.equals(ancestorNS) + && SchemaSymbols.ATTVAL_ANYTYPE.equals(ancestorName) + && (((derivationMethod & DERIVATION_RESTRICTION) != 0) + || (derivationMethod == DERIVATION_ANY))) { + return true; + } + + // restriction + if ((derivationMethod & DERIVATION_RESTRICTION) != 0) { + if (isDerivedByRestriction(ancestorNS, ancestorName, this)) { + return true; + } + } + + // list + if ((derivationMethod & DERIVATION_LIST) != 0) { + if (isDerivedByList(ancestorNS, ancestorName, this)) { + return true; + } + } + + // union + if ((derivationMethod & DERIVATION_UNION) != 0) { + if (isDerivedByUnion(ancestorNS, ancestorName, this)) { + return true; + } + } + + // extension + if (((derivationMethod & DERIVATION_EXTENSION) != 0) + && (((derivationMethod & DERIVATION_RESTRICTION) == 0) + && ((derivationMethod & DERIVATION_LIST) == 0) + && ((derivationMethod & DERIVATION_UNION) == 0))) { + return false; + } + + // If the value of the parameter is 0 i.e. no bit (corresponding to + // restriction, list, extension or union) is set to 1 for the + // derivationMethod parameter. + if (((derivationMethod & DERIVATION_EXTENSION) == 0) + && (((derivationMethod & DERIVATION_RESTRICTION) == 0) + && ((derivationMethod & DERIVATION_LIST) == 0) + && ((derivationMethod & DERIVATION_UNION) == 0))) { + return isDerivedByAny(ancestorNS, ancestorName, this); + } + + return false; + } + + + /** + * Checks if a type is derived from another by any combination of restriction, list ir union. See: + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom + * + * @param ancestorNS + * The namspace of the ancestor type declaration + * @param ancestorName + * The name of the ancestor type declaration + * @param type + * The reference type definition + * + * @return boolean True if the type is derived by restriciton for the reference type + */ + private boolean isDerivedByAny(String ancestorNS, String ancestorName, + XSTypeDefinition type) { + + boolean derivedFrom = false; + XSTypeDefinition oldType = null; + // for each base, item or member type + while (type != null && type != oldType) { + + // If the ancestor type is reached or is the same as this type. + if ((ancestorName.equals(type.getName())) + && ((ancestorNS == null && type.getNamespace() == null) + || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) { + derivedFrom = true; + break; + } + + // check if derived by restriction or list or union + if (isDerivedByRestriction(ancestorNS, ancestorName, type)) { + return true; + } else if (isDerivedByList(ancestorNS, ancestorName, type)) { + return true; + } else if (isDerivedByUnion(ancestorNS, ancestorName, type)) { + return true; + } + oldType = type; + // get the base, item or member type depending on the variety + if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_ABSENT + || ((XSSimpleTypeDecl) type).getVariety() == VARIETY_ATOMIC) { + type = type.getBaseType(); + } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_UNION) { + for (int i = 0; i < ((XSSimpleTypeDecl) type).getMemberTypes().getLength(); i++) { + return isDerivedByAny(ancestorNS, ancestorName, + (XSTypeDefinition) ((XSSimpleTypeDecl) type) + .getMemberTypes().item(i)); + } + } else if (((XSSimpleTypeDecl) type).getVariety() == VARIETY_LIST) { + type = ((XSSimpleTypeDecl) type).getItemType(); + } + } + + return derivedFrom; + } + + /** + * DOM Level 3 + * Checks if a type is derived from another by restriction. See: + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom + * + * @param ancestorNS + * The namspace of the ancestor type declaration + * @param ancestorName + * The name of the ancestor type declaration + * @param type + * The reference type definition + * + * @return boolean True if the type is derived by restriciton for the + * reference type + */ + private boolean isDerivedByRestriction (String ancestorNS, String ancestorName, XSTypeDefinition type) { + XSTypeDefinition oldType = null; + while (type != null && type != oldType) { + if ((ancestorName.equals(type.getName())) + && ((ancestorNS != null && ancestorNS.equals(type.getNamespace())) + || (type.getNamespace() == null && ancestorNS == null))) { + + return true; + } + oldType = type; + type = type.getBaseType(); + } + + return false; + } + + /** + * Checks if a type is derived from another by list. See: + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom + * + * @param ancestorNS + * The namspace of the ancestor type declaration + * @param ancestorName + * The name of the ancestor type declaration + * @param type + * The reference type definition + * + * @return boolean True if the type is derived by list for the reference type + */ + private boolean isDerivedByList (String ancestorNS, String ancestorName, XSTypeDefinition type) { + // If the variety is union + if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_LIST) { + + // get the {item type} + XSTypeDefinition itemType = ((XSSimpleTypeDefinition)type).getItemType(); + + // T2 is the {item type definition} + if (itemType != null) { + + // T2 is derived from the other type definition by DERIVATION_RESTRICTION + if (isDerivedByRestriction(ancestorNS, ancestorName, itemType)) { + return true; + } + } + } + return false; + } + + /** + * Checks if a type is derived from another by union. See: + * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom + * + * @param ancestorNS + * The namspace of the ancestor type declaration + * @param ancestorName + * The name of the ancestor type declaration + * @param type + * The reference type definition + * + * @return boolean True if the type is derived by union for the reference type + */ + private boolean isDerivedByUnion (String ancestorNS, String ancestorName, XSTypeDefinition type) { + + // If the variety is union + if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_UNION) { + + // get member types + XSObjectList memberTypes = ((XSSimpleTypeDefinition)type).getMemberTypes(); + + for (int i = 0; i < memberTypes.getLength(); i++) { + // One of the {member type definitions} is T2. + if (memberTypes.item(i) != null) { + // T2 is derived from the other type definition by DERIVATION_RESTRICTION + if (isDerivedByRestriction(ancestorNS, ancestorName,(XSSimpleTypeDefinition)memberTypes.item(i))) { + return true; + } + } + } + } + return false; + } + + + static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE, false, true, false, true, XSConstants.ANYSIMPLETYPE_DT); + + static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE, ORDERED_FALSE, false, true, false, true, XSSimpleTypeDecl.ANYATOMICTYPE_DT); + + /** + * Validation context used to validate facet values. + */ + static final ValidationContext fDummyContext = new ValidationContext() { + public boolean needFacetChecking() { + return true; + } + + public boolean needExtraChecking() { + return false; + } + public boolean needToNormalize() { + return false; + } + public boolean useNamespaces() { + return true; + } + + public boolean isEntityDeclared(String name) { + return false; + } + + public boolean isEntityUnparsed(String name) { + return false; + } + + public boolean isIdDeclared(String name) { + return false; + } + + public void addId(String name) { + } + + public void addIdRef(String name) { + } + + public String getSymbol (String symbol) { + return symbol.intern(); + } + + public String getURI(String prefix) { + return null; + } - /** - * DOM Level 3 - * Checks if a type is derived from another by restriction. See: - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * - * @param ancestorNS - * The namspace of the ancestor type declaration - * @param ancestorName - * The name of the ancestor type declaration - * @param type - * The reference type definition - * - * @return boolean True if the type is derived by restriciton for the - * reference type - */ - private boolean isDerivedByRestriction (String ancestorNS, String ancestorName, XSTypeDefinition type) { - XSTypeDefinition oldType = null; - while (type != null && type != oldType) { - if ((ancestorName.equals(type.getName())) - && ((ancestorNS != null && ancestorNS.equals(type.getNamespace())) - || (type.getNamespace() == null && ancestorNS == null))) { - - return true; - } - oldType = type; - type = type.getBaseType(); - } - - return false; - } - - /** - * Checks if a type is derived from another by list. See: - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * - * @param ancestorNS - * The namspace of the ancestor type declaration - * @param ancestorName - * The name of the ancestor type declaration - * @param type - * The reference type definition - * - * @return boolean True if the type is derived by list for the reference type - */ - private boolean isDerivedByList (String ancestorNS, String ancestorName, XSTypeDefinition type) { - // If the variety is union - if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_LIST) { - - // get the {item type} - XSTypeDefinition itemType = ((XSSimpleTypeDefinition)type).getItemType(); - - // T2 is the {item type definition} - if (itemType != null) { - - // T2 is derived from the other type definition by DERIVATION_RESTRICTION - if (isDerivedByRestriction(ancestorNS, ancestorName, itemType)) { - return true; - } - } - } - return false; - } - - /** - * Checks if a type is derived from another by union. See: - * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * - * @param ancestorNS - * The namspace of the ancestor type declaration - * @param ancestorName - * The name of the ancestor type declaration - * @param type - * The reference type definition - * - * @return boolean True if the type is derived by union for the reference type - */ - private boolean isDerivedByUnion (String ancestorNS, String ancestorName, XSTypeDefinition type) { - - // If the variety is union - if (type !=null && ((XSSimpleTypeDefinition)type).getVariety() == VARIETY_UNION) { - - // get member types - XSObjectList memberTypes = ((XSSimpleTypeDefinition)type).getMemberTypes(); - - for (int i = 0; i < memberTypes.getLength(); i++) { - // One of the {member type definitions} is T2. - if (memberTypes.item(i) != null) { - // T2 is derived from the other type definition by DERIVATION_RESTRICTION - if (isDerivedByRestriction(ancestorNS, ancestorName,(XSSimpleTypeDefinition)memberTypes.item(i))) { - return true; - } - } - } + public Locale getLocale() { + return Locale.getDefault(); } - return false; - } - - - static final XSSimpleTypeDecl fAnySimpleType = new XSSimpleTypeDecl(null, "anySimpleType", DV_ANYSIMPLETYPE, ORDERED_FALSE, false, true, false, true, XSConstants.ANYSIMPLETYPE_DT); - - static final XSSimpleTypeDecl fAnyAtomicType = new XSSimpleTypeDecl(fAnySimpleType, "anyAtomicType", DV_ANYATOMICTYPE, ORDERED_FALSE, false, true, false, true, XSSimpleTypeDecl.ANYATOMICTYPE_DT); - - /** - * Validation context used to validate facet values. - */ - static final ValidationContext fDummyContext = new ValidationContext() { - public boolean needFacetChecking() { - return true; - } - - public boolean needExtraChecking() { - return false; - } - public boolean needToNormalize() { - return false; - } - public boolean useNamespaces() { - return true; - } - - public boolean isEntityDeclared(String name) { - return false; - } - - public boolean isEntityUnparsed(String name) { - return false; - } - - public boolean isIdDeclared(String name) { - return false; - } - - public void addId(String name) { - } - - public void addIdRef(String name) { - } - - public String getSymbol (String symbol) { - return symbol.intern(); - } - - public String getURI(String prefix) { - return null; - } - }; - + }; + private boolean fAnonymous = false; - - /** - * A wrapper of ValidationContext, to provide a way of switching to a - * different Namespace declaration context. - */ - class ValidationContextImpl implements ValidationContext { - ValidationContext fExternal; - ValidationContextImpl(ValidationContext external) { - fExternal = external; - } - - NamespaceContext fNSContext; - void setNSContext(NamespaceContext nsContext) { - fNSContext = nsContext; - } - - public boolean needFacetChecking() { - return fExternal.needFacetChecking(); - } - - public boolean needExtraChecking() { - return fExternal.needExtraChecking(); - } - public boolean needToNormalize() { - return fExternal.needToNormalize(); - } - // schema validation is predicated upon namespaces - public boolean useNamespaces() { - return true; - } - - public boolean isEntityDeclared (String name) { - return fExternal.isEntityDeclared(name); - } - - public boolean isEntityUnparsed (String name) { - return fExternal.isEntityUnparsed(name); - } - - public boolean isIdDeclared (String name) { - return fExternal.isIdDeclared(name); - } - - public void addId(String name) { - fExternal.addId(name); - } - - public void addIdRef(String name) { - fExternal.addIdRef(name); - } - - public String getSymbol (String symbol) { - return fExternal.getSymbol(symbol); - } - - public String getURI(String prefix) { - if (fNSContext == null) - return fExternal.getURI(prefix); - else - return fNSContext.getURI(prefix); - } - } - - public void reset(){ + + /** + * A wrapper of ValidationContext, to provide a way of switching to a + * different Namespace declaration context. + */ + class ValidationContextImpl implements ValidationContext { + ValidationContext fExternal; + ValidationContextImpl(ValidationContext external) { + fExternal = external; + } + + NamespaceContext fNSContext; + void setNSContext(NamespaceContext nsContext) { + fNSContext = nsContext; + } + + public boolean needFacetChecking() { + return fExternal.needFacetChecking(); + } + + public boolean needExtraChecking() { + return fExternal.needExtraChecking(); + } + public boolean needToNormalize() { + return fExternal.needToNormalize(); + } + // schema validation is predicated upon namespaces + public boolean useNamespaces() { + return true; + } + + public boolean isEntityDeclared (String name) { + return fExternal.isEntityDeclared(name); + } + + public boolean isEntityUnparsed (String name) { + return fExternal.isEntityUnparsed(name); + } + + public boolean isIdDeclared (String name) { + return fExternal.isIdDeclared(name); + } + + public void addId(String name) { + fExternal.addId(name); + } + + public void addIdRef(String name) { + fExternal.addIdRef(name); + } + + public String getSymbol (String symbol) { + return fExternal.getSymbol(symbol); + } + + public String getURI(String prefix) { + if (fNSContext == null) + return fExternal.getURI(prefix); + else + return fNSContext.getURI(prefix); + } - // if it's immutable, can't be reset: - if (fIsImmutable) return; - fItemType = null; - fMemberTypes = null; - - fTypeName = null; - fTargetNamespace = null; - fFinalSet = 0; - fBase = null; - fVariety = -1; - fValidationDV = -1; - - fFacetsDefined = 0; - fFixedFacet = 0; - - //for constraining facets - fWhiteSpace = 0; - fLength = -1; - fMinLength = -1; - fMaxLength = -1; - fTotalDigits = -1; - fFractionDigits = -1; - fPattern = null; - fPatternStr = null; - fEnumeration = null; - fEnumerationType = null; + public Locale getLocale() { + return fExternal.getLocale(); + } + } + + public void reset(){ + + // if it's immutable, can't be reset: + if (fIsImmutable) return; + fItemType = null; + fMemberTypes = null; + + fTypeName = null; + fTargetNamespace = null; + fFinalSet = 0; + fBase = null; + fVariety = -1; + fValidationDV = -1; + + fFacetsDefined = 0; + fFixedFacet = 0; + + //for constraining facets + fWhiteSpace = 0; + fLength = -1; + fMinLength = -1; + fMaxLength = -1; + fTotalDigits = -1; + fFractionDigits = -1; + fPattern = null; + fPatternStr = null; + fEnumeration = null; + fEnumerationType = null; fEnumerationItemType = null; - fLexicalPattern = null; - fLexicalEnumeration = null; - fMaxInclusive = null; - fMaxExclusive = null; - fMinExclusive = null; - fMinInclusive = null; - lengthAnnotation = null; - minLengthAnnotation = null; - maxLengthAnnotation = null; - whiteSpaceAnnotation = null; - totalDigitsAnnotation = null; - fractionDigitsAnnotation = null; - patternAnnotations = null; - enumerationAnnotations = null; - maxInclusiveAnnotation = null; - maxExclusiveAnnotation = null; - minInclusiveAnnotation = null; - minExclusiveAnnotation = null; - - fPatternType = SPECIAL_PATTERN_NONE; - fAnnotations = null; - fFacets = null; - - // REVISIT: reset for fundamental facets - } - /** - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() - */ - public XSNamespaceItem getNamespaceItem() { - // REVISIT: implement - return null; - } - - /** - * @see java.lang.Object#toString() - */ - public String toString() { - return this.fTargetNamespace+"," +this.fTypeName; - } - - /** - * A list of constraining facets if it exists, otherwise an empty - * <code>XSObjectList</code>. Note: This method must not be used to - * retrieve values for <code>enumeration</code> and <code>pattern</code> - * facets. - */ - public XSObjectList getFacets() { - if (fFacets == null && - (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) { - - XSFacetImpl[] facets = new XSFacetImpl[10]; - int count = 0; - if ((fFacetsDefined & FACET_WHITESPACE) != 0) { - facets[count] = - new XSFacetImpl( - FACET_WHITESPACE, - WS_FACET_STRING[fWhiteSpace], - (fFixedFacet & FACET_WHITESPACE) != 0, - whiteSpaceAnnotation); - count++; - } - if (fLength != -1) { - facets[count] = - new XSFacetImpl( - FACET_LENGTH, - Integer.toString(fLength), - (fFixedFacet & FACET_LENGTH) != 0, - lengthAnnotation); - count++; - } - if (fMinLength != -1) { - facets[count] = - new XSFacetImpl( - FACET_MINLENGTH, - Integer.toString(fMinLength), - (fFixedFacet & FACET_MINLENGTH) != 0, - minLengthAnnotation); - count++; - } - if (fMaxLength != -1) { - facets[count] = - new XSFacetImpl( - FACET_MAXLENGTH, - Integer.toString(fMaxLength), - (fFixedFacet & FACET_MAXLENGTH) != 0, - maxLengthAnnotation); - count++; - } - if (fTotalDigits != -1) { - facets[count] = - new XSFacetImpl( - FACET_TOTALDIGITS, - Integer.toString(fTotalDigits), - (fFixedFacet & FACET_TOTALDIGITS) != 0, - totalDigitsAnnotation); - count++; - } - if (fValidationDV == DV_INTEGER) { - facets[count] = - new XSFacetImpl( - FACET_FRACTIONDIGITS, - "0", - true, - null); - count++; - } - if (fFractionDigits != -1) { - facets[count] = - new XSFacetImpl( - FACET_FRACTIONDIGITS, - Integer.toString(fFractionDigits), - (fFixedFacet & FACET_FRACTIONDIGITS) != 0, - fractionDigitsAnnotation); - count++; - } - if (fMaxInclusive != null) { - facets[count] = - new XSFacetImpl( - FACET_MAXINCLUSIVE, - fMaxInclusive.toString(), - (fFixedFacet & FACET_MAXINCLUSIVE) != 0, - maxInclusiveAnnotation); - count++; - } - if (fMaxExclusive != null) { - facets[count] = - new XSFacetImpl( - FACET_MAXEXCLUSIVE, - fMaxExclusive.toString(), - (fFixedFacet & FACET_MAXEXCLUSIVE) != 0, - maxExclusiveAnnotation); - count++; - } - if (fMinExclusive != null) { - facets[count] = - new XSFacetImpl( - FACET_MINEXCLUSIVE, - fMinExclusive.toString(), - (fFixedFacet & FACET_MINEXCLUSIVE) != 0, - minExclusiveAnnotation); - count++; - } - if (fMinInclusive != null) { - facets[count] = - new XSFacetImpl( - FACET_MININCLUSIVE, - fMinInclusive.toString(), - (fFixedFacet & FACET_MININCLUSIVE) != 0, - minInclusiveAnnotation); - count++; - } - fFacets = new XSObjectListImpl(facets, count); - } - return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST; - } - - /** - * A list of enumeration and pattern constraining facets if it exists, - * otherwise an empty <code>XSObjectList</code>. - */ - public XSObjectList getMultiValueFacets() { - if (fMultiValueFacets == null && - ((fFacetsDefined & FACET_ENUMERATION) != 0 || - (fFacetsDefined & FACET_PATTERN) != 0 || - fPatternType != SPECIAL_PATTERN_NONE || - fValidationDV == DV_INTEGER)) { - - XSMVFacetImpl[] facets = new XSMVFacetImpl[2]; - int count = 0; - if ((fFacetsDefined & FACET_PATTERN) != 0 || - fPatternType != SPECIAL_PATTERN_NONE || - fValidationDV == DV_INTEGER) { - facets[count] = - new XSMVFacetImpl( - FACET_PATTERN, - this.getLexicalPattern(), - patternAnnotations); - count++; - } - if (fEnumeration != null) { - facets[count] = - new XSMVFacetImpl( - FACET_ENUMERATION, - this.getLexicalEnumeration(), - enumerationAnnotations); - count++; - } - fMultiValueFacets = new XSObjectListImpl(facets, count); - } - return (fMultiValueFacets != null) ? - fMultiValueFacets : XSObjectListImpl.EMPTY_LIST; - } - + fLexicalPattern = null; + fLexicalEnumeration = null; + fMaxInclusive = null; + fMaxExclusive = null; + fMinExclusive = null; + fMinInclusive = null; + lengthAnnotation = null; + minLengthAnnotation = null; + maxLengthAnnotation = null; + whiteSpaceAnnotation = null; + totalDigitsAnnotation = null; + fractionDigitsAnnotation = null; + patternAnnotations = null; + enumerationAnnotations = null; + maxInclusiveAnnotation = null; + maxExclusiveAnnotation = null; + minInclusiveAnnotation = null; + minExclusiveAnnotation = null; + + fPatternType = SPECIAL_PATTERN_NONE; + fAnnotations = null; + fFacets = null; + + // REVISIT: reset for fundamental facets + } + /** + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() + */ + public XSNamespaceItem getNamespaceItem() { + // REVISIT: implement + return null; + } + + /** + * @see java.lang.Object#toString() + */ + public String toString() { + return this.fTargetNamespace+"," +this.fTypeName; + } + + /** + * A list of constraining facets if it exists, otherwise an empty + * <code>XSObjectList</code>. Note: This method must not be used to + * retrieve values for <code>enumeration</code> and <code>pattern</code> + * facets. + */ + public XSObjectList getFacets() { + if (fFacets == null && + (fFacetsDefined != 0 || fValidationDV == DV_INTEGER)) { + + XSFacetImpl[] facets = new XSFacetImpl[10]; + int count = 0; + if ((fFacetsDefined & FACET_WHITESPACE) != 0) { + facets[count] = + new XSFacetImpl( + FACET_WHITESPACE, + WS_FACET_STRING[fWhiteSpace], + (fFixedFacet & FACET_WHITESPACE) != 0, + whiteSpaceAnnotation); + count++; + } + if (fLength != -1) { + facets[count] = + new XSFacetImpl( + FACET_LENGTH, + Integer.toString(fLength), + (fFixedFacet & FACET_LENGTH) != 0, + lengthAnnotation); + count++; + } + if (fMinLength != -1) { + facets[count] = + new XSFacetImpl( + FACET_MINLENGTH, + Integer.toString(fMinLength), + (fFixedFacet & FACET_MINLENGTH) != 0, + minLengthAnnotation); + count++; + } + if (fMaxLength != -1) { + facets[count] = + new XSFacetImpl( + FACET_MAXLENGTH, + Integer.toString(fMaxLength), + (fFixedFacet & FACET_MAXLENGTH) != 0, + maxLengthAnnotation); + count++; + } + if (fTotalDigits != -1) { + facets[count] = + new XSFacetImpl( + FACET_TOTALDIGITS, + Integer.toString(fTotalDigits), + (fFixedFacet & FACET_TOTALDIGITS) != 0, + totalDigitsAnnotation); + count++; + } + if (fValidationDV == DV_INTEGER) { + facets[count] = + new XSFacetImpl( + FACET_FRACTIONDIGITS, + "0", + true, + null); + count++; + } + if (fFractionDigits != -1) { + facets[count] = + new XSFacetImpl( + FACET_FRACTIONDIGITS, + Integer.toString(fFractionDigits), + (fFixedFacet & FACET_FRACTIONDIGITS) != 0, + fractionDigitsAnnotation); + count++; + } + if (fMaxInclusive != null) { + facets[count] = + new XSFacetImpl( + FACET_MAXINCLUSIVE, + fMaxInclusive.toString(), + (fFixedFacet & FACET_MAXINCLUSIVE) != 0, + maxInclusiveAnnotation); + count++; + } + if (fMaxExclusive != null) { + facets[count] = + new XSFacetImpl( + FACET_MAXEXCLUSIVE, + fMaxExclusive.toString(), + (fFixedFacet & FACET_MAXEXCLUSIVE) != 0, + maxExclusiveAnnotation); + count++; + } + if (fMinExclusive != null) { + facets[count] = + new XSFacetImpl( + FACET_MINEXCLUSIVE, + fMinExclusive.toString(), + (fFixedFacet & FACET_MINEXCLUSIVE) != 0, + minExclusiveAnnotation); + count++; + } + if (fMinInclusive != null) { + facets[count] = + new XSFacetImpl( + FACET_MININCLUSIVE, + fMinInclusive.toString(), + (fFixedFacet & FACET_MININCLUSIVE) != 0, + minInclusiveAnnotation); + count++; + } + fFacets = new XSObjectListImpl(facets, count); + } + return (fFacets != null) ? fFacets : XSObjectListImpl.EMPTY_LIST; + } + + /** + * A list of enumeration and pattern constraining facets if it exists, + * otherwise an empty <code>XSObjectList</code>. + */ + public XSObjectList getMultiValueFacets() { + if (fMultiValueFacets == null && + ((fFacetsDefined & FACET_ENUMERATION) != 0 || + (fFacetsDefined & FACET_PATTERN) != 0 || + fPatternType != SPECIAL_PATTERN_NONE || + fValidationDV == DV_INTEGER)) { + + XSMVFacetImpl[] facets = new XSMVFacetImpl[2]; + int count = 0; + if ((fFacetsDefined & FACET_PATTERN) != 0 || + fPatternType != SPECIAL_PATTERN_NONE || + fValidationDV == DV_INTEGER) { + facets[count] = + new XSMVFacetImpl( + FACET_PATTERN, + this.getLexicalPattern(), + patternAnnotations); + count++; + } + if (fEnumeration != null) { + facets[count] = + new XSMVFacetImpl( + FACET_ENUMERATION, + this.getLexicalEnumeration(), + enumerationAnnotations); + count++; + } + fMultiValueFacets = new XSObjectListImpl(facets, count); + } + return (fMultiValueFacets != null) ? + fMultiValueFacets : XSObjectListImpl.EMPTY_LIST; + } + public Object getMinInclusiveValue() { return fMinInclusive; } - + public Object getMinExclusiveValue() { return fMinExclusive; } - + public Object getMaxInclusiveValue() { return fMaxInclusive; } - + public Object getMaxExclusiveValue() { return fMaxExclusive; } - + public void setAnonymous(boolean anon) { fAnonymous = anon; } - - private static final class XSFacetImpl implements XSFacet { - final short kind; - final String value; - final boolean fixed; - final XSAnnotation annotation; - - public XSFacetImpl(short kind, String value, boolean fixed, XSAnnotation annotation) { - this.kind = kind; - this.value = value; - this.fixed = fixed; - this.annotation = annotation; - } - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getAnnotation() - */ - public XSAnnotation getAnnotation() { - return annotation; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind() - */ - public short getFacetKind() { - return kind; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getLexicalFacetValue() - */ - public String getLexicalFacetValue() { - return value; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSFacet#isFixed() - */ - public boolean getFixed() { - return fixed; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName() - */ - public String getName() { - return null; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace() - */ - public String getNamespace() { - return null; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() - */ - public XSNamespaceItem getNamespaceItem() { - // REVISIT: implement - return null; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType() - */ - public short getType() { - return XSConstants.FACET; - } - - } - - private static final class XSMVFacetImpl implements XSMultiValueFacet { - final short kind; - XSObjectList annotations; - StringList values; - - public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) { - this.kind = kind; - this.values = values; - this.annotations = annotations; - } - - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind() - */ - public short getFacetKind() { - return kind; - } - - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getAnnotations() - */ - public XSObjectList getAnnotations() { - return annotations; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getLexicalFacetValues() - */ - public StringList getLexicalFacetValues() { - return values; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName() - */ - public String getName() { - return null; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace() - */ - public String getNamespace() { - return null; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() - */ - public XSNamespaceItem getNamespaceItem() { - // REVISIT: implement - return null; - } - - /* (non-Javadoc) - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType() - */ - public short getType() { - return XSConstants.MULTIVALUE_FACET; - } - } + + private static final class XSFacetImpl implements XSFacet { + final short kind; + final String value; + final boolean fixed; + final XSAnnotation annotation; + + public XSFacetImpl(short kind, String value, boolean fixed, XSAnnotation annotation) { + this.kind = kind; + this.value = value; + this.fixed = fixed; + this.annotation = annotation; + } + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getAnnotation() + */ + public XSAnnotation getAnnotation() { + return annotation; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind() + */ + public short getFacetKind() { + return kind; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getLexicalFacetValue() + */ + public String getLexicalFacetValue() { + return value; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSFacet#isFixed() + */ + public boolean getFixed() { + return fixed; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName() + */ + public String getName() { + return null; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace() + */ + public String getNamespace() { + return null; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() + */ + public XSNamespaceItem getNamespaceItem() { + // REVISIT: implement + return null; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType() + */ + public short getType() { + return XSConstants.FACET; + } + + } + + private static final class XSMVFacetImpl implements XSMultiValueFacet { + final short kind; + XSObjectList annotations; + StringList values; + + public XSMVFacetImpl(short kind, StringList values, XSObjectList annotations) { + this.kind = kind; + this.values = values; + this.annotations = annotations; + } + + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSFacet#getFacetKind() + */ + public short getFacetKind() { + return kind; + } + + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getAnnotations() + */ + public XSObjectList getAnnotations() { + return annotations; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSMultiValueFacet#getLexicalFacetValues() + */ + public StringList getLexicalFacetValues() { + return values; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getName() + */ + public String getName() { + return null; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespace() + */ + public String getNamespace() { + return null; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() + */ + public XSNamespaceItem getNamespaceItem() { + // REVISIT: implement + return null; + } + + /* (non-Javadoc) + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getType() + */ + public short getType() { + return XSConstants.MULTIVALUE_FACET; + } + } public String getTypeNamespace() { return getNamespace(); @@ -3239,7 +3252,7 @@ public boolean isDerivedFrom(String typeNamespaceArg, String typeNameArg, int derivationMethod) { return isDOMDerivedFrom(typeNamespaceArg, typeNameArg, derivationMethod); } - + private short convertToPrimitiveKind(short valueType) { /** Primitive datatypes. */ if (valueType <= XSConstants.NOTATION_DT) { @@ -3256,5 +3269,6 @@ /** Other types. */ return valueType; } + +} // class XSSimpleTypeDecl -} // class XSSimpleTypeDecl
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/validation/ValidationState.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/validation/ValidationState.java Wed Sep 28 17:10:18 2011 +0100 @@ -26,14 +26,16 @@ import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import java.util.Hashtable; import java.util.Enumeration; +import java.util.Locale; /** * Implementation of ValidationContext inteface. Used to establish an * environment for simple type validation. - * + * * @xerces.internal * * @author Elena Litani, IBM + * @version $Id: ValidationState.java,v 1.6 2010/07/23 02:09:27 joehw Exp $ */ public class ValidationState implements ValidationContext { @@ -48,6 +50,7 @@ private EntityState fEntityState = null; private NamespaceContext fNamespaceContext = null; private SymbolTable fSymbolTable = null; + private Locale fLocale = null; //REVISIT: Should replace with a lighter structure. private final Hashtable fIdTable = new Hashtable(); @@ -191,4 +194,13 @@ return null; } + // Locale + + public void setLocale(Locale locale) { + fLocale = locale; + } + + public Locale getLocale() { + return fLocale; + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/CaseInsensitiveMap.java Wed Sep 28 17:10:18 2011 +0100 @@ -0,0 +1,177 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.impl.xpath.regex; + +/** + * @version $Id: CaseInsensitiveMap.java,v 1.1 2010/07/27 06:29:27 joehw Exp $ + */ + +public class CaseInsensitiveMap { + + private static int CHUNK_SHIFT = 10; /* 2^10 = 1k */ + private static int CHUNK_SIZE = (1<<CHUNK_SHIFT); + private static int CHUNK_MASK = (CHUNK_SIZE-1); + private static int INITIAL_CHUNK_COUNT = 64; /* up to 0xFFFF */ + + private static int[][][] caseInsensitiveMap; + private static Boolean mapBuilt = Boolean.FALSE; + + private static int LOWER_CASE_MATCH = 1; + private static int UPPER_CASE_MATCH = 2; + + /** + * Return a list of code point characters (not including the input value) + * that can be substituted in a case insensitive match + */ + static public int[] get(int codePoint) { + if (mapBuilt == Boolean.FALSE) { + synchronized (mapBuilt) { + if (mapBuilt == Boolean.FALSE) { + buildCaseInsensitiveMap(); + } + } // synchronized + } // if mapBuilt + + return (codePoint < 0x10000) ? getMapping(codePoint) : null; + } + + private static int[] getMapping(int codePoint) { + int chunk = codePoint >>> CHUNK_SHIFT; + int offset = codePoint & CHUNK_MASK; + + return caseInsensitiveMap[chunk][offset]; + } + + private static void buildCaseInsensitiveMap() { + caseInsensitiveMap = new int[INITIAL_CHUNK_COUNT][][]; + for (int i=0; i<INITIAL_CHUNK_COUNT; i++) { + caseInsensitiveMap[i] = new int[CHUNK_SIZE][]; + } + + int lc, uc; + for (int i=0; i<0x10000; i++) { + lc = Character.toLowerCase(i); + uc = Character.toUpperCase(i); + + // lower/upper case value is not the same as code point + if (lc != uc || lc != i) { + int[] map = new int[2]; + int index = 0; + + if (lc != i) { + map[index++] = lc; + map[index++] = LOWER_CASE_MATCH; + int[] lcMap = getMapping(lc); + if (lcMap != null) { + map = updateMap(i, map, lc, lcMap, LOWER_CASE_MATCH); + } + } + + if (uc != i) { + if (index == map.length) { + map = expandMap(map, 2); + } + map[index++] = uc; + map[index++] = UPPER_CASE_MATCH; + int[] ucMap = getMapping(uc); + if (ucMap != null) { + map = updateMap(i, map, uc, ucMap, UPPER_CASE_MATCH); + } + } + + set(i, map); + } + } + + mapBuilt = Boolean.TRUE; + } + + private static int[] expandMap(int[] srcMap, int expandBy) { + final int oldLen = srcMap.length; + int[] newMap = new int[oldLen + expandBy]; + + System.arraycopy(srcMap, 0, newMap, 0, oldLen); + return newMap; + } + + private static void set(int codePoint, int[] map) { + int chunk = codePoint >>> CHUNK_SHIFT; + int offset = codePoint & CHUNK_MASK; + + caseInsensitiveMap[chunk][offset] = map; + } + + private static int[] updateMap(int codePoint, int[] codePointMap, + int ciCodePoint, int[] ciCodePointMap, int matchType) { + for (int i=0; i<ciCodePointMap.length; i+=2) { + int c = ciCodePointMap[i]; + int[] cMap = getMapping(c); + if (cMap != null) { + if (contains(cMap, ciCodePoint, matchType)) { + if (!contains(cMap, codePoint)) { + cMap = expandAndAdd(cMap, codePoint, matchType); + set(c, cMap); + } + if (!contains(codePointMap, c)) { + codePointMap = expandAndAdd(codePointMap, c,matchType); + } + } + } + } + + if (!contains(ciCodePointMap, codePoint)) { + ciCodePointMap = expandAndAdd(ciCodePointMap, codePoint, matchType); + set(ciCodePoint, ciCodePointMap); + } + + return codePointMap; + } + + private static boolean contains(int[] map, int codePoint) { + for (int i=0; i<map.length; i += 2) { + if (map[i] == codePoint) { + return true; + } + } + return false; + } + + private static boolean contains(int[] map, int codePoint, int matchType) { + for (int i=0; i<map.length; i += 2) { + if (map[i] == codePoint && map[i+1] == matchType) { + return true; + } + } + return false; + } + + private static int[] expandAndAdd(int[] srcMap, int codePoint, int matchType) { + final int oldLen = srcMap.length; + int[] newMap = new int[oldLen + 2]; + + System.arraycopy(srcMap, 0, newMap, 0, oldLen); + newMap[oldLen] = codePoint; + newMap[oldLen+1] = matchType; + return newMap; + } +} +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/ParserForXMLSchema.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/ParserForXMLSchema.java Wed Sep 28 17:10:18 2011 +0100 @@ -25,10 +25,11 @@ /** * A regular expression parser for the XML Schema. - * + * * @xerces.internal * * @author TAMURA Kent <kent@trl.ibm.co.jp> + * @version $Id: ParserForXMLSchema.java,v 1.7 2010/07/27 05:02:34 joehw Exp $ */ class ParserForXMLSchema extends RegexParser { @@ -36,7 +37,7 @@ //this.setLocale(Locale.getDefault()); } public ParserForXMLSchema(Locale locale) { - //this.setLocale(locale); + super(locale); } Token processCaret() throws ParseException { @@ -161,8 +162,8 @@ * c-c-subtraction ::= (positive-c-group | negative-c-group) subtraction * subtraction ::= '-' c-c-expression * c-range ::= single-range | from-to-range - * single-range ::= multi-c-escape | category-c-escape | block-c-escape | <any XML char> - * cc-normal-c ::= <any character except [, ], \> + * single-range ::= multi-c-escape | category-c-escape | block-c-escape | <any XML char> + * cc-normal-c ::= <any character except [, ], \> * from-to-range ::= cc-normal-c '-' cc-normal-c * * @param useNrage Ignored. @@ -172,7 +173,7 @@ this.setContext(S_INBRACKETS); this.next(); // '[' boolean nrange = false; - boolean wasDecoded = false; // used to detect if the last - was escaped. + boolean wasDecoded = false; // used to detect if the last - was escaped. RangeToken base = null; RangeToken tok; if (this.read() == T_CHAR && this.chardata == '^') { @@ -188,7 +189,7 @@ boolean firstloop = true; while ((type = this.read()) != T_EOF) { // Don't use 'cotinue' for this loop. - wasDecoded = false; + wasDecoded = false; // single-range | from-to-range | subtraction if (type == T_CHAR && this.chardata == ']' && !firstloop) { if (nrange) { @@ -224,9 +225,9 @@ break; case '-': - c = this.decodeEscaped(); - wasDecoded = true; - break; + c = this.decodeEscaped(); + wasDecoded = true; + break; default: c = this.decodeEscaped(); @@ -249,21 +250,28 @@ if (type == T_CHAR) { if (c == '[') throw this.ex("parser.cc.6", this.offset-2); if (c == ']') throw this.ex("parser.cc.7", this.offset-2); - if (c == '-' && this.chardata == ']' && firstloop) throw this.ex("parser.cc.8", this.offset-2); // if regex = '[-]' then invalid + if (c == '-' && this.chardata != ']' && !firstloop) throw this.ex("parser.cc.8", this.offset-2); // if regex = '[-]' then invalid } - if(c == '-' && this.chardata == '-' && this.read() != T_BACKSOLIDUS && !wasDecoded) { - throw this.ex("parser.cc.8", this.offset-2); - } - if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'. - tok.addRange(c, c); + if (this.read() != T_CHAR || this.chardata != '-' || c == '-' && firstloop) { // Here is no '-'. + if (!this.isSet(RegularExpression.IGNORE_CASE) || c > 0xffff) { + tok.addRange(c, c); + } + else { + addCaseInsensitiveChar(tok, c); + } } else { // Found '-' // Is this '-' is a from-to token?? this.next(); // Skips '-' if ((type = this.read()) == T_EOF) throw this.ex("parser.cc.2", this.offset); // c '-' ']' -> '-' is a single-range. - if(type == T_CHAR && this.chardata == ']') { // if - is at the last position of the group - tok.addRange(c, c); - tok.addRange('-', '-'); + if(type == T_CHAR && this.chardata == ']') { // if - is at the last position of the group + if (!this.isSet(RegularExpression.IGNORE_CASE) || c > 0xffff) { + tok.addRange(c, c); + } + else { + addCaseInsensitiveChar(tok, c); + } + tok.addRange('-', '-'); } else if (type == T_XMLSCHEMA_CC_SUBTRACTION) { throw this.ex("parser.cc.8", this.offset-1); @@ -280,7 +288,13 @@ this.next(); if (c > rangeend) throw this.ex("parser.ope.3", this.offset-1); - tok.addRange(c, rangeend); + if (!this.isSet(RegularExpression.IGNORE_CASE) || + (c > 0xffff && rangeend > 0xffff)) { + tok.addRange(c, rangeend); + } + else { + addCaseInsensitiveCharRange(tok, c, rangeend); + } } } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegexParser.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegexParser.java Wed Sep 28 17:10:18 2011 +0100 @@ -27,9 +27,10 @@ /** * A Regular Expression Parser. - * + * * @xerces.internal * + * @version $Id: RegexParser.java,v 1.7 2010/07/27 07:00:02 joehw Exp $ */ class RegexParser { static final int T_CHAR = 0; @@ -78,6 +79,7 @@ static protected final int S_INBRACKETS = 1; static protected final int S_INXBRACKETS = 2; int context = S_NORMAL; + int parenOpened = 1; int parennumber = 1; boolean hasBackReferences; Vector references = null; @@ -91,10 +93,16 @@ public void setLocale(Locale locale) { try { - this.resources = ResourceBundle.getBundle("com.sun.org.apache.xerces.internal.impl.xpath.regex.message", locale); - } catch (MissingResourceException mre) { + if (locale != null) { + this.resources = ResourceBundle.getBundle("com.sun.org.apache.xerces.internal.impl.xpath.regex.message", locale); + } + else { + this.resources = ResourceBundle.getBundle("com.sun.org.apache.xerces.internal.impl.xpath.regex.message"); + } + } + catch (MissingResourceException mre) { throw new RuntimeException("Installation Problem??? Couldn't load messages: " - +mre.getMessage()); + + mre.getMessage()); } } @@ -102,7 +110,7 @@ return new ParseException(this.resources.getString(key), loc); } - private final boolean isSet(int flag) { + protected final boolean isSet(int flag) { return (this.options & flag) == flag; } @@ -111,6 +119,7 @@ this.offset = 0; this.setContext(S_NORMAL); this.parennumber = 1; + this.parenOpened = 1; this.hasBackReferences = false; this.regex = regex; if (this.isSet(RegularExpression.EXTENDED_COMMENT)) @@ -171,8 +180,9 @@ break; case '-': - if (this.isSet(RegularExpression.XMLSCHEMA_MODE) - && this.offset < this.regexlen && this.regex.charAt(this.offset) == '[') { + // Allow character class subtraction (regardless of whether we are in + // XML Schema mode or not) + if (this.offset < this.regexlen && this.regex.charAt(this.offset) == '[') { this.offset++; ret = T_XMLSCHEMA_CC_SUBTRACTION; } else @@ -208,8 +218,22 @@ case ')': ret = T_RPAREN; break; case '.': ret = T_DOT; break; case '[': ret = T_LBRACKET; break; - case '^': ret = T_CARET; break; - case '$': ret = T_DOLLAR; break; + case '^': + if (this.isSet(RegularExpression.XMLSCHEMA_MODE)) { + ret = T_CHAR; + } + else { + ret = T_CARET; + } + break; + case '$': + if (this.isSet(RegularExpression.XMLSCHEMA_MODE)) { + ret = T_CHAR; + } + else { + ret = T_DOLLAR; + } + break; case '(': ret = T_LPAREN; if (this.offset >= this.regexlen) @@ -420,9 +444,10 @@ } Token processParen() throws ParseException { this.next(); - int p = this.parennumber++; + int p = this.parenOpened++; Token tok = Token.createParen(this.parseRegex(), p); if (this.read() != T_RPAREN) throw ex("parser.factor.1", this.offset-1); + this.parennumber++; this.next(); // Skips ')' return tok; } @@ -442,9 +467,31 @@ int ch = this.regex.charAt(this.offset); if ('1' <= ch && ch <= '9') { refno = ch-'0'; + int finalRefno = refno; + + if (this.parennumber <= refno) + throw ex("parser.parse.2", this.offset); + + while (this.offset + 1 < this.regexlen) { + ch = this.regex.charAt(this.offset + 1); + if ('1' <= ch && ch <= '9') { + refno = (refno * 10) + (ch - '0'); + if (refno < this.parennumber) { + finalRefno= refno; + ++this.offset; + } + else { + break; + } + } + else { + break; + } + } + this.hasBackReferences = true; if (this.references == null) this.references = new Vector(); - this.references.addElement(new ReferencePosition(refno, this.offset)); + this.references.addElement(new ReferencePosition(finalRefno, this.offset)); this.offset ++; if (this.regex.charAt(this.offset) != ')') throw ex("parser.factor.1", this.offset); this.offset ++; @@ -553,10 +600,33 @@ } Token processBackreference() throws ParseException { int refnum = this.chardata-'0'; - Token tok = Token.createBackReference(refnum); + int finalRefnum = refnum; + + if (this.parennumber <= refnum) + throw ex("parser.parse.2", this.offset-2); + + while (this.offset < this.regexlen) { + final int ch = this.regex.charAt(this.offset); + if ('1' <= ch && ch <= '9') { + refnum = (refnum * 10) + (ch - '0'); + if (refnum < this.parennumber) { + ++this.offset; + finalRefnum = refnum; + this.chardata = ch; + } + else { + break; + } + } + else { + break; + } + } + + Token tok = Token.createBackReference(finalRefnum); this.hasBackReferences = true; if (this.references == null) this.references = new Vector(); - this.references.addElement(new ReferencePosition(refnum, this.offset-2)); + this.references.addElement(new ReferencePosition(finalRefnum, this.offset-2)); this.next(); return tok; } @@ -821,7 +891,6 @@ while ((type = this.read()) != T_EOF) { if (type == T_CHAR && this.chardata == ']' && !firstloop) break; - firstloop = false; int c = this.chardata; boolean end = false; if (type == T_BACKSOLIDUS) { @@ -871,42 +940,83 @@ throw this.ex("parser.cc.1", nameend); this.offset = nameend+2; } + else if (type == T_XMLSCHEMA_CC_SUBTRACTION && !firstloop) { + if (nrange) { + nrange = false; + if (useNrange) { + tok = (RangeToken) Token.complementRanges(tok); + } + else { + base.subtractRanges(tok); + tok = base; + } + } + RangeToken range2 = this.parseCharacterClass(false); + tok.subtractRanges(range2); + if (this.read() != T_CHAR || this.chardata != ']') { + throw this.ex("parser.cc.5", this.offset); + } + break; // Exit this loop + } this.next(); if (!end) { // if not shorthands... if (this.read() != T_CHAR || this.chardata != '-') { // Here is no '-'. - tok.addRange(c, c); - } else { + if (!this.isSet(RegularExpression.IGNORE_CASE) || c > 0xffff) { + tok.addRange(c, c); + } + else { + addCaseInsensitiveChar(tok, c); + } + } + else if (type == T_XMLSCHEMA_CC_SUBTRACTION) { + throw this.ex("parser.cc.8", this.offset-1); + } + else { this.next(); // Skips '-' if ((type = this.read()) == T_EOF) throw this.ex("parser.cc.2", this.offset); if (type == T_CHAR && this.chardata == ']') { - tok.addRange(c, c); + if (!this.isSet(RegularExpression.IGNORE_CASE) || c > 0xffff) { + tok.addRange(c, c); + } + else { + addCaseInsensitiveChar(tok, c); + } tok.addRange('-', '-'); } else { int rangeend = this.chardata; - if (type == T_BACKSOLIDUS) + if (type == T_BACKSOLIDUS) { rangeend = this.decodeEscaped(); + } this.next(); - tok.addRange(c, rangeend); + if (c > rangeend) { + throw this.ex("parser.ope.3", this.offset-1); + } + if (!this.isSet(RegularExpression.IGNORE_CASE) || + (c > 0xffff && rangeend > 0xffff)) { + tok.addRange(c, rangeend); + } + else { + addCaseInsensitiveCharRange(tok, c, rangeend); + } } } } if (this.isSet(RegularExpression.SPECIAL_COMMA) - && this.read() == T_CHAR && this.chardata == ',') + && this.read() == T_CHAR && this.chardata == ',') { this.next(); + } + firstloop = false; } - if (this.read() == T_EOF) + if (this.read() == T_EOF) { throw this.ex("parser.cc.2", this.offset); + } + if (!useNrange && nrange) { base.subtractRanges(tok); tok = base; } tok.sortRanges(); tok.compactRanges(); - //tok.dumpRanges(); - /* - if (this.isSet(RegularExpression.IGNORE_CASE)) - tok = RangeToken.createCaseInsensitiveToken(tok); - */ this.setContext(S_NORMAL); this.next(); // Skips ']' @@ -1085,4 +1195,38 @@ if (ch < 'a') return -1; return ch-'a'+10; } + + static protected final void addCaseInsensitiveChar(RangeToken tok, int c) { + final int[] caseMap = CaseInsensitiveMap.get(c); + tok.addRange(c, c); + + if (caseMap != null) { + for (int i=0; i<caseMap.length; i+=2) { + tok.addRange(caseMap[i], caseMap[i]); + } + } + + } + + static protected final void addCaseInsensitiveCharRange(RangeToken tok, int start, int end) { + int[] caseMap; + int r1, r2; + if (start <= end) { + r1 = start; + r2 = end; + } else { + r1 = end; + r2 = start; + } + + tok.addRange(r1, r2); + for (int ch = r1; ch <= r2; ch++) { + caseMap = CaseInsensitiveMap.get(ch); + if (caseMap != null) { + for (int i=0; i<caseMap.length; i+=2) { + tok.addRange(caseMap[i], caseMap[i]); + } + } + } + } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java Wed Sep 28 17:10:18 2011 +0100 @@ -21,6 +21,10 @@ package com.sun.org.apache.xerces.internal.impl.xpath.regex; import java.text.CharacterIterator; +import java.util.Locale; +import java.util.Stack; + +import com.sun.org.apache.xerces.internal.util.IntStack; /** * A regular expression matching engine using Non-deterministic Finite Automaton (NFA). @@ -478,14 +482,15 @@ * </ul> * * <hr width="50%"> - * + * * @xerces.internal * * @author TAMURA Kent <kent@trl.ibm.co.jp> + * @version $Id: RegularExpression.java,v 1.9 2010/07/27 05:02:34 joehw Exp $ */ public class RegularExpression implements java.io.Serializable { - private static final long serialVersionUID = 3905241217112815923L; + private static final long serialVersionUID = 6242499334195006401L; static final boolean DEBUG = false; @@ -575,10 +580,7 @@ if (tok.type == Token.NONGREEDYCLOSURE) { op = Op.createNonGreedyClosure(); } else { // Token.CLOSURE - if (child.getMinLength() == 0) - op = Op.createClosure(this.numberOfClosures++); - else - op = Op.createClosure(-1); + op = Op.createClosure(this.numberOfClosures++); } op.next = next; op.setChild(compile(child, op, reverse)); @@ -701,7 +703,7 @@ * @param match A Match instance for storing matching result. * @return Offset of the start position in <VAR>target</VAR>; or -1 if not match. */ - public boolean matches(char[] target, int start, int end, Match match) { + public boolean matches(char[] target, int start, int end, Match match) { synchronized (this) { if (this.operations == null) @@ -726,14 +728,14 @@ con.match = match; if (RegularExpression.isSet(this.options, XMLSCHEMA_MODE)) { - int matchEnd = this. matchCharArray (con, this.operations, con.start, 1, this.options); + int matchEnd = this. match(con, this.operations, con.start, 1, this.options); //System.err.println("DEBUG: matchEnd="+matchEnd); if (matchEnd == con.limit) { if (con.match != null) { con.match.setBeginning(0, con.start); con.match.setEnd(0, matchEnd); } - con.inuse = false; + con.setInUse(false); return true; } return false; @@ -751,10 +753,10 @@ con.match.setBeginning(0, o); con.match.setEnd(0, o+this.fixedString.length()); } - con.inuse = false; + con.setInUse(false); return true; } - con.inuse = false; + con.setInUse(false); return false; } @@ -767,7 +769,7 @@ int o = this.fixedStringTable.matches(target, con.start, con.limit); if (o < 0) { //System.err.println("Non-match in fixed-string search."); - con.inuse = false; + con.setInUse(false); return false; } } @@ -783,7 +785,7 @@ && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { if (isSet(this.options, SINGLE_LINE)) { matchStart = con.start; - matchEnd = this. matchCharArray (con, this.operations, con.start, 1, this.options); + matchEnd = this. match(con, this.operations, con.start, 1, this.options); } else { boolean previousIsEOL = true; for (matchStart = con.start; matchStart <= limit; matchStart ++) { @@ -792,8 +794,8 @@ previousIsEOL = true; } else { if (previousIsEOL) { - if (0 <= (matchEnd = this. matchCharArray (con, this.operations, - matchStart, 1, this.options))) + if (0 <= (matchEnd = this. match(con, this.operations, + matchStart, 1, this.options))) break; } previousIsEOL = false; @@ -808,33 +810,16 @@ else if (this.firstChar != null) { //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar); RangeToken range = this.firstChar; - if (RegularExpression.isSet(this.options, IGNORE_CASE)) { - range = this.firstChar.getCaseInsensitiveToken(); - for (matchStart = con.start; matchStart <= limit; matchStart ++) { - int ch = target [ matchStart ] ; - if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { - ch = REUtil.composeFromSurrogates(ch, target [ matchStart+1 ] ); - if (!range.match(ch)) continue; - } else { - if (!range.match(ch)) { - char ch1 = Character.toUpperCase((char)ch); - if (!range.match(ch1)) - if (!range.match(Character.toLowerCase(ch1))) - continue; - } - } - if (0 <= (matchEnd = this. matchCharArray (con, this.operations, - matchStart, 1, this.options))) - break; + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target [matchStart] ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { + ch = REUtil.composeFromSurrogates(ch, target[matchStart+1]); } - } else { - for (matchStart = con.start; matchStart <= limit; matchStart ++) { - int ch = target [ matchStart ] ; - if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target [ matchStart+1 ] ); - if (!range.match(ch)) continue; - if (0 <= (matchEnd = this. matchCharArray (con, this.operations, - matchStart, 1, this.options))) + if (!range.match(ch)) { + continue; + } + if (0 <= (matchEnd = this. match(con, this.operations, + matchStart, 1, this.options))) { break; } } @@ -845,7 +830,7 @@ */ else { for (matchStart = con.start; matchStart <= limit; matchStart ++) { - if (0 <= (matchEnd = this. matchCharArray (con, this.operations, matchStart, 1, this.options))) + if (0 <= (matchEnd = this. match(con, this.operations, matchStart, 1, this.options))) break; } } @@ -855,521 +840,14 @@ con.match.setBeginning(0, matchStart); con.match.setEnd(0, matchEnd); } - con.inuse = false; + con.setInUse(false); return true; } else { - con.inuse = false; + con.setInUse(false); return false; } } -/** - * @return -1 when not match; offset of the end of matched string when match. - */ - private int matchCharArray (Context con, Op op, int offset, int dx, int opts) { - - char[] target = con.charTarget; - - - while (true) { - if (op == null) - return isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; - if (offset > con.limit || offset < con.start) - return -1; - switch (op.type) { - case Op.CHAR: - if (isSet(opts, IGNORE_CASE)) { - int ch = op.getData(); - if (dx > 0) { - if (offset >= con.limit || !matchIgnoreCase(ch, target [ offset ] )) - return -1; - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch, target [ o1 ] )) - return -1; - offset = o1; - } - } else { - int ch = op.getData(); - if (dx > 0) { - if (offset >= con.limit || ch != target [ offset ] ) - return -1; - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0 || ch != target [ o1 ] ) - return -1; - offset = o1; - } - } - op = op.next; - break; - - case Op.DOT: - if (dx > 0) { - if (offset >= con.limit) - return -1; - int ch = target [ offset ] ; - if (isSet(opts, SINGLE_LINE)) { - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - offset ++; - } else { - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target [ ++offset ] ); - if (isEOLChar(ch)) - return -1; - } - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0) - return -1; - int ch = target [ o1 ] ; - if (isSet(opts, SINGLE_LINE)) { - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - o1 --; - } else { - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - ch = REUtil.composeFromSurrogates( target [ --o1 ] , ch); - if (!isEOLChar(ch)) - return -1; - } - offset = o1; - } - op = op.next; - break; - - case Op.RANGE: - case Op.NRANGE: - if (dx > 0) { - if (offset >= con.limit) - return -1; - int ch = target [ offset ] ; - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target [ ++offset ] ); - RangeToken tok = op.getToken(); - if (isSet(opts, IGNORE_CASE)) { - tok = tok.getCaseInsensitiveToken(); - if (!tok.match(ch)) { - if (ch >= 0x10000) return -1; - char uch; - if (!tok.match(uch = Character.toUpperCase((char)ch)) - && !tok.match(Character.toLowerCase(uch))) - return -1; - } - } else { - if (!tok.match(ch)) return -1; - } - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0) - return -1; - int ch = target [ o1 ] ; - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - ch = REUtil.composeFromSurrogates( target [ --o1 ] , ch); - RangeToken tok = op.getToken(); - if (isSet(opts, IGNORE_CASE)) { - tok = tok.getCaseInsensitiveToken(); - if (!tok.match(ch)) { - if (ch >= 0x10000) return -1; - char uch; - if (!tok.match(uch = Character.toUpperCase((char)ch)) - && !tok.match(Character.toLowerCase(uch))) - return -1; - } - } else { - if (!tok.match(ch)) return -1; - } - offset = o1; - } - op = op.next; - break; - - case Op.ANCHOR: - boolean go = false; - switch (op.getData()) { - case '^': - if (isSet(opts, MULTIPLE_LINES)) { - if (!(offset == con.start - || offset > con.start && isEOLChar( target [ offset-1 ] ))) - return -1; - } else { - if (offset != con.start) - return -1; - } - break; - - case '@': // Internal use only. - // The @ always matches line beginnings. - if (!(offset == con.start - || offset > con.start && isEOLChar( target [ offset-1 ] ))) - return -1; - break; - - case '$': - if (isSet(opts, MULTIPLE_LINES)) { - if (!(offset == con.limit - || offset < con.limit && isEOLChar( target [ offset ] ))) - return -1; - } else { - if (!(offset == con.limit - || offset+1 == con.limit && isEOLChar( target [ offset ] ) - || offset+2 == con.limit && target [ offset ] == CARRIAGE_RETURN - && target [ offset+1 ] == LINE_FEED)) - return -1; - } - break; - - case 'A': - if (offset != con.start) return -1; - break; - - case 'Z': - if (!(offset == con.limit - || offset+1 == con.limit && isEOLChar( target [ offset ] ) - || offset+2 == con.limit && target [ offset ] == CARRIAGE_RETURN - && target [ offset+1 ] == LINE_FEED)) - return -1; - break; - - case 'z': - if (offset != con.limit) return -1; - break; - - case 'b': - if (con.length == 0) return -1; - { - int after = getWordType(target, con.start, con.limit, offset, opts); - if (after == WT_IGNORE) return -1; - int before = getPreviousWordType(target, con.start, con.limit, offset, opts); - if (after == before) return -1; - } - break; - - case 'B': - if (con.length == 0) - go = true; - else { - int after = getWordType(target, con.start, con.limit, offset, opts); - go = after == WT_IGNORE - || after == getPreviousWordType(target, con.start, con.limit, offset, opts); - } - if (!go) return -1; - break; - - case '<': - if (con.length == 0 || offset == con.limit) return -1; - if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER - || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) - return -1; - break; - - case '>': - if (con.length == 0 || offset == con.start) return -1; - if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER - || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) - return -1; - break; - } // switch anchor type - op = op.next; - break; - - case Op.BACKREFERENCE: - { - int refno = op.getData(); - if (refno <= 0 || refno >= this.nofparen) - throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); - if (con.match.getBeginning(refno) < 0 - || con.match.getEnd(refno) < 0) - return -1; // ******** - int o2 = con.match.getBeginning(refno); - int literallen = con.match.getEnd(refno)-o2; - if (!isSet(opts, IGNORE_CASE)) { - if (dx > 0) { - if (!regionMatches(target, offset, con.limit, o2, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatches(target, offset-literallen, con.limit, o2, literallen)) - return -1; - offset -= literallen; - } - } else { - if (dx > 0) { - if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, - o2, literallen)) - return -1; - offset -= literallen; - } - } - } - op = op.next; - break; - case Op.STRING: - { - String literal = op.getString(); - int literallen = literal.length(); - if (!isSet(opts, IGNORE_CASE)) { - if (dx > 0) { - if (!regionMatches(target, offset, con.limit, literal, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatches(target, offset-literallen, con.limit, literal, literallen)) - return -1; - offset -= literallen; - } - } else { - if (dx > 0) { - if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, - literal, literallen)) - return -1; - offset -= literallen; - } - } - } - op = op.next; - break; - - case Op.CLOSURE: - { - /* - * Saves current position to avoid - * zero-width repeats. - */ - int id = op.getData(); - if (id >= 0) { - int previousOffset = con.offsets[id]; - if (previousOffset < 0 || previousOffset != offset) { - con.offsets[id] = offset; - } else { - con.offsets[id] = -1; - op = op.next; - break; - } - } - - int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts); - if (id >= 0) con.offsets[id] = -1; - if (ret >= 0) return ret; - op = op.next; - } - break; - - case Op.QUESTION: - { - int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts); - if (ret >= 0) return ret; - op = op.next; - } - break; - - case Op.NONGREEDYCLOSURE: - case Op.NONGREEDYQUESTION: - { - int ret = this. matchCharArray (con, op.next, offset, dx, opts); - if (ret >= 0) return ret; - op = op.getChild(); - } - break; - - case Op.UNION: - for (int i = 0; i < op.size(); i ++) { - int ret = this. matchCharArray (con, op.elementAt(i), offset, dx, opts); - if (DEBUG) { - System.err.println("UNION: "+i+", ret="+ret); - } - if (ret >= 0) return ret; - } - return -1; - - case Op.CAPTURE: - int refno = op.getData(); - if (con.match != null && refno > 0) { - int save = con.match.getBeginning(refno); - con.match.setBeginning(refno, offset); - int ret = this. matchCharArray (con, op.next, offset, dx, opts); - if (ret < 0) con.match.setBeginning(refno, save); - return ret; - } else if (con.match != null && refno < 0) { - int index = -refno; - int save = con.match.getEnd(index); - con.match.setEnd(index, offset); - int ret = this. matchCharArray (con, op.next, offset, dx, opts); - if (ret < 0) con.match.setEnd(index, save); - return ret; - } - op = op.next; - break; - - case Op.LOOKAHEAD: - if (0 > this. matchCharArray (con, op.getChild(), offset, 1, opts)) return -1; - op = op.next; - break; - case Op.NEGATIVELOOKAHEAD: - if (0 <= this. matchCharArray (con, op.getChild(), offset, 1, opts)) return -1; - op = op.next; - break; - case Op.LOOKBEHIND: - if (0 > this. matchCharArray (con, op.getChild(), offset, -1, opts)) return -1; - op = op.next; - break; - case Op.NEGATIVELOOKBEHIND: - if (0 <= this. matchCharArray (con, op.getChild(), offset, -1, opts)) return -1; - op = op.next; - break; - - case Op.INDEPENDENT: - { - int ret = this. matchCharArray (con, op.getChild(), offset, dx, opts); - if (ret < 0) return ret; - offset = ret; - op = op.next; - } - break; - - case Op.MODIFIER: - { - int localopts = opts; - localopts |= op.getData(); - localopts &= ~op.getData2(); - //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16)); - int ret = this. matchCharArray (con, op.getChild(), offset, dx, localopts); - if (ret < 0) return ret; - offset = ret; - op = op.next; - } - break; - - case Op.CONDITION: - { - Op.ConditionOp cop = (Op.ConditionOp)op; - boolean matchp = false; - if (cop.refNumber > 0) { - if (cop.refNumber >= this.nofparen) - throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); - matchp = con.match.getBeginning(cop.refNumber) >= 0 - && con.match.getEnd(cop.refNumber) >= 0; - } else { - matchp = 0 <= this. matchCharArray (con, cop.condition, offset, dx, opts); - } - - if (matchp) { - op = cop.yes; - } else if (cop.no != null) { - op = cop.no; - } else { - op = cop.next; - } - } - break; - - default: - throw new RuntimeException("Unknown operation type: "+op.type); - } // switch (op.type) - } // while - } - - private static final int getPreviousWordType(char[] target, int begin, int end, - int offset, int opts) { - int ret = getWordType(target, begin, end, --offset, opts); - while (ret == WT_IGNORE) - ret = getWordType(target, begin, end, --offset, opts); - return ret; - } - - private static final int getWordType(char[] target, int begin, int end, - int offset, int opts) { - if (offset < begin || offset >= end) return WT_OTHER; - return getWordType0( target [ offset ] , opts); - } - - - - private static final boolean regionMatches(char[] target, int offset, int limit, - String part, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = 0; - while (partlen-- > 0) { - if ( target [ offset++ ] != part.charAt(i++)) - return false; - } - return true; - } - - private static final boolean regionMatches(char[] target, int offset, int limit, - int offset2, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = offset2; - while (partlen-- > 0) { - if ( target [ offset++ ] != target [ i++ ] ) - return false; - } - return true; - } - -/** - * @see java.lang.String#regionMatches - */ - private static final boolean regionMatchesIgnoreCase(char[] target, int offset, int limit, - String part, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = 0; - while (partlen-- > 0) { - char ch1 = target [ offset++ ] ; - char ch2 = part.charAt(i++); - if (ch1 == ch2) - continue; - char uch1 = Character.toUpperCase(ch1); - char uch2 = Character.toUpperCase(ch2); - if (uch1 == uch2) - continue; - if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) - return false; - } - return true; - } - - private static final boolean regionMatchesIgnoreCase(char[] target, int offset, int limit, - int offset2, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = offset2; - while (partlen-- > 0) { - char ch1 = target [ offset++ ] ; - char ch2 = target [ i++ ] ; - if (ch1 == ch2) - continue; - char uch1 = Character.toUpperCase(ch1); - char uch2 = Character.toUpperCase(ch2); - if (uch1 == uch2) - continue; - if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) - return false; - } - return true; - } - - - - /** * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not. * @@ -1438,7 +916,7 @@ if (DEBUG) { System.err.println("target string="+target); } - int matchEnd = this. matchString (con, this.operations, con.start, 1, this.options); + int matchEnd = this. match(con, this.operations, con.start, 1, this.options); if (DEBUG) { System.err.println("matchEnd="+matchEnd); System.err.println("con.limit="+con.limit); @@ -1448,7 +926,7 @@ con.match.setBeginning(0, con.start); con.match.setEnd(0, matchEnd); } - con.inuse = false; + con.setInUse(false); return true; } return false; @@ -1466,10 +944,10 @@ con.match.setBeginning(0, o); con.match.setEnd(0, o+this.fixedString.length()); } - con.inuse = false; + con.setInUse(false); return true; } - con.inuse = false; + con.setInUse(false); return false; } @@ -1482,7 +960,7 @@ int o = this.fixedStringTable.matches(target, con.start, con.limit); if (o < 0) { //System.err.println("Non-match in fixed-string search."); - con.inuse = false; + con.setInUse(false); return false; } } @@ -1498,7 +976,7 @@ && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { if (isSet(this.options, SINGLE_LINE)) { matchStart = con.start; - matchEnd = this. matchString (con, this.operations, con.start, 1, this.options); + matchEnd = this.match(con, this.operations, con.start, 1, this.options); } else { boolean previousIsEOL = true; for (matchStart = con.start; matchStart <= limit; matchStart ++) { @@ -1507,8 +985,8 @@ previousIsEOL = true; } else { if (previousIsEOL) { - if (0 <= (matchEnd = this. matchString (con, this.operations, - matchStart, 1, this.options))) + if (0 <= (matchEnd = this.match(con, this.operations, + matchStart, 1, this.options))) break; } previousIsEOL = false; @@ -1523,33 +1001,16 @@ else if (this.firstChar != null) { //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar); RangeToken range = this.firstChar; - if (RegularExpression.isSet(this.options, IGNORE_CASE)) { - range = this.firstChar.getCaseInsensitiveToken(); - for (matchStart = con.start; matchStart <= limit; matchStart ++) { - int ch = target .charAt( matchStart ) ; - if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { - ch = REUtil.composeFromSurrogates(ch, target .charAt( matchStart+1 ) ); - if (!range.match(ch)) continue; - } else { - if (!range.match(ch)) { - char ch1 = Character.toUpperCase((char)ch); - if (!range.match(ch1)) - if (!range.match(Character.toLowerCase(ch1))) - continue; - } - } - if (0 <= (matchEnd = this. matchString (con, this.operations, - matchStart, 1, this.options))) - break; + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .charAt( matchStart ) ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { + ch = REUtil.composeFromSurrogates(ch, target.charAt(matchStart+1)); } - } else { - for (matchStart = con.start; matchStart <= limit; matchStart ++) { - int ch = target .charAt( matchStart ) ; - if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target .charAt( matchStart+1 ) ); - if (!range.match(ch)) continue; - if (0 <= (matchEnd = this. matchString (con, this.operations, - matchStart, 1, this.options))) + if (!range.match(ch)) { + continue; + } + if (0 <= (matchEnd = this.match(con, this.operations, + matchStart, 1, this.options))) { break; } } @@ -1560,7 +1021,7 @@ */ else { for (matchStart = con.start; matchStart <= limit; matchStart ++) { - if (0 <= (matchEnd = this. matchString (con, this.operations, matchStart, 1, this.options))) + if (0 <= (matchEnd = this.match(con, this.operations, matchStart, 1, this.options))) break; } } @@ -1570,10 +1031,10 @@ con.match.setBeginning(0, matchStart); con.match.setEnd(0, matchEnd); } - con.inuse = false; + con.setInUse(false); return true; } else { - con.inuse = false; + con.setInUse(false); return false; } } @@ -1581,425 +1042,497 @@ /** * @return -1 when not match; offset of the end of matched string when match. */ - private int matchString (Context con, Op op, int offset, int dx, int opts) { - - - - - String target = con.strTarget; - - - + private int match(Context con, Op op, int offset, int dx, int opts) { + final ExpressionTarget target = con.target; + final Stack opStack = new Stack(); + final IntStack dataStack = new IntStack(); + final boolean isSetIgnoreCase = isSet(opts, IGNORE_CASE); + int retValue = -1; + boolean returned = false; - while (true) { - if (op == null) - return isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; - if (offset > con.limit || offset < con.start) - return -1; - switch (op.type) { - case Op.CHAR: - if (isSet(opts, IGNORE_CASE)) { - int ch = op.getData(); - if (dx > 0) { - if (offset >= con.limit || !matchIgnoreCase(ch, target .charAt( offset ) )) - return -1; - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch, target .charAt( o1 ) )) - return -1; - offset = o1; - } - } else { - int ch = op.getData(); - if (dx > 0) { - if (offset >= con.limit || ch != target .charAt( offset ) ) - return -1; - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0 || ch != target .charAt( o1 ) ) - return -1; - offset = o1; - } + for (;;) { + if (op == null || offset > con.limit || offset < con.start) { + if (op == null) { + retValue = isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; + } + else { + retValue = -1; } - op = op.next; - break; - - case Op.DOT: - if (dx > 0) { - if (offset >= con.limit) - return -1; - int ch = target .charAt( offset ) ; - if (isSet(opts, SINGLE_LINE)) { - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - offset ++; - } else { - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target .charAt( ++offset ) ); - if (isEOLChar(ch)) - return -1; + returned = true; + } + else { + retValue = -1; + // dx value is either 1 or -1 + switch (op.type) { + case Op.CHAR: + { + final int o1 = (dx > 0) ? offset : offset -1; + if (o1 >= con.limit || o1 < 0 || !matchChar(op.getData(), target.charAt(o1), isSetIgnoreCase)) { + returned = true; + break; + } + offset += dx; + op = op.next; } - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0) - return -1; - int ch = target .charAt( o1 ) ; - if (isSet(opts, SINGLE_LINE)) { - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - o1 --; - } else { - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - ch = REUtil.composeFromSurrogates( target .charAt( --o1 ) , ch); - if (!isEOLChar(ch)) - return -1; - } - offset = o1; - } - op = op.next; - break; + break; - case Op.RANGE: - case Op.NRANGE: - if (dx > 0) { - if (offset >= con.limit) - return -1; - int ch = target .charAt( offset ) ; - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target .charAt( ++offset ) ); - RangeToken tok = op.getToken(); - if (isSet(opts, IGNORE_CASE)) { - tok = tok.getCaseInsensitiveToken(); - if (!tok.match(ch)) { - if (ch >= 0x10000) return -1; - char uch; - if (!tok.match(uch = Character.toUpperCase((char)ch)) - && !tok.match(Character.toLowerCase(uch))) - return -1; + case Op.DOT: + { + int o1 = (dx > 0) ? offset : offset - 1; + if (o1 >= con.limit || o1 < 0) { + returned = true; + break; + } + if (isSet(opts, SINGLE_LINE)) { + if (REUtil.isHighSurrogate(target.charAt(o1)) && o1+dx >= 0 && o1+dx < con.limit) { + o1 += dx; + } + } + else { + int ch = target.charAt(o1); + if (REUtil.isHighSurrogate(ch) && o1+dx >= 0 && o1+dx < con.limit) { + o1 += dx; + ch = REUtil.composeFromSurrogates(ch, target.charAt(o1)); + } + if (isEOLChar(ch)) { + returned = true; + break; + } } - } else { - if (!tok.match(ch)) return -1; + offset = (dx > 0) ? o1 + 1 : o1; + op = op.next; } - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0) - return -1; - int ch = target .charAt( o1 ) ; - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - ch = REUtil.composeFromSurrogates( target .charAt( --o1 ) , ch); - RangeToken tok = op.getToken(); - if (isSet(opts, IGNORE_CASE)) { - tok = tok.getCaseInsensitiveToken(); + break; + + case Op.RANGE: + case Op.NRANGE: + { + int o1 = (dx > 0) ? offset : offset -1; + if (o1 >= con.limit || o1 < 0) { + returned = true; + break; + } + int ch = target.charAt(offset); + if (REUtil.isHighSurrogate(ch) && o1+dx < con.limit && o1+dx >=0) { + o1 += dx; + ch = REUtil.composeFromSurrogates(ch, target.charAt(o1)); + } + final RangeToken tok = op.getToken(); if (!tok.match(ch)) { - if (ch >= 0x10000) return -1; - char uch; - if (!tok.match(uch = Character.toUpperCase((char)ch)) - && !tok.match(Character.toLowerCase(uch))) - return -1; + returned = true; + break; } - } else { - if (!tok.match(ch)) return -1; + offset = (dx > 0) ? o1+1 : o1; + op = op.next; } - offset = o1; - } - op = op.next; - break; + break; - case Op.ANCHOR: - boolean go = false; - switch (op.getData()) { - case '^': - if (isSet(opts, MULTIPLE_LINES)) { - if (!(offset == con.start - || offset > con.start && isEOLChar( target .charAt( offset-1 ) ))) - return -1; - } else { - if (offset != con.start) - return -1; + case Op.ANCHOR: + { + if (!matchAnchor(target, op, con, offset, opts)) { + returned = true; + break; + } + op = op.next; } break; - case '@': // Internal use only. - // The @ always matches line beginnings. - if (!(offset == con.start - || offset > con.start && isEOLChar( target .charAt( offset-1 ) ))) - return -1; + case Op.BACKREFERENCE: + { + int refno = op.getData(); + if (refno <= 0 || refno >= this.nofparen) { + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); + } + if (con.match.getBeginning(refno) < 0 || con.match.getEnd(refno) < 0) { + returned = true; + break; + } + int o2 = con.match.getBeginning(refno); + int literallen = con.match.getEnd(refno)-o2; + if (dx > 0) { + if (!target.regionMatches(isSetIgnoreCase, offset, con.limit, o2, literallen)) { + returned = true; + break; + } + offset += literallen; + } + else { + if (!target.regionMatches(isSetIgnoreCase, offset-literallen, con.limit, o2, literallen)) { + returned = true; + break; + } + offset -= literallen; + } + op = op.next; + } break; - case '$': - if (isSet(opts, MULTIPLE_LINES)) { - if (!(offset == con.limit - || offset < con.limit && isEOLChar( target .charAt( offset ) ))) - return -1; - } else { - if (!(offset == con.limit - || offset+1 == con.limit && isEOLChar( target .charAt( offset ) ) - || offset+2 == con.limit && target .charAt( offset ) == CARRIAGE_RETURN - && target .charAt( offset+1 ) == LINE_FEED)) - return -1; + case Op.STRING: + { + String literal = op.getString(); + int literallen = literal.length(); + if (dx > 0) { + if (!target.regionMatches(isSetIgnoreCase, offset, con.limit, literal, literallen)) { + returned = true; + break; + } + offset += literallen; + } + else { + if (!target.regionMatches(isSetIgnoreCase, offset-literallen, con.limit, literal, literallen)) { + returned = true; + break; + } + offset -= literallen; + } + op = op.next; + } + break; + + case Op.CLOSURE: + { + // Saves current position to avoid zero-width repeats. + final int id = op.getData(); + if (con.closureContexts[id].contains(offset)) { + returned = true; + break; + } + + con.closureContexts[id].addOffset(offset); + } + // fall through + + case Op.QUESTION: + { + opStack.push(op); + dataStack.push(offset); + op = op.getChild(); } break; - case 'A': - if (offset != con.start) return -1; + case Op.NONGREEDYCLOSURE: + case Op.NONGREEDYQUESTION: + { + opStack.push(op); + dataStack.push(offset); + op = op.next; + } break; - case 'Z': - if (!(offset == con.limit - || offset+1 == con.limit && isEOLChar( target .charAt( offset ) ) - || offset+2 == con.limit && target .charAt( offset ) == CARRIAGE_RETURN - && target .charAt( offset+1 ) == LINE_FEED)) - return -1; + case Op.UNION: + if (op.size() == 0) { + returned = true; + } + else { + opStack.push(op); + dataStack.push(0); + dataStack.push(offset); + op = op.elementAt(0); + } break; - case 'z': - if (offset != con.limit) return -1; + case Op.CAPTURE: + { + final int refno = op.getData(); + if (con.match != null) { + if (refno > 0) { + dataStack.push(con.match.getBeginning(refno)); + con.match.setBeginning(refno, offset); + } + else { + final int index = -refno; + dataStack.push(con.match.getEnd(index)); + con.match.setEnd(index, offset); + } + opStack.push(op); + dataStack.push(offset); + } + op = op.next; + } break; - case 'b': - if (con.length == 0) return -1; + case Op.LOOKAHEAD: + case Op.NEGATIVELOOKAHEAD: + case Op.LOOKBEHIND: + case Op.NEGATIVELOOKBEHIND: + { + opStack.push(op); + dataStack.push(dx); + dataStack.push(offset); + dx = (op.type == Op.LOOKAHEAD || op.type == Op.NEGATIVELOOKAHEAD) ? 1 : -1; + op = op.getChild(); + } + break; + + case Op.INDEPENDENT: { - int after = getWordType(target, con.start, con.limit, offset, opts); - if (after == WT_IGNORE) return -1; - int before = getPreviousWordType(target, con.start, con.limit, offset, opts); - if (after == before) return -1; + opStack.push(op); + dataStack.push(offset); + op = op.getChild(); + } + break; + + case Op.MODIFIER: + { + int localopts = opts; + localopts |= op.getData(); + localopts &= ~op.getData2(); + opStack.push(op); + dataStack.push(opts); + dataStack.push(offset); + opts = localopts; + op = op.getChild(); } break; - case 'B': - if (con.length == 0) - go = true; - else { - int after = getWordType(target, con.start, con.limit, offset, opts); - go = after == WT_IGNORE - || after == getPreviousWordType(target, con.start, con.limit, offset, opts); + case Op.CONDITION: + { + Op.ConditionOp cop = (Op.ConditionOp)op; + if (cop.refNumber > 0) { + if (cop.refNumber >= this.nofparen) { + throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); + } + if (con.match.getBeginning(cop.refNumber) >= 0 + && con.match.getEnd(cop.refNumber) >= 0) { + op = cop.yes; + } + else if (cop.no != null) { + op = cop.no; + } + else { + op = cop.next; + } + } + else { + opStack.push(op); + dataStack.push(offset); + op = cop.condition; + } } - if (!go) return -1; - break; - - case '<': - if (con.length == 0 || offset == con.limit) return -1; - if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER - || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) - return -1; break; - case '>': - if (con.length == 0 || offset == con.start) return -1; - if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER - || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) - return -1; + default: + throw new RuntimeException("Unknown operation type: " + op.type); + } + } + + // handle recursive operations + while (returned) { + // exhausted all the operations + if (opStack.isEmpty()) { + return retValue; + } + + op = (Op) opStack.pop(); + offset = dataStack.pop(); + + switch (op.type) { + case Op.CLOSURE: + case Op.QUESTION: + if (retValue < 0) { + op = op.next; + returned = false; + } break; - } // switch anchor type - op = op.next; - break; - case Op.BACKREFERENCE: - { - int refno = op.getData(); - if (refno <= 0 || refno >= this.nofparen) - throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); - if (con.match.getBeginning(refno) < 0 - || con.match.getEnd(refno) < 0) - return -1; // ******** - int o2 = con.match.getBeginning(refno); - int literallen = con.match.getEnd(refno)-o2; - if (!isSet(opts, IGNORE_CASE)) { - if (dx > 0) { - if (!regionMatches(target, offset, con.limit, o2, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatches(target, offset-literallen, con.limit, o2, literallen)) - return -1; - offset -= literallen; + case Op.NONGREEDYCLOSURE: + case Op.NONGREEDYQUESTION: + if (retValue < 0) { + op = op.getChild(); + returned = false; + } + break; + + case Op.UNION: + { + int unionIndex = dataStack.pop(); + if (DEBUG) { + System.err.println("UNION: "+unionIndex+", ret="+retValue); } - } else { - if (dx > 0) { - if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, - o2, literallen)) - return -1; - offset -= literallen; + + if (retValue < 0) { + if (++unionIndex < op.size()) { + opStack.push(op); + dataStack.push(unionIndex); + dataStack.push(offset); + op = op.elementAt(unionIndex); + returned = false; + } + else { + retValue = -1; + } } } - } - op = op.next; - break; - case Op.STRING: - { - String literal = op.getString(); - int literallen = literal.length(); - if (!isSet(opts, IGNORE_CASE)) { - if (dx > 0) { - if (!regionMatches(target, offset, con.limit, literal, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatches(target, offset-literallen, con.limit, literal, literallen)) - return -1; - offset -= literallen; + break; + + case Op.CAPTURE: + final int refno = op.getData(); + final int saved = dataStack.pop(); + if (retValue < 0) { + if (refno > 0) { + con.match.setBeginning(refno, saved); } - } else { - if (dx > 0) { - if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, - literal, literallen)) - return -1; - offset -= literallen; - } - } - } - op = op.next; - break; - - case Op.CLOSURE: - { - /* - * Saves current position to avoid - * zero-width repeats. - */ - int id = op.getData(); - if (id >= 0) { - int previousOffset = con.offsets[id]; - if (previousOffset < 0 || previousOffset != offset) { - con.offsets[id] = offset; - } else { - con.offsets[id] = -1; - op = op.next; - break; + else { + con.match.setEnd(-refno, saved); } } - int ret = this. matchString (con, op.getChild(), offset, dx, opts); - if (id >= 0) con.offsets[id] = -1; - if (ret >= 0) return ret; - op = op.next; - } - break; + break; - case Op.QUESTION: - { - int ret = this. matchString (con, op.getChild(), offset, dx, opts); - if (ret >= 0) return ret; - op = op.next; - } - break; - - case Op.NONGREEDYCLOSURE: - case Op.NONGREEDYQUESTION: - { - int ret = this. matchString (con, op.next, offset, dx, opts); - if (ret >= 0) return ret; - op = op.getChild(); - } - break; + case Op.LOOKAHEAD: + case Op.LOOKBEHIND: + { + dx = dataStack.pop(); + if (0 <= retValue) { + op = op.next; + returned = false; + } + retValue = -1; + } + break; - case Op.UNION: - for (int i = 0; i < op.size(); i ++) { - int ret = this. matchString (con, op.elementAt(i), offset, dx, opts); - if (DEBUG) { - System.err.println("UNION: "+i+", ret="+ret); + case Op.NEGATIVELOOKAHEAD: + case Op.NEGATIVELOOKBEHIND: + { + dx = dataStack.pop(); + if (0 > retValue) { + op = op.next; + returned = false; + } + retValue = -1; } - if (ret >= 0) return ret; - } - return -1; + break; - case Op.CAPTURE: - int refno = op.getData(); - if (con.match != null && refno > 0) { - int save = con.match.getBeginning(refno); - con.match.setBeginning(refno, offset); - int ret = this. matchString (con, op.next, offset, dx, opts); - if (ret < 0) con.match.setBeginning(refno, save); - return ret; - } else if (con.match != null && refno < 0) { - int index = -refno; - int save = con.match.getEnd(index); - con.match.setEnd(index, offset); - int ret = this. matchString (con, op.next, offset, dx, opts); - if (ret < 0) con.match.setEnd(index, save); - return ret; - } - op = op.next; - break; + case Op.MODIFIER: + opts = dataStack.pop(); + // fall through - case Op.LOOKAHEAD: - if (0 > this. matchString (con, op.getChild(), offset, 1, opts)) return -1; - op = op.next; - break; - case Op.NEGATIVELOOKAHEAD: - if (0 <= this. matchString (con, op.getChild(), offset, 1, opts)) return -1; - op = op.next; - break; - case Op.LOOKBEHIND: - if (0 > this. matchString (con, op.getChild(), offset, -1, opts)) return -1; - op = op.next; - break; - case Op.NEGATIVELOOKBEHIND: - if (0 <= this. matchString (con, op.getChild(), offset, -1, opts)) return -1; - op = op.next; - break; - - case Op.INDEPENDENT: - { - int ret = this. matchString (con, op.getChild(), offset, dx, opts); - if (ret < 0) return ret; - offset = ret; - op = op.next; - } - break; + case Op.INDEPENDENT: + if (retValue >= 0) { + offset = retValue; + op = op.next; + returned = false; + } + break; - case Op.MODIFIER: - { - int localopts = opts; - localopts |= op.getData(); - localopts &= ~op.getData2(); - //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16)); - int ret = this. matchString (con, op.getChild(), offset, dx, localopts); - if (ret < 0) return ret; - offset = ret; - op = op.next; - } - break; + case Op.CONDITION: + { + final Op.ConditionOp cop = (Op.ConditionOp)op; + if (0 <= retValue) { + op = cop.yes; + } + else if (cop.no != null) { + op = cop.no; + } + else { + op = cop.next; + } + } + returned = false; + break; - case Op.CONDITION: - { - Op.ConditionOp cop = (Op.ConditionOp)op; - boolean matchp = false; - if (cop.refNumber > 0) { - if (cop.refNumber >= this.nofparen) - throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); - matchp = con.match.getBeginning(cop.refNumber) >= 0 - && con.match.getEnd(cop.refNumber) >= 0; - } else { - matchp = 0 <= this. matchString (con, cop.condition, offset, dx, opts); - } + default: + break; + } + } + } + } - if (matchp) { - op = cop.yes; - } else if (cop.no != null) { - op = cop.no; - } else { - op = cop.next; - } - } - break; - - default: - throw new RuntimeException("Unknown operation type: "+op.type); - } // switch (op.type) - } // while + private boolean matchChar(int ch, int other, boolean ignoreCase) { + return (ignoreCase) ? matchIgnoreCase(ch, other) : ch == other; } - private static final int getPreviousWordType(String target, int begin, int end, + boolean matchAnchor(ExpressionTarget target, Op op, Context con, int offset, int opts) { + boolean go = false; + switch (op.getData()) { + case '^': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.start + || offset > con.start && offset < con.limit && isEOLChar(target.charAt(offset-1)))) + return false; + } else { + if (offset != con.start) + return false; + } + break; + + case '@': // Internal use only. + // The @ always matches line beginnings. + if (!(offset == con.start + || offset > con.start && isEOLChar(target.charAt(offset-1)))) + return false; + break; + + case '$': + if (isSet(opts, MULTIPLE_LINES)) { + if (!(offset == con.limit + || offset < con.limit && isEOLChar(target.charAt(offset)))) + return false; + } else { + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar(target.charAt(offset)) + || offset+2 == con.limit && target.charAt(offset) == CARRIAGE_RETURN + && target.charAt(offset+1) == LINE_FEED)) + return false; + } + break; + + case 'A': + if (offset != con.start) return false; + break; + + case 'Z': + if (!(offset == con.limit + || offset+1 == con.limit && isEOLChar(target.charAt(offset)) + || offset+2 == con.limit && target.charAt(offset) == CARRIAGE_RETURN + && target.charAt(offset+1) == LINE_FEED)) + return false; + break; + + case 'z': + if (offset != con.limit) return false; + break; + + case 'b': + if (con.length == 0) + return false; + { + int after = getWordType(target, con.start, con.limit, offset, opts); + if (after == WT_IGNORE) return false; + int before = getPreviousWordType(target, con.start, con.limit, offset, opts); + if (after == before) return false; + } + break; + + case 'B': + if (con.length == 0) + go = true; + else { + int after = getWordType(target, con.start, con.limit, offset, opts); + go = after == WT_IGNORE + || after == getPreviousWordType(target, con.start, con.limit, offset, opts); + } + if (!go) return false; + break; + + case '<': + if (con.length == 0 || offset == con.limit) return false; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) + return false; + break; + + case '>': + if (con.length == 0 || offset == con.start) return false; + if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER + || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) + return false; + break; + } // switch anchor type + + return true; + } + + private static final int getPreviousWordType(ExpressionTarget target, int begin, int end, int offset, int opts) { int ret = getWordType(target, begin, end, --offset, opts); while (ret == WT_IGNORE) @@ -2007,41 +1540,12 @@ return ret; } - private static final int getWordType(String target, int begin, int end, + private static final int getWordType(ExpressionTarget target, int begin, int end, int offset, int opts) { if (offset < begin || offset >= end) return WT_OTHER; - return getWordType0( target .charAt( offset ) , opts); - } - - - private static final boolean regionMatches(String text, int offset, int limit, - String part, int partlen) { - if (limit-offset < partlen) return false; - return text.regionMatches(offset, part, 0, partlen); - } - - private static final boolean regionMatches(String text, int offset, int limit, - int offset2, int partlen) { - if (limit-offset < partlen) return false; - return text.regionMatches(offset, text, offset2, partlen); + return getWordType0(target.charAt(offset) , opts); } - private static final boolean regionMatchesIgnoreCase(String text, int offset, int limit, - String part, int partlen) { - return text.regionMatches(true, offset, part, 0, partlen); - } - - private static final boolean regionMatchesIgnoreCase(String text, int offset, int limit, - int offset2, int partlen) { - if (limit-offset < partlen) return false; - return text.regionMatches(true, offset, text, offset2, partlen); - } - - - - - - /** * Checks whether the <var>target</var> text <strong>contains</strong> this pattern or not. @@ -2088,14 +1592,14 @@ con.match = match; if (RegularExpression.isSet(this.options, XMLSCHEMA_MODE)) { - int matchEnd = this. matchCharacterIterator (con, this.operations, con.start, 1, this.options); + int matchEnd = this.match(con, this.operations, con.start, 1, this.options); //System.err.println("DEBUG: matchEnd="+matchEnd); if (matchEnd == con.limit) { if (con.match != null) { con.match.setBeginning(0, con.start); con.match.setEnd(0, matchEnd); } - con.inuse = false; + con.setInUse(false); return true; } return false; @@ -2113,10 +1617,10 @@ con.match.setBeginning(0, o); con.match.setEnd(0, o+this.fixedString.length()); } - con.inuse = false; + con.setInUse(false); return true; } - con.inuse = false; + con.setInUse(false); return false; } @@ -2129,7 +1633,7 @@ int o = this.fixedStringTable.matches(target, con.start, con.limit); if (o < 0) { //System.err.println("Non-match in fixed-string search."); - con.inuse = false; + con.setInUse(false); return false; } } @@ -2145,7 +1649,7 @@ && this.operations.type == Op.CLOSURE && this.operations.getChild().type == Op.DOT) { if (isSet(this.options, SINGLE_LINE)) { matchStart = con.start; - matchEnd = this. matchCharacterIterator (con, this.operations, con.start, 1, this.options); + matchEnd = this.match(con, this.operations, con.start, 1, this.options); } else { boolean previousIsEOL = true; for (matchStart = con.start; matchStart <= limit; matchStart ++) { @@ -2154,8 +1658,8 @@ previousIsEOL = true; } else { if (previousIsEOL) { - if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, - matchStart, 1, this.options))) + if (0 <= (matchEnd = this.match(con, this.operations, + matchStart, 1, this.options))) break; } previousIsEOL = false; @@ -2170,34 +1674,17 @@ else if (this.firstChar != null) { //System.err.println("DEBUG: with firstchar-matching: "+this.firstChar); RangeToken range = this.firstChar; - if (RegularExpression.isSet(this.options, IGNORE_CASE)) { - range = this.firstChar.getCaseInsensitiveToken(); - for (matchStart = con.start; matchStart <= limit; matchStart ++) { - int ch = target .setIndex( matchStart ) ; - if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { - ch = REUtil.composeFromSurrogates(ch, target .setIndex( matchStart+1 ) ); - if (!range.match(ch)) continue; - } else { - if (!range.match(ch)) { - char ch1 = Character.toUpperCase((char)ch); - if (!range.match(ch1)) - if (!range.match(Character.toLowerCase(ch1))) - continue; - } - } - if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, - matchStart, 1, this.options))) - break; + for (matchStart = con.start; matchStart <= limit; matchStart ++) { + int ch = target .setIndex( matchStart ) ; + if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) { + ch = REUtil.composeFromSurrogates(ch, target.setIndex(matchStart+1)); } - } else { - for (matchStart = con.start; matchStart <= limit; matchStart ++) { - int ch = target .setIndex( matchStart ) ; - if (REUtil.isHighSurrogate(ch) && matchStart+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target .setIndex( matchStart+1 ) ); - if (!range.match(ch)) continue; - if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, - matchStart, 1, this.options))) - break; + if (!range.match(ch)) { + continue; + } + if (0 <= (matchEnd = this.match(con, this.operations, + matchStart, 1, this.options))) { + break; } } } @@ -2207,7 +1694,7 @@ */ else { for (matchStart = con.start; matchStart <= limit; matchStart ++) { - if (0 <= (matchEnd = this. matchCharacterIterator (con, this.operations, matchStart, 1, this.options))) + if (0 <= (matchEnd = this. match(con, this.operations, matchStart, 1, this.options))) break; } } @@ -2217,526 +1704,14 @@ con.match.setBeginning(0, matchStart); con.match.setEnd(0, matchEnd); } - con.inuse = false; + con.setInUse(false); return true; } else { - con.inuse = false; + con.setInUse(false); return false; } } - /** - * @return -1 when not match; offset of the end of matched string when match. - */ - private int matchCharacterIterator (Context con, Op op, int offset, int dx, int opts) { - - - CharacterIterator target = con.ciTarget; - - - - - - - while (true) { - if (op == null) - return isSet(opts, XMLSCHEMA_MODE) && offset != con.limit ? -1 : offset; - if (offset > con.limit || offset < con.start) - return -1; - switch (op.type) { - case Op.CHAR: - if (isSet(opts, IGNORE_CASE)) { - int ch = op.getData(); - if (dx > 0) { - if (offset >= con.limit || !matchIgnoreCase(ch, target .setIndex( offset ) )) - return -1; - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0 || !matchIgnoreCase(ch, target .setIndex( o1 ) )) - return -1; - offset = o1; - } - } else { - int ch = op.getData(); - if (dx > 0) { - if (offset >= con.limit || ch != target .setIndex( offset ) ) - return -1; - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0 || ch != target .setIndex( o1 ) ) - return -1; - offset = o1; - } - } - op = op.next; - break; - - case Op.DOT: - if (dx > 0) { - if (offset >= con.limit) - return -1; - int ch = target .setIndex( offset ) ; - if (isSet(opts, SINGLE_LINE)) { - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - offset ++; - } else { - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target .setIndex( ++offset ) ); - if (isEOLChar(ch)) - return -1; - } - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0) - return -1; - int ch = target .setIndex( o1 ) ; - if (isSet(opts, SINGLE_LINE)) { - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - o1 --; - } else { - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - ch = REUtil.composeFromSurrogates( target .setIndex( --o1 ) , ch); - if (!isEOLChar(ch)) - return -1; - } - offset = o1; - } - op = op.next; - break; - - case Op.RANGE: - case Op.NRANGE: - if (dx > 0) { - if (offset >= con.limit) - return -1; - int ch = target .setIndex( offset ) ; - if (REUtil.isHighSurrogate(ch) && offset+1 < con.limit) - ch = REUtil.composeFromSurrogates(ch, target .setIndex( ++offset ) ); - RangeToken tok = op.getToken(); - if (isSet(opts, IGNORE_CASE)) { - tok = tok.getCaseInsensitiveToken(); - if (!tok.match(ch)) { - if (ch >= 0x10000) return -1; - char uch; - if (!tok.match(uch = Character.toUpperCase((char)ch)) - && !tok.match(Character.toLowerCase(uch))) - return -1; - } - } else { - if (!tok.match(ch)) return -1; - } - offset ++; - } else { - int o1 = offset-1; - if (o1 >= con.limit || o1 < 0) - return -1; - int ch = target .setIndex( o1 ) ; - if (REUtil.isLowSurrogate(ch) && o1-1 >= 0) - ch = REUtil.composeFromSurrogates( target .setIndex( --o1 ) , ch); - RangeToken tok = op.getToken(); - if (isSet(opts, IGNORE_CASE)) { - tok = tok.getCaseInsensitiveToken(); - if (!tok.match(ch)) { - if (ch >= 0x10000) return -1; - char uch; - if (!tok.match(uch = Character.toUpperCase((char)ch)) - && !tok.match(Character.toLowerCase(uch))) - return -1; - } - } else { - if (!tok.match(ch)) return -1; - } - offset = o1; - } - op = op.next; - break; - - case Op.ANCHOR: - boolean go = false; - switch (op.getData()) { - case '^': - if (isSet(opts, MULTIPLE_LINES)) { - if (!(offset == con.start - || offset > con.start && isEOLChar( target .setIndex( offset-1 ) ))) - return -1; - } else { - if (offset != con.start) - return -1; - } - break; - - case '@': // Internal use only. - // The @ always matches line beginnings. - if (!(offset == con.start - || offset > con.start && isEOLChar( target .setIndex( offset-1 ) ))) - return -1; - break; - - case '$': - if (isSet(opts, MULTIPLE_LINES)) { - if (!(offset == con.limit - || offset < con.limit && isEOLChar( target .setIndex( offset ) ))) - return -1; - } else { - if (!(offset == con.limit - || offset+1 == con.limit && isEOLChar( target .setIndex( offset ) ) - || offset+2 == con.limit && target .setIndex( offset ) == CARRIAGE_RETURN - && target .setIndex( offset+1 ) == LINE_FEED)) - return -1; - } - break; - - case 'A': - if (offset != con.start) return -1; - break; - - case 'Z': - if (!(offset == con.limit - || offset+1 == con.limit && isEOLChar( target .setIndex( offset ) ) - || offset+2 == con.limit && target .setIndex( offset ) == CARRIAGE_RETURN - && target .setIndex( offset+1 ) == LINE_FEED)) - return -1; - break; - - case 'z': - if (offset != con.limit) return -1; - break; - - case 'b': - if (con.length == 0) return -1; - { - int after = getWordType(target, con.start, con.limit, offset, opts); - if (after == WT_IGNORE) return -1; - int before = getPreviousWordType(target, con.start, con.limit, offset, opts); - if (after == before) return -1; - } - break; - - case 'B': - if (con.length == 0) - go = true; - else { - int after = getWordType(target, con.start, con.limit, offset, opts); - go = after == WT_IGNORE - || after == getPreviousWordType(target, con.start, con.limit, offset, opts); - } - if (!go) return -1; - break; - - case '<': - if (con.length == 0 || offset == con.limit) return -1; - if (getWordType(target, con.start, con.limit, offset, opts) != WT_LETTER - || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_OTHER) - return -1; - break; - - case '>': - if (con.length == 0 || offset == con.start) return -1; - if (getWordType(target, con.start, con.limit, offset, opts) != WT_OTHER - || getPreviousWordType(target, con.start, con.limit, offset, opts) != WT_LETTER) - return -1; - break; - } // switch anchor type - op = op.next; - break; - - case Op.BACKREFERENCE: - { - int refno = op.getData(); - if (refno <= 0 || refno >= this.nofparen) - throw new RuntimeException("Internal Error: Reference number must be more than zero: "+refno); - if (con.match.getBeginning(refno) < 0 - || con.match.getEnd(refno) < 0) - return -1; // ******** - int o2 = con.match.getBeginning(refno); - int literallen = con.match.getEnd(refno)-o2; - if (!isSet(opts, IGNORE_CASE)) { - if (dx > 0) { - if (!regionMatches(target, offset, con.limit, o2, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatches(target, offset-literallen, con.limit, o2, literallen)) - return -1; - offset -= literallen; - } - } else { - if (dx > 0) { - if (!regionMatchesIgnoreCase(target, offset, con.limit, o2, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, - o2, literallen)) - return -1; - offset -= literallen; - } - } - } - op = op.next; - break; - case Op.STRING: - { - String literal = op.getString(); - int literallen = literal.length(); - if (!isSet(opts, IGNORE_CASE)) { - if (dx > 0) { - if (!regionMatches(target, offset, con.limit, literal, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatches(target, offset-literallen, con.limit, literal, literallen)) - return -1; - offset -= literallen; - } - } else { - if (dx > 0) { - if (!regionMatchesIgnoreCase(target, offset, con.limit, literal, literallen)) - return -1; - offset += literallen; - } else { - if (!regionMatchesIgnoreCase(target, offset-literallen, con.limit, - literal, literallen)) - return -1; - offset -= literallen; - } - } - } - op = op.next; - break; - - case Op.CLOSURE: - { - /* - * Saves current position to avoid - * zero-width repeats. - */ - int id = op.getData(); - if (id >= 0) { - int previousOffset = con.offsets[id]; - if (previousOffset < 0 || previousOffset != offset) { - con.offsets[id] = offset; - } else { - con.offsets[id] = -1; - op = op.next; - break; - } - } - - int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts); - if (id >= 0) con.offsets[id] = -1; - if (ret >= 0) return ret; - op = op.next; - } - break; - - case Op.QUESTION: - { - int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts); - if (ret >= 0) return ret; - op = op.next; - } - break; - - case Op.NONGREEDYCLOSURE: - case Op.NONGREEDYQUESTION: - { - int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts); - if (ret >= 0) return ret; - op = op.getChild(); - } - break; - - case Op.UNION: - for (int i = 0; i < op.size(); i ++) { - int ret = this. matchCharacterIterator (con, op.elementAt(i), offset, dx, opts); - if (DEBUG) { - System.err.println("UNION: "+i+", ret="+ret); - } - if (ret >= 0) return ret; - } - return -1; - - case Op.CAPTURE: - int refno = op.getData(); - if (con.match != null && refno > 0) { - int save = con.match.getBeginning(refno); - con.match.setBeginning(refno, offset); - int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts); - if (ret < 0) con.match.setBeginning(refno, save); - return ret; - } else if (con.match != null && refno < 0) { - int index = -refno; - int save = con.match.getEnd(index); - con.match.setEnd(index, offset); - int ret = this. matchCharacterIterator (con, op.next, offset, dx, opts); - if (ret < 0) con.match.setEnd(index, save); - return ret; - } - op = op.next; - break; - - case Op.LOOKAHEAD: - if (0 > this. matchCharacterIterator (con, op.getChild(), offset, 1, opts)) return -1; - op = op.next; - break; - case Op.NEGATIVELOOKAHEAD: - if (0 <= this. matchCharacterIterator (con, op.getChild(), offset, 1, opts)) return -1; - op = op.next; - break; - case Op.LOOKBEHIND: - if (0 > this. matchCharacterIterator (con, op.getChild(), offset, -1, opts)) return -1; - op = op.next; - break; - case Op.NEGATIVELOOKBEHIND: - if (0 <= this. matchCharacterIterator (con, op.getChild(), offset, -1, opts)) return -1; - op = op.next; - break; - - case Op.INDEPENDENT: - { - int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, opts); - if (ret < 0) return ret; - offset = ret; - op = op.next; - } - break; - - case Op.MODIFIER: - { - int localopts = opts; - localopts |= op.getData(); - localopts &= ~op.getData2(); - //System.err.println("MODIFIER: "+Integer.toString(opts, 16)+" -> "+Integer.toString(localopts, 16)); - int ret = this. matchCharacterIterator (con, op.getChild(), offset, dx, localopts); - if (ret < 0) return ret; - offset = ret; - op = op.next; - } - break; - - case Op.CONDITION: - { - Op.ConditionOp cop = (Op.ConditionOp)op; - boolean matchp = false; - if (cop.refNumber > 0) { - if (cop.refNumber >= this.nofparen) - throw new RuntimeException("Internal Error: Reference number must be more than zero: "+cop.refNumber); - matchp = con.match.getBeginning(cop.refNumber) >= 0 - && con.match.getEnd(cop.refNumber) >= 0; - } else { - matchp = 0 <= this. matchCharacterIterator (con, cop.condition, offset, dx, opts); - } - - if (matchp) { - op = cop.yes; - } else if (cop.no != null) { - op = cop.no; - } else { - op = cop.next; - } - } - break; - - default: - throw new RuntimeException("Unknown operation type: "+op.type); - } // switch (op.type) - } // while - } - - private static final int getPreviousWordType(CharacterIterator target, int begin, int end, - int offset, int opts) { - int ret = getWordType(target, begin, end, --offset, opts); - while (ret == WT_IGNORE) - ret = getWordType(target, begin, end, --offset, opts); - return ret; - } - - private static final int getWordType(CharacterIterator target, int begin, int end, - int offset, int opts) { - if (offset < begin || offset >= end) return WT_OTHER; - return getWordType0( target .setIndex( offset ) , opts); - } - - - - private static final boolean regionMatches(CharacterIterator target, int offset, int limit, - String part, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = 0; - while (partlen-- > 0) { - if ( target .setIndex( offset++ ) != part.charAt(i++)) - return false; - } - return true; - } - - private static final boolean regionMatches(CharacterIterator target, int offset, int limit, - int offset2, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = offset2; - while (partlen-- > 0) { - if ( target .setIndex( offset++ ) != target .setIndex( i++ ) ) - return false; - } - return true; - } - - /** - * @see java.lang.String#regionMatches - */ - private static final boolean regionMatchesIgnoreCase(CharacterIterator target, int offset, int limit, - String part, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = 0; - while (partlen-- > 0) { - char ch1 = target .setIndex( offset++ ) ; - char ch2 = part.charAt(i++); - if (ch1 == ch2) - continue; - char uch1 = Character.toUpperCase(ch1); - char uch2 = Character.toUpperCase(ch2); - if (uch1 == uch2) - continue; - if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) - return false; - } - return true; - } - - private static final boolean regionMatchesIgnoreCase(CharacterIterator target, int offset, int limit, - int offset2, int partlen) { - if (offset < 0) return false; - if (limit-offset < partlen) - return false; - int i = offset2; - while (partlen-- > 0) { - char ch1 = target .setIndex( offset++ ) ; - char ch2 = target .setIndex( i++ ) ; - if (ch1 == ch2) - continue; - char uch1 = Character.toUpperCase(ch1); - char uch2 = Character.toUpperCase(ch2); - if (uch1 == uch2) - continue; - if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) - return false; - } - return true; - } - - - - // ================================================================ /** @@ -2773,47 +1748,343 @@ transient BMPattern fixedStringTable = null; transient boolean fixedStringOnly = false; + static abstract class ExpressionTarget { + abstract char charAt(int index); + abstract boolean regionMatches(boolean ignoreCase, int offset, int limit, String part, int partlen); + abstract boolean regionMatches(boolean ignoreCase, int offset, int limit, int offset2, int partlen); + } + + static final class StringTarget extends ExpressionTarget { + + private String target; + + StringTarget(String target) { + this.target = target; + } + + final void resetTarget(String target) { + this.target = target; + } + + final char charAt(int index) { + return target.charAt(index); + } + + final boolean regionMatches(boolean ignoreCase, int offset, int limit, + String part, int partlen) { + if (limit-offset < partlen) { + return false; + } + return (ignoreCase) ? target.regionMatches(true, offset, part, 0, partlen) : target.regionMatches(offset, part, 0, partlen); + } + + final boolean regionMatches(boolean ignoreCase, int offset, int limit, + int offset2, int partlen) { + if (limit-offset < partlen) { + return false; + } + return (ignoreCase) ? target.regionMatches(true, offset, target, offset2, partlen) + : target.regionMatches(offset, target, offset2, partlen); + } + } + + static final class CharArrayTarget extends ExpressionTarget { + + char[] target; + + CharArrayTarget(char[] target) { + this.target = target; + } + + final void resetTarget(char[] target) { + this.target = target; + } + + char charAt(int index) { + return target[index]; + } + + final boolean regionMatches(boolean ignoreCase, int offset, int limit, + String part, int partlen) { + if (offset < 0 || limit-offset < partlen) { + return false; + } + return (ignoreCase) ? regionMatchesIgnoreCase(offset, limit, part, partlen) + : regionMatches(offset, limit, part, partlen); + } + + private final boolean regionMatches(int offset, int limit, String part, int partlen) { + int i = 0; + while (partlen-- > 0) { + if (target[offset++] != part.charAt(i++)) { + return false; + } + } + return true; + } + + private final boolean regionMatchesIgnoreCase(int offset, int limit, String part, int partlen) { + int i = 0; + while (partlen-- > 0) { + final char ch1 = target[offset++] ; + final char ch2 = part.charAt(i++); + if (ch1 == ch2) { + continue; + } + final char uch1 = Character.toUpperCase(ch1); + final char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) { + continue; + } + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) { + return false; + } + } + return true; + } + + final boolean regionMatches(boolean ignoreCase, int offset, int limit, int offset2, int partlen) { + if (offset < 0 || limit-offset < partlen) { + return false; + } + return (ignoreCase) ? regionMatchesIgnoreCase(offset, limit, offset2, partlen) + : regionMatches(offset, limit, offset2, partlen); + } + + private final boolean regionMatches(int offset, int limit, int offset2, int partlen) { + int i = offset2; + while (partlen-- > 0) { + if ( target [ offset++ ] != target [ i++ ] ) + return false; + } + return true; + } + + private final boolean regionMatchesIgnoreCase(int offset, int limit, int offset2, int partlen) { + int i = offset2; + while (partlen-- > 0) { + final char ch1 = target[offset++] ; + final char ch2 = target[i++] ; + if (ch1 == ch2) { + continue; + } + final char uch1 = Character.toUpperCase(ch1); + final char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) { + continue; + } + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) { + return false; + } + } + return true; + } + } + + static final class CharacterIteratorTarget extends ExpressionTarget { + CharacterIterator target; + + CharacterIteratorTarget(CharacterIterator target) { + this.target = target; + } + + final void resetTarget(CharacterIterator target) { + this.target = target; + } + + final char charAt(int index) { + return target.setIndex(index); + } + + final boolean regionMatches(boolean ignoreCase, int offset, int limit, + String part, int partlen) { + if (offset < 0 || limit-offset < partlen) { + return false; + } + return (ignoreCase) ? regionMatchesIgnoreCase(offset, limit, part, partlen) + : regionMatches(offset, limit, part, partlen); + } + + private final boolean regionMatches(int offset, int limit, String part, int partlen) { + int i = 0; + while (partlen-- > 0) { + if (target.setIndex(offset++) != part.charAt(i++)) { + return false; + } + } + return true; + } + + private final boolean regionMatchesIgnoreCase(int offset, int limit, String part, int partlen) { + int i = 0; + while (partlen-- > 0) { + final char ch1 = target.setIndex(offset++) ; + final char ch2 = part.charAt(i++); + if (ch1 == ch2) { + continue; + } + final char uch1 = Character.toUpperCase(ch1); + final char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) { + continue; + } + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) { + return false; + } + } + return true; + } + + final boolean regionMatches(boolean ignoreCase, int offset, int limit, int offset2, int partlen) { + if (offset < 0 || limit-offset < partlen) { + return false; + } + return (ignoreCase) ? regionMatchesIgnoreCase(offset, limit, offset2, partlen) + : regionMatches(offset, limit, offset2, partlen); + } + + private final boolean regionMatches(int offset, int limit, int offset2, int partlen) { + int i = offset2; + while (partlen-- > 0) { + if (target.setIndex(offset++) != target.setIndex(i++)) { + return false; + } + } + return true; + } + + private final boolean regionMatchesIgnoreCase(int offset, int limit, int offset2, int partlen) { + int i = offset2; + while (partlen-- > 0) { + final char ch1 = target.setIndex(offset++) ; + final char ch2 = target.setIndex(i++) ; + if (ch1 == ch2) { + continue; + } + final char uch1 = Character.toUpperCase(ch1); + final char uch2 = Character.toUpperCase(ch2); + if (uch1 == uch2) { + continue; + } + if (Character.toLowerCase(uch1) != Character.toLowerCase(uch2)) { + return false; + } + } + return true; + } + } + + static final class ClosureContext { + + int[] offsets = new int[4]; + int currentIndex = 0; + + boolean contains(int offset) { + for (int i=0; i<currentIndex;++i) { + if (offsets[i] == offset) { + return true; + } + } + return false; + } + + void reset() { + currentIndex = 0; + } + + void addOffset(int offset) { + // We do not check for duplicates, caller is responsible for that + if (currentIndex == offsets.length) { + offsets = expandOffsets(); + } + offsets[currentIndex++] = offset; + } + + private int[] expandOffsets() { + final int len = offsets.length; + final int newLen = len << 1; + int[] newOffsets = new int[newLen]; + + System.arraycopy(offsets, 0, newOffsets, 0, currentIndex); + return newOffsets; + } + } static final class Context { - CharacterIterator ciTarget; - String strTarget; - char[] charTarget; int start; int limit; int length; Match match; boolean inuse = false; - int[] offsets; + ClosureContext[] closureContexts; + + private StringTarget stringTarget; + private CharArrayTarget charArrayTarget; + private CharacterIteratorTarget characterIteratorTarget; + + ExpressionTarget target; Context() { } private void resetCommon(int nofclosures) { this.length = this.limit-this.start; - this.inuse = true; + setInUse(true); this.match = null; - if (this.offsets == null || this.offsets.length != nofclosures) - this.offsets = new int[nofclosures]; - for (int i = 0; i < nofclosures; i ++) this.offsets[i] = -1; + if (this.closureContexts == null || this.closureContexts.length != nofclosures) { + this.closureContexts = new ClosureContext[nofclosures]; + } + for (int i = 0; i < nofclosures; i ++) { + if (this.closureContexts[i] == null) { + this.closureContexts[i] = new ClosureContext(); + } + else { + this.closureContexts[i].reset(); + } + } } + void reset(CharacterIterator target, int start, int limit, int nofclosures) { - this.ciTarget = target; + if (characterIteratorTarget == null) { + characterIteratorTarget = new CharacterIteratorTarget(target); + } + else { + characterIteratorTarget.resetTarget(target); + } + this.target = characterIteratorTarget; this.start = start; this.limit = limit; this.resetCommon(nofclosures); } + void reset(String target, int start, int limit, int nofclosures) { - this.strTarget = target; + if (stringTarget == null) { + stringTarget = new StringTarget(target); + } + else { + stringTarget.resetTarget(target); + } + this.target = stringTarget; this.start = start; this.limit = limit; this.resetCommon(nofclosures); } + void reset(char[] target, int start, int limit, int nofclosures) { - this.charTarget = target; + if (charArrayTarget == null) { + charArrayTarget = new CharArrayTarget(target); + } + else { + charArrayTarget.resetTarget(target); + } + this.target = charArrayTarget; this.start = start; this.limit = limit; this.resetCommon(nofclosures); } + synchronized void setInUse(boolean inUse) { + this.inuse = inUse; + } } /** @@ -2967,10 +2238,10 @@ * Creates a new RegularExpression instance. * * @param regex A regular expression - * @exception com.sun.org.apache.xerces.internal.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax. + * @exception org.apache.xerces.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax. */ public RegularExpression(String regex) throws ParseException { - this.setPattern(regex, null); + this(regex, null); } /** @@ -2978,12 +2249,23 @@ * * @param regex A regular expression * @param options A String consisted of "i" "m" "s" "u" "w" "," "X" - * @exception com.sun.org.apache.xerces.internal.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax. + * @exception org.apache.xerces.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax. */ public RegularExpression(String regex, String options) throws ParseException { this.setPattern(regex, options); } + /** + * Creates a new RegularExpression instance with options. + * + * @param regex A regular expression + * @param options A String consisted of "i" "m" "s" "u" "w" "," "X" + * @exception org.apache.xerces.utils.regex.ParseException <VAR>regex</VAR> is not conforming to the syntax. + */ + public RegularExpression(String regex, String options, Locale locale) throws ParseException { + this.setPattern(regex, options, locale); + } + RegularExpression(String regex, Token tok, int parens, boolean hasBackReferences, int options) { this.regex = regex; this.tokentree = tok; @@ -2996,14 +2278,18 @@ * */ public void setPattern(String newPattern) throws ParseException { - this.setPattern(newPattern, this.options); + this.setPattern(newPattern, Locale.getDefault()); } - private void setPattern(String newPattern, int options) throws ParseException { + public void setPattern(String newPattern, Locale locale) throws ParseException { + this.setPattern(newPattern, this.options, locale); + } + + private void setPattern(String newPattern, int options, Locale locale) throws ParseException { this.regex = newPattern; this.options = options; RegexParser rp = RegularExpression.isSet(this.options, RegularExpression.XMLSCHEMA_MODE) - ? new ParserForXMLSchema() : new RegexParser(); + ? new ParserForXMLSchema(locale) : new RegexParser(locale); this.tokentree = rp.parse(this.regex, this.options); this.nofparen = rp.parennumber; this.hasBackReferences = rp.hasBackReferences; @@ -3015,7 +2301,11 @@ * */ public void setPattern(String newPattern, String options) throws ParseException { - this.setPattern(newPattern, REUtil.parseOptions(options)); + this.setPattern(newPattern, options, Locale.getDefault()); + } + + public void setPattern(String newPattern, String options, Locale locale) throws ParseException { + this.setPattern(newPattern, REUtil.parseOptions(options), locale); } /**
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/Token.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xpath/regex/Token.java Wed Sep 28 17:10:18 2011 +0100 @@ -25,13 +25,14 @@ /** * This class represents a node in parse tree. - * + * * @xerces.internal * + * @version $Id: Token.java,v 1.7 2010/07/27 05:02:34 joehw Exp $ */ class Token implements java.io.Serializable { - private static final long serialVersionUID = 4049923761862293040L; + private static final long serialVersionUID = 8484976002585487481L; static final boolean COUNTTOKENS = true; static int tokens = 0; @@ -59,7 +60,7 @@ static final int UTF16_MAX = 0x10ffff; - int type; + final int type; static Token token_dot; static Token token_0to9; @@ -440,35 +441,15 @@ } return FC_TERMINAL; - case DOT: // **** - if (isSet(options, RegularExpression.SINGLE_LINE)) { - return FC_CONTINUE; // **** We can not optimize. - } else { - return FC_CONTINUE; - /* - result.addRange(0, RegularExpression.LINE_FEED-1); - result.addRange(RegularExpression.LINE_FEED+1, RegularExpression.CARRIAGE_RETURN-1); - result.addRange(RegularExpression.CARRIAGE_RETURN+1, - RegularExpression.LINE_SEPARATOR-1); - result.addRange(RegularExpression.PARAGRAPH_SEPARATOR+1, UTF16_MAX); - return 1; - */ - } + case DOT: + return FC_ANY; case RANGE: - if (isSet(options, RegularExpression.IGNORE_CASE)) { - result.mergeRanges(((RangeToken)this).getCaseInsensitiveToken()); - } else { - result.mergeRanges(this); - } + result.mergeRanges(this); return FC_TERMINAL; case NRANGE: // **** - if (isSet(options, RegularExpression.IGNORE_CASE)) { - result.mergeRanges(Token.complementRanges(((RangeToken)this).getCaseInsensitiveToken())); - } else { - result.mergeRanges(Token.complementRanges(this)); - } + result.mergeRanges(Token.complementRanges(this)); return FC_TERMINAL; case INDEPENDENT: @@ -710,7 +691,7 @@ /*FEFF..FEFF;*/ "Specials", /*FF00..FFEF;*/ "Halfwidth and Fullwidth Forms", //missing Specials add manually - /*10300..1032F;*/ "Old Italic", // 84 + /*10300..1032F;*/ "Old Italic", // 84 /*10330..1034F;*/ "Gothic", /*10400..1044F;*/ "Deseret", /*1D000..1D0FF;*/ "Byzantine Musical Symbols", @@ -820,7 +801,7 @@ type = CHAR_SYMBOL; break; default: - throw new RuntimeException("com.sun.org.apache.xerces.internal.utils.regex.Token#getRange(): Unknown Unicode category: "+type); + throw new RuntimeException("org.apache.xerces.utils.regex.Token#getRange(): Unknown Unicode category: "+type); } ranges[type].addRange(i, i); } // for all characters @@ -1047,8 +1028,7 @@ base_char.subtractRanges(Token.getRange("C", true)); Token virama = Token.createRange(); - for (int i = 0; i < Token.viramaString.length(); i ++) { - int ch = viramaString.charAt(i); + for (int i = 0; i < Token.viramaString.length(); i++) { virama.addRange(i, i); } @@ -1095,10 +1075,10 @@ */ static class StringToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3257288015452780086L; + private static final long serialVersionUID = -4614366944218504172L; String string; - int refNumber; + final int refNumber; StringToken(int type, String str, int n) { super(type); @@ -1126,10 +1106,10 @@ */ static class ConcatToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 4050760502994940212L; + private static final long serialVersionUID = 8717321425541346381L; - Token child; - Token child2; + final Token child; + final Token child2; ConcatToken(Token t1, Token t2) { super(Token.CONCAT); @@ -1161,9 +1141,9 @@ */ static class CharToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3257284751277569842L; + private static final long serialVersionUID = -4394272816279496989L; - int chardata; + final int chardata; CharToken(int type, int ch) { super(type); @@ -1225,11 +1205,11 @@ */ static class ClosureToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3545230349706932537L; + private static final long serialVersionUID = 1308971930673997452L; int min; int max; - Token child; + final Token child; ClosureToken(int type, Token tok) { super(type); @@ -1294,10 +1274,10 @@ */ static class ParenToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3257572797621219636L; + private static final long serialVersionUID = -5938014719827987704L; - Token child; - int parennumber; + final Token child; + final int parennumber; ParenToken(int type, Token tok, int paren) { super(type); @@ -1352,12 +1332,12 @@ */ static class ConditionToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3761408607870399794L; + private static final long serialVersionUID = 4353765277910594411L; - int refNumber; - Token condition; - Token yes; - Token no; + final int refNumber; + final Token condition; + final Token yes; + final Token no; ConditionToken(int refno, Token cond, Token yespat, Token nopat) { super(Token.CONDITION); this.refNumber = refno; @@ -1398,11 +1378,11 @@ */ static class ModifierToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3258689892778324790L; + private static final long serialVersionUID = -9114536559696480356L; - Token child; - int add; - int mask; + final Token child; + final int add; + final int mask; ModifierToken(Token tok, int add, int mask) { super(Token.MODIFIERGROUP); @@ -1441,7 +1421,7 @@ */ static class UnionToken extends Token implements java.io.Serializable { - private static final long serialVersionUID = 3256723987530003507L; + private static final long serialVersionUID = -2568843945989489861L; Vector children;
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Wed Sep 28 17:10:18 2011 +0100 @@ -77,117 +77,122 @@ /** * This class implements xni.grammars.XMLGrammarLoader. * It also serves as implementation of xs.XSLoader interface and DOMConfiguration interface. - * - * This class is designed to interact either with a proxy for a user application - * which wants to preparse schemas, or with our own Schema validator. + * + * This class is designed to interact either with a proxy for a user application + * which wants to preparse schemas, or with our own Schema validator. * It is hoped that none of these "external" classes will therefore need to communicate directly * with XSDHandler in future. * <p>This class only knows how to make XSDHandler do its thing. * The caller must ensure that all its properties (schemaLocation, JAXPSchemaSource * etc.) have been properly set. * - * @xerces.internal + * @xerces.internal * * @author Neil Graham, IBM + * @version $Id: XMLSchemaLoader.java,v 1.8 2010/07/23 02:09:29 joehw Exp $ */ public class XMLSchemaLoader implements XMLGrammarLoader, XMLComponent, -// XML Component API +// XML Component API XSLoader, DOMConfiguration { - + // Feature identifiers: - + /** Feature identifier: schema full checking*/ protected static final String SCHEMA_FULL_CHECKING = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_FULL_CHECKING; - + /** Feature identifier: continue after fatal error. */ protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE; - + /** Feature identifier: allow java encodings to be recognized when parsing schema docs. */ protected static final String ALLOW_JAVA_ENCODINGS = Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE; - + /** Feature identifier: standard uri conformant feature. */ protected static final String STANDARD_URI_CONFORMANT_FEATURE = Constants.XERCES_FEATURE_PREFIX + Constants.STANDARD_URI_CONFORMANT_FEATURE; - + /** Feature identifier: validate annotations. */ protected static final String VALIDATE_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX + Constants.VALIDATE_ANNOTATIONS_FEATURE; - + /** Feature: disallow doctype*/ - protected static final String DISALLOW_DOCTYPE = + protected static final String DISALLOW_DOCTYPE = Constants.XERCES_FEATURE_PREFIX + Constants.DISALLOW_DOCTYPE_DECL_FEATURE; - + /** Feature: generate synthetic annotations */ - protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = + protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE; - + /** Feature identifier: honour all schemaLocations */ - protected static final String HONOUR_ALL_SCHEMALOCATIONS = + protected static final String HONOUR_ALL_SCHEMALOCATIONS = Constants.XERCES_FEATURE_PREFIX + Constants.HONOUR_ALL_SCHEMALOCATIONS_FEATURE; - - protected static final String AUGMENT_PSVI = + + protected static final String AUGMENT_PSVI = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_AUGMENT_PSVI; - - protected static final String PARSER_SETTINGS = - Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; - + + protected static final String PARSER_SETTINGS = + Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; + // recognized features: private static final String[] RECOGNIZED_FEATURES = { SCHEMA_FULL_CHECKING, AUGMENT_PSVI, CONTINUE_AFTER_FATAL_ERROR, ALLOW_JAVA_ENCODINGS, - STANDARD_URI_CONFORMANT_FEATURE, + STANDARD_URI_CONFORMANT_FEATURE, DISALLOW_DOCTYPE, GENERATE_SYNTHETIC_ANNOTATIONS, VALIDATE_ANNOTATIONS, HONOUR_ALL_SCHEMALOCATIONS }; - + // property identifiers - + /** Property identifier: symbol table. */ public static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; - + /** Property identifier: error reporter. */ public static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; - + /** Property identifier: error handler. */ protected static final String ERROR_HANDLER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY; - + /** Property identifier: entity resolver. */ public static final String ENTITY_RESOLVER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; - + /** Property identifier: grammar pool. */ public static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; - + /** Property identifier: schema location. */ protected static final String SCHEMA_LOCATION = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_LOCATION; - + /** Property identifier: no namespace schema location. */ protected static final String SCHEMA_NONS_LOCATION = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_NONS_LOCATION; - + /** Property identifier: JAXP schema source. */ protected static final String JAXP_SCHEMA_SOURCE = Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; - + protected static final String SECURITY_MANAGER = - Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Property identifier: locale. */ + protected static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + protected static final String ENTITY_MANAGER = - Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; - + Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; + // recognized properties private static final String [] RECOGNIZED_PROPERTIES = { ENTITY_MANAGER, @@ -199,11 +204,12 @@ SCHEMA_LOCATION, SCHEMA_NONS_LOCATION, JAXP_SCHEMA_SOURCE, - SECURITY_MANAGER + SECURITY_MANAGER, + LOCALE }; - + // Data - + // features and properties private ParserConfigurationSettings fLoaderConfig = new ParserConfigurationSettings(); private SymbolTable fSymbolTable = null; @@ -213,7 +219,7 @@ private XMLGrammarPool fGrammarPool = null; private String fExternalSchemas = null; private String fExternalNoNSSchema = null; - // JAXP property: schema source + // JAXP property: schema source private Object fJAXPSource = null; // is Schema Full Checking enabled private boolean fIsCheckedFully = false; @@ -221,7 +227,7 @@ private boolean fJAXPProcessed = false; // if features/properties has not been changed, the value of this attribute is "false" private boolean fSettingsChanged = true; - + // xml schema parsing private XSDHandler fSchemaHandler; private XSGrammarBucket fGrammarBucket; @@ -229,30 +235,30 @@ private SubstitutionGroupHandler fSubGroupHandler; private CMBuilder fCMBuilder; private XSDDescription fXSDDescription = new XSDDescription(); - + private Hashtable fJAXPCache; private Locale fLocale = Locale.getDefault(); - + // XSLoader attributes private DOMStringList fRecognizedParameters = null; - + /** DOM L3 error handler */ private DOMErrorHandlerWrapper fErrorHandler = null; - + /** DOM L3 resource resolver */ private DOMEntityResolverWrapper fResourceResolver = null; - + // default constructor. Create objects we absolutely need: public XMLSchemaLoader() { this( new SymbolTable(), null, new XMLEntityManager(), null, null, null); } - + public XMLSchemaLoader(SymbolTable symbolTable) { this( symbolTable, null, new XMLEntityManager(), null, null, null); } - + /** - * This constractor is used by the XMLSchemaValidator. Additional properties, i.e. XMLEntityManager, + * This constractor is used by the XMLSchemaValidator. Additional properties, i.e. XMLEntityManager, * will be passed during reset(XMLComponentManager). * @param errorReporter * @param grammarBucket @@ -264,26 +270,26 @@ SubstitutionGroupHandler sHandler, CMBuilder builder) { this(null, errorReporter, null, grammarBucket, sHandler, builder); } - + XMLSchemaLoader(SymbolTable symbolTable, XMLErrorReporter errorReporter, XMLEntityManager entityResolver, XSGrammarBucket grammarBucket, SubstitutionGroupHandler sHandler, CMBuilder builder) { - + // store properties and features in configuration fLoaderConfig.addRecognizedFeatures(RECOGNIZED_FEATURES); - fLoaderConfig.addRecognizedProperties(RECOGNIZED_PROPERTIES); - if (symbolTable != null){ - fLoaderConfig.setProperty(SYMBOL_TABLE, symbolTable); + fLoaderConfig.addRecognizedProperties(RECOGNIZED_PROPERTIES); + if (symbolTable != null){ + fLoaderConfig.setProperty(SYMBOL_TABLE, symbolTable); } - + if(errorReporter == null) { errorReporter = new XMLErrorReporter (); errorReporter.setLocale(fLocale); errorReporter.setProperty(ERROR_HANDLER, new DefaultErrorHandler()); - + } fErrorReporter = errorReporter; // make sure error reporter knows about schemas... @@ -291,15 +297,15 @@ fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter()); } fLoaderConfig.setProperty(ERROR_REPORTER, fErrorReporter); - fEntityManager = entityResolver; - // entity manager is null if XMLSchemaValidator creates the loader - if (fEntityManager != null){ + fEntityManager = entityResolver; + // entity manager is null if XMLSchemaValidator creates the loader + if (fEntityManager != null){ fLoaderConfig.setProperty(ENTITY_MANAGER, fEntityManager); } - + // by default augment PSVI (i.e. don't use declaration pool) fLoaderConfig.setFeature(AUGMENT_PSVI, true); - + if(grammarBucket == null ) { grammarBucket = new XSGrammarBucket(); } @@ -308,10 +314,10 @@ sHandler = new SubstitutionGroupHandler(fGrammarBucket); } fSubGroupHandler = sHandler; - + //get an instance of the CMNodeFactory */ CMNodeFactory nodeFactory = new CMNodeFactory() ; - + if(builder == null) { builder = new CMBuilder(nodeFactory); } @@ -319,10 +325,10 @@ fSchemaHandler = new XSDHandler(fGrammarBucket); fDeclPool = new XSDeclarationPool(); fJAXPCache = new Hashtable(); - + fSettingsChanged = true; } - + /** * Returns a list of feature identifiers that are recognized by * this XMLGrammarLoader. This method may return null if no features @@ -331,7 +337,7 @@ public String[] getRecognizedFeatures() { return (String[])(RECOGNIZED_FEATURES.clone()); } // getRecognizedFeatures(): String[] - + /** * Returns the state of a feature. * @@ -340,10 +346,10 @@ * @throws XMLConfigurationException Thrown on configuration error. */ public boolean getFeature(String featureId) - throws XMLConfigurationException { - return fLoaderConfig.getFeature(featureId); + throws XMLConfigurationException { + return fLoaderConfig.getFeature(featureId); } // getFeature (String): boolean - + /** * Sets the state of a feature. * @@ -355,16 +361,16 @@ */ public void setFeature(String featureId, boolean state) throws XMLConfigurationException { - fSettingsChanged = true; + fSettingsChanged = true; if(featureId.equals(CONTINUE_AFTER_FATAL_ERROR)) { fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR, state); - } + } else if(featureId.equals(GENERATE_SYNTHETIC_ANNOTATIONS)) { fSchemaHandler.setGenerateSyntheticAnnotations(state); } fLoaderConfig.setFeature(featureId, state); } // setFeature(String, boolean) - + /** * Returns a list of property identifiers that are recognized by * this XMLGrammarLoader. This method may return null if no properties @@ -373,7 +379,7 @@ public String[] getRecognizedProperties() { return (String[])(RECOGNIZED_PROPERTIES.clone()); } // getRecognizedProperties(): String[] - + /** * Returns the state of a property. * @@ -385,7 +391,7 @@ throws XMLConfigurationException { return fLoaderConfig.getProperty(propertyId); } // getProperty(String): Object - + /** * Sets the state of a property. * @@ -396,33 +402,36 @@ * recognized or cannot be set. */ public void setProperty(String propertyId, - Object state) throws XMLConfigurationException { + Object state) throws XMLConfigurationException { fSettingsChanged = true; - fLoaderConfig.setProperty(propertyId, state); - if(propertyId.equals( JAXP_SCHEMA_SOURCE)) { + fLoaderConfig.setProperty(propertyId, state); + if (propertyId.equals(JAXP_SCHEMA_SOURCE)) { fJAXPSource = state; fJAXPProcessed = false; - } - else if(propertyId.equals( XMLGRAMMAR_POOL)) { + } + else if (propertyId.equals(XMLGRAMMAR_POOL)) { fGrammarPool = (XMLGrammarPool)state; - } - else if (propertyId.equals(SCHEMA_LOCATION)){ + } + else if (propertyId.equals(SCHEMA_LOCATION)) { fExternalSchemas = (String)state; } - else if (propertyId.equals(SCHEMA_NONS_LOCATION)){ + else if (propertyId.equals(SCHEMA_NONS_LOCATION)) { fExternalNoNSSchema = (String) state; } - else if (propertyId.equals(ENTITY_RESOLVER)){ + else if (propertyId.equals(LOCALE)) { + setLocale((Locale) state); + } + else if (propertyId.equals(ENTITY_RESOLVER)) { fEntityManager.setProperty(ENTITY_RESOLVER, state); } - else if (propertyId.equals(ERROR_REPORTER)){ + else if (propertyId.equals(ERROR_REPORTER)) { fErrorReporter = (XMLErrorReporter)state; if (fErrorReporter.getMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN) == null) { fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter()); } } } // setProperty(String, Object) - + /** * Set the locale to use for messages. * @@ -435,12 +444,12 @@ fLocale = locale; fErrorReporter.setLocale(locale); } // setLocale(Locale) - + /** Return the Locale the XMLGrammarLoader is using. */ public Locale getLocale() { return fLocale; } // getLocale(): Locale - + /** * Sets the error handler. * @@ -449,12 +458,12 @@ public void setErrorHandler(XMLErrorHandler errorHandler) { fErrorReporter.setProperty(ERROR_HANDLER, errorHandler); } // setErrorHandler(XMLErrorHandler) - + /** Returns the registered error handler. */ public XMLErrorHandler getErrorHandler() { return fErrorReporter.getErrorHandler(); } // getErrorHandler(): XMLErrorHandler - + /** * Sets the entity resolver. * @@ -465,30 +474,30 @@ fLoaderConfig.setProperty(ENTITY_RESOLVER, entityResolver); fEntityManager.setProperty(ENTITY_RESOLVER, entityResolver); } // setEntityResolver(XMLEntityResolver) - + /** Returns the registered entity resolver. */ public XMLEntityResolver getEntityResolver() { return fUserEntityResolver; } // getEntityResolver(): XMLEntityResolver - + /** * Returns a Grammar object by parsing the contents of the * entities pointed to by sources. - * - * @param source[] the locations of the entity which forms + * + * @param source[] the locations of the entity which forms * the staring point of the grammars to be constructed * @throws IOException when a problem is encounted reading the entity * @throws XNIException when a condition arises (such as a FatalError) that requires parsing * of the entity be terminated */ - public void loadGrammar(XMLInputSource source[]) + public void loadGrammar(XMLInputSource source[]) throws IOException, XNIException { int numSource = source.length; for (int i = 0; i < numSource; ++i) { loadGrammar(source[i]); - } + } } - + /** * Returns a Grammar object by parsing the contents of the * entity pointed to by source. @@ -501,11 +510,11 @@ */ public Grammar loadGrammar(XMLInputSource source) throws IOException, XNIException { - - // REVISIT: this method should have a namespace parameter specified by + + // REVISIT: this method should have a namespace parameter specified by // user. In this case we can easily detect if a schema asked to be loaded // is already in the local cache. - + reset(fLoaderConfig); fSettingsChanged = false; XSDDescription desc = new XSDDescription(); @@ -520,7 +529,7 @@ processExternalHints(fExternalSchemas, fExternalNoNSSchema, locationPairs, fErrorReporter); SchemaGrammar grammar = loadSchema(desc, source, locationPairs); - + if(grammar != null && fGrammarPool != null) { fGrammarPool.cacheGrammars(XMLGrammarDescription.XML_SCHEMA, fGrammarBucket.getGrammars()); // NOTE: we only need to verify full checking in case the schema was not provided via JAXP @@ -531,11 +540,11 @@ } return grammar; } // loadGrammar(XMLInputSource): Grammar - + /** * This method is called either from XMLGrammarLoader.loadGrammar or from XMLSchemaValidator. * Note: in either case, the EntityManager (or EntityResolvers) are not going to be invoked - * to resolve the location of the schema in XSDDescription + * to resolve the location of the schema in XSDDescription * @param desc * @param source * @param locationPairs @@ -546,17 +555,17 @@ SchemaGrammar loadSchema(XSDDescription desc, XMLInputSource source, Hashtable locationPairs) throws IOException, XNIException { - + // this should only be done once per invocation of this object; // unless application alters JAXPSource in the mean time. if(!fJAXPProcessed) { processJAXPSchemaSource(locationPairs); } SchemaGrammar grammar = fSchemaHandler.parseSchema(source, desc, locationPairs); - + return grammar; } // loadSchema(XSDDescription, XMLInputSource): SchemaGrammar - + /** This method tries to resolve location of the given schema. * The loader stores the namespace/location pairs in a hashtable (use "" as the * namespace of absent namespace). When resolving an entity, loader first tries @@ -583,7 +592,7 @@ if(tempLA != null) loc = tempLA.getFirstLocation(); } - + // if it's not import, or if the target namespace is not set // in the schema location properties, use location hint if (loc == null) { @@ -591,13 +600,13 @@ if (hints != null && hints.length > 0) loc = hints[0]; } - + String expandedLoc = XMLEntityManager.expandSystemId(loc, desc.getBaseSystemId(), false); desc.setLiteralSystemId(loc); desc.setExpandedSystemId(expandedLoc); return entityResolver.resolveEntity(desc); } - + // add external schema locations to the location pairs public static void processExternalHints(String sl, String nsl, Hashtable locations, @@ -625,7 +634,7 @@ XMLErrorReporter.SEVERITY_WARNING); } } - + if (nsl != null) { try { // similarly for no ns schema location property @@ -673,7 +682,7 @@ } return true; } // tokenizeSchemaLocation(String, Hashtable): boolean - + /** * Translate the various JAXP SchemaSource property types to XNI * XMLInputSource. Valid types are: String, org.xml.sax.InputSource, @@ -682,14 +691,14 @@ * should be available to imported schemas. I have assumed * that it should. - NG * Note: all JAXP schema files will be checked for full-schema validity if the feature was set up - * + * */ private void processJAXPSchemaSource(Hashtable locationPairs) throws IOException { fJAXPProcessed = true; if (fJAXPSource == null) { return; } - + Class componentType = fJAXPSource.getClass().getComponentType(); XMLInputSource xis = null; String sid = null; @@ -739,7 +748,7 @@ "}. Possible types of the array supported are Object, String, File, "+ "InputStream, InputSource."); } - + // JAXP spec. allow []s of type String, File, InputStream, // InputSource also, apart from [] of type Object. Object[] objArr = (Object[]) fJAXPSource; @@ -767,10 +776,10 @@ String targetNamespace = null ; // load schema SchemaGrammar grammar = fSchemaHandler.parseSchema(xis,fXSDDescription, locationPairs); - + if(fIsCheckedFully) { XSConstraints.fullSchemaChecking(fGrammarBucket, fSubGroupHandler, fCMBuilder, fErrorReporter); - } + } if(grammar != null){ targetNamespace = grammar.getTargetNamespace() ; if(jaxpSchemaSourceNamespaces.contains(targetNamespace)){ @@ -793,14 +802,14 @@ } } }//processJAXPSchemaSource - + private XMLInputSource xsdToXMLInputSource( Object val) { if (val instanceof String) { // String value is treated as a URI that is passed through the // EntityResolver - String loc = (String) val; + String loc = (String) val; fXSDDescription.reset(); fXSDDescription.setValues(null, loc, null, null); XMLInputSource xis = null; @@ -840,65 +849,65 @@ "}. Possible types of the value supported are String, File, InputStream, "+ "InputSource OR an array of these types."); } - - + + //Convert a SAX InputSource to an equivalent XNI XMLInputSource - + private static XMLInputSource saxToXMLInputSource(InputSource sis) { String publicId = sis.getPublicId(); String systemId = sis.getSystemId(); - + Reader charStream = sis.getCharacterStream(); if (charStream != null) { return new XMLInputSource(publicId, systemId, null, charStream, null); } - + InputStream byteStream = sis.getByteStream(); if (byteStream != null) { return new XMLInputSource(publicId, systemId, null, byteStream, sis.getEncoding()); } - + return new XMLInputSource(publicId, systemId, null); } - + static class LocationArray{ - + int length ; String [] locations = new String[2]; - + public void resize(int oldLength , int newLength){ String [] temp = new String[newLength] ; System.arraycopy(locations, 0, temp, 0, Math.min(oldLength, newLength)); locations = temp ; length = Math.min(oldLength, newLength); } - + public void addLocation(String location){ if(length >= locations.length ){ resize(length, Math.max(1, length*2)); } locations[length++] = location; }//setLocation() - + public String [] getLocationArray(){ if(length < locations.length ){ resize(locations.length, length); } return locations; }//getLocationArray() - + public String getFirstLocation(){ return length > 0 ? locations[0] : null; } - + public int getLength(){ return length ; } - + } //locationArray - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#getFeatureDefault(java.lang.String) */ @@ -908,7 +917,7 @@ } return null; } - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#getPropertyDefault(java.lang.String) */ @@ -916,44 +925,46 @@ // TODO Auto-generated method stub return null; } - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.parser.XMLComponent#reset(com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager) */ public void reset(XMLComponentManager componentManager) throws XMLConfigurationException { - + fGrammarBucket.reset(); - - fSubGroupHandler.reset(); - + + fSubGroupHandler.reset(); + boolean parser_settings; try { - parser_settings = componentManager.getFeature(PARSER_SETTINGS); + parser_settings = componentManager.getFeature(PARSER_SETTINGS); } catch (XMLConfigurationException e){ parser_settings = true; } if (!parser_settings || !fSettingsChanged){ + // need to reprocess JAXP schema sources + fJAXPProcessed = false; // reinitialize grammar bucket initGrammarBucket(); - return; - } - + return; + } + // get registered entity manager to be able to resolve JAXP schema-source property: - // Note: in case XMLSchemaValidator has created the loader, + // Note: in case XMLSchemaValidator has created the loader, // the entity manager property is null - fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER); - + fEntityManager = (XMLEntityManager)componentManager.getProperty(ENTITY_MANAGER); + // get the error reporter fErrorReporter = (XMLErrorReporter)componentManager.getProperty(ERROR_REPORTER); - + boolean psvi = true; try { psvi = componentManager.getFeature(AUGMENT_PSVI); } catch (XMLConfigurationException e) { psvi = false; } - + if (!psvi) { fDeclPool.reset(); fCMBuilder.setDeclPool(fDeclPool); @@ -962,7 +973,7 @@ fCMBuilder.setDeclPool(null); fSchemaHandler.setDeclPool(null); } - + // get schema location properties try { fExternalSchemas = (String) componentManager.getProperty(SCHEMA_LOCATION); @@ -976,12 +987,12 @@ try { fJAXPSource = componentManager.getProperty(JAXP_SCHEMA_SOURCE); fJAXPProcessed = false; - + } catch (XMLConfigurationException e) { fJAXPSource = null; fJAXPProcessed = false; } - + // clear grammars, and put the one for schema namespace there try { fGrammarPool = (XMLGrammarPool) componentManager.getProperty(XMLGRAMMAR_POOL); @@ -995,7 +1006,7 @@ fErrorReporter.setFeature(CONTINUE_AFTER_FATAL_ERROR, fatalError); } catch (XMLConfigurationException e) { } - // set full validation to false + // set full validation to false try { fIsCheckedFully = componentManager.getFeature(SCHEMA_FULL_CHECKING); } @@ -1009,9 +1020,9 @@ catch (XMLConfigurationException e) { fSchemaHandler.setGenerateSyntheticAnnotations(false); } - fSchemaHandler.reset(componentManager); + fSchemaHandler.reset(componentManager); } - + private void initGrammarBucket(){ if(fGrammarPool != null) { Grammar [] initialGrammars = fGrammarPool.retrieveInitialGrammarSet(XMLGrammarDescription.XML_SCHEMA); @@ -1028,15 +1039,15 @@ } } } - - + + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.XSLoader#getConfig() */ public DOMConfiguration getConfig() { return this; } - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.XSLoader#load(org.w3c.dom.ls.LSInput) */ @@ -1049,7 +1060,7 @@ return null; } } - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadInputList(com.sun.org.apache.xerces.internal.xs.DOMInputList) */ @@ -1069,7 +1080,7 @@ } return new XSModelImpl(gs); } - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadURI(java.lang.String) */ @@ -1083,7 +1094,7 @@ return null; } } - + /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.XSLoader#loadURIList(com.sun.org.apache.xerces.internal.xs.StringList) */ @@ -1104,7 +1115,7 @@ } return new XSModelImpl(gs); } - + void reportDOMFatalError(Exception e) { if (fErrorHandler != null) { DOMErrorImpl error = new DOMErrorImpl(); @@ -1114,7 +1125,7 @@ fErrorHandler.getErrorHandler().handleError(error); } } - + /* (non-Javadoc) * @see DOMConfiguration#canSetParameter(String, Object) */ @@ -1129,9 +1140,9 @@ name.equals(GENERATE_SYNTHETIC_ANNOTATIONS) || name.equals(HONOUR_ALL_SCHEMALOCATIONS)) { return true; - + } - return false; + return false; } if (name.equals(Constants.DOM_ERROR_HANDLER) || name.equals(Constants.DOM_RESOURCE_RESOLVER) || @@ -1147,19 +1158,19 @@ } return false; } - + /* (non-Javadoc) * @see DOMConfiguration#getParameter(String) */ public Object getParameter(String name) throws DOMException { - + if (name.equals(Constants.DOM_ERROR_HANDLER)){ return (fErrorHandler != null) ? fErrorHandler.getErrorHandler() : null; } else if (name.equals(Constants.DOM_RESOURCE_RESOLVER)) { return (fResourceResolver != null) ? fResourceResolver.getEntityResolver() : null; } - + try { boolean feature = getFeature(name); return (feature) ? Boolean.TRUE : Boolean.FALSE; @@ -1178,7 +1189,7 @@ } } } - + /* (non-Javadoc) * @see DOMConfiguration#getParameterNames() */ @@ -1203,11 +1214,11 @@ v.add(VALIDATE_ANNOTATIONS); v.add(GENERATE_SYNTHETIC_ANNOTATIONS); v.add(HONOUR_ALL_SCHEMALOCATIONS); - fRecognizedParameters = new DOMStringListImpl(v); + fRecognizedParameters = new DOMStringListImpl(v); } return fRecognizedParameters; } - + /* (non-Javadoc) * @see DOMConfiguration#setParameter(String, Object) */ @@ -1246,14 +1257,14 @@ throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); } return; - + } if (name.equals(Constants.DOM_RESOURCE_RESOLVER)) { if (value instanceof LSResourceResolver) { try { fResourceResolver = new DOMEntityResolverWrapper((LSResourceResolver) value); setEntityResolver(fResourceResolver); - } + } catch (XMLConfigurationException e) {} } else { // REVISIT: type mismatch @@ -1266,33 +1277,33 @@ } return; } - + try { setProperty(name, value); } catch (Exception ex) { - + String msg = DOMMessageFormatter.formatMessage( DOMMessageFormatter.DOM_DOMAIN, "FEATURE_NOT_SUPPORTED", new Object[] { name }); throw new DOMException(DOMException.NOT_SUPPORTED_ERR, msg); - + } - + } - - XMLInputSource dom2xmlInputSource(LSInput is) { + + XMLInputSource dom2xmlInputSource(LSInput is) { // need to wrap the LSInput with an XMLInputSource XMLInputSource xis = null; - + /** * An LSParser looks at inputs specified in LSInput in * the following order: characterStream, byteStream, * stringData, systemId, publicId. For consistency * have the same behaviour for XSLoader. */ - + // check whether there is a Reader // according to DOM, we need to treat such reader as "UTF-16". if (is.getCharacterStream() != null) { @@ -1318,8 +1329,9 @@ xis = new XMLInputSource(is.getPublicId(), is.getSystemId(), is.getBaseURI()); } - + return xis; } + +} // XMLGrammarLoader -} // XMLGrammarLoader
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Wed Sep 28 17:10:18 2011 +0100 @@ -104,7 +104,7 @@ * @author Elena Litani IBM * @author Andy Clark IBM * @author Neeraj Bajaj, Sun Microsystems, inc. - * @version $Id: XMLSchemaValidator.java,v 1.11 2009/07/28 15:18:12 spericas Exp $ + * @version $Id: XMLSchemaValidator.java,v 1.14 2010/08/10 00:17:49 joehw Exp $ */ public class XMLSchemaValidator implements XMLComponent, XMLDocumentFilter, FieldActivator, RevalidationHandler { @@ -761,6 +761,7 @@ text = handleCharacters(text); if (fSawOnlyWhitespaceInElementContent) { + fSawOnlyWhitespaceInElementContent = false; if (!reportWhitespace) { ignorableWhitespace(text, augs); return; @@ -3450,34 +3451,19 @@ return; } - // do we have enough values? + // Validation Rule: Identity-constraint Satisfied + // 4.2 If the {identity-constraint category} is key, then all of the following must be true: + // 4.2.1 The target node set and the qualified node set are equal, that is, every member of the + // target node set is also a member of the qualified node set and vice versa. + // + // If the IDC is a key check whether we have all the fields. if (fValuesCount != fFieldCount) { - switch (fIdentityConstraint.getCategory()) { - case IdentityConstraint.IC_UNIQUE : - { - String code = "UniqueNotEnoughValues"; - String ename = fIdentityConstraint.getElementName(); - reportSchemaError(code, new Object[] { ename }); - break; - } - case IdentityConstraint.IC_KEY : - { - String code = "KeyNotEnoughValues"; - UniqueOrKey key = (UniqueOrKey) fIdentityConstraint; - String ename = fIdentityConstraint.getElementName(); - String kname = key.getIdentityConstraintName(); - reportSchemaError(code, new Object[] { ename, kname }); - break; - } - case IdentityConstraint.IC_KEYREF : - { - String code = "KeyRefNotEnoughValues"; - KeyRef keyref = (KeyRef) fIdentityConstraint; - String ename = fIdentityConstraint.getElementName(); - String kname = (keyref.getKey()).getIdentityConstraintName(); - reportSchemaError(code, new Object[] { ename, kname }); - break; - } + if (fIdentityConstraint.getCategory() == IdentityConstraint.IC_KEY) { + String code = "KeyNotEnoughValues"; + UniqueOrKey key = (UniqueOrKey) fIdentityConstraint; + String ename = fIdentityConstraint.getElementName(); + String kname = key.getIdentityConstraintName(); + reportSchemaError(code, new Object[] { ename, kname }); } return; }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/XSComplexTypeDecl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/XSComplexTypeDecl.java Wed Sep 28 17:10:18 2011 +0100 @@ -32,10 +32,11 @@ * The XML representation for a complexType * schema component is a <complexType> element information item * - * @xerces.internal + * @xerces.internal * * @author Elena Litani, IBM * @author Sandy Gao, IBM + * @version $Id: XSComplexTypeDecl.java,v 1.6 2010/04/23 01:42:43 joehw Exp $ */ public class XSComplexTypeDecl implements XSComplexTypeDefinition, TypeInfo { @@ -74,7 +75,7 @@ XSParticleDecl fParticle = null; // if there is a particle, the content model corresponding to that particle - XSCMValidator fCMValidator = null; + volatile XSCMValidator fCMValidator = null; // list of annotations affiliated with this type XSObjectListImpl fAnnotations = null; @@ -85,15 +86,15 @@ static final int DERIVATION_EXTENSION = 2; static final int DERIVATION_UNION = 4; static final int DERIVATION_LIST = 8; - + public XSComplexTypeDecl() { // do-nothing constructor for now. } public void setValues(String name, String targetNamespace, - XSTypeDefinition baseType, short derivedBy, short schemaFinal, + XSTypeDefinition baseType, short derivedBy, short schemaFinal, short block, short contentType, - boolean isAbstract, XSAttributeGroupDecl attrGrp, + boolean isAbstract, XSAttributeGroupDecl attrGrp, XSSimpleType simpleType, XSParticleDecl particle, XSObjectListImpl annotations) { fTargetNamespace = targetNamespace; @@ -151,10 +152,13 @@ fMiscFlags |= CT_IS_ANONYMOUS; } - public synchronized XSCMValidator getContentModel(CMBuilder cmBuilder) { + public XSCMValidator getContentModel(CMBuilder cmBuilder) { if (fCMValidator == null) - fCMValidator = cmBuilder.getContentModel(this); - + synchronized (this) { + if (fCMValidator == null) { + fCMValidator = cmBuilder.getContentModel(this); + } + } return fCMValidator; } @@ -166,12 +170,12 @@ } public String toString() { - StringBuffer str = new StringBuffer(); + StringBuilder str = new StringBuilder(192); appendTypeInfo(str); return str.toString(); } - void appendTypeInfo(StringBuffer str) { + void appendTypeInfo(StringBuilder str) { String contentType[] = {"EMPTY", "SIMPLE", "ELEMENT", "MIXED"}; String derivedBy[] = {"EMPTY", "EXTENSION", "RESTRICTION"}; @@ -237,14 +241,14 @@ * Checks if a type is derived from another given the the name, namespace * and derivation method. See: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * + * * @param ancestorNS * The namspace of the ancestor type declaration * @param ancestorName * The name of the ancestor type declaration * @param derivation * The derivation method - * + * * @return boolean True if the ancestor type is derived from the reference * type by the specifiied derivation method. */ @@ -253,16 +257,16 @@ // ancestor is null, retur false if (ancestorName == null) return false; - + // ancestor is anyType, return true if (ancestorNS != null && ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) && ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE) - && (derivationMethod == DERIVATION_RESTRICTION + && (derivationMethod == DERIVATION_RESTRICTION && derivationMethod == DERIVATION_EXTENSION)) { return true; } - + // restriction if ((derivationMethod & DERIVATION_RESTRICTION) != 0) { if (isDerivedByRestriction(ancestorNS, ancestorName, @@ -270,7 +274,7 @@ return true; } } - + // extension if ((derivationMethod & DERIVATION_EXTENSION) != 0) { if (isDerivedByExtension(ancestorNS, ancestorName, @@ -278,7 +282,7 @@ return true; } } - + // list or union if ((((derivationMethod & DERIVATION_LIST) != 0) || ((derivationMethod & DERIVATION_UNION) != 0)) && ((derivationMethod & DERIVATION_RESTRICTION) == 0) @@ -289,10 +293,10 @@ ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE; } - if(!(fName.equals(SchemaSymbols.ATTVAL_ANYTYPE) + if(!(fName.equals(SchemaSymbols.ATTVAL_ANYTYPE) && fTargetNamespace.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA))){ if (fBaseType != null && fBaseType instanceof XSSimpleTypeDecl) { - + return ((XSSimpleTypeDecl) fBaseType).isDOMDerivedFrom(ancestorNS, ancestorName, derivationMethod); } else if (fBaseType != null @@ -302,25 +306,25 @@ } } } - + // If the value of the parameter is 0 i.e. no bit (corresponding to - // restriction, list, extension or union) is set to 1 for the - // derivationMethod parameter. + // restriction, list, extension or union) is set to 1 for the + // derivationMethod parameter. if (((derivationMethod & DERIVATION_EXTENSION) == 0) && (((derivationMethod & DERIVATION_RESTRICTION) == 0) - && ((derivationMethod & DERIVATION_LIST) == 0) + && ((derivationMethod & DERIVATION_LIST) == 0) && ((derivationMethod & DERIVATION_UNION) == 0))) { return isDerivedByAny(ancestorNS, ancestorName, derivationMethod, this); } return false; } - + /** * Checks if a type is derived from another by any combination of * restriction, list ir union. See: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * + * * @param ancestorNS * The namspace of the ancestor type declaration * @param ancestorName @@ -329,7 +333,7 @@ * A short indication the method of derivation * @param type * The reference type definition - * + * * @return boolean True if the type is derived by any method for the * reference type */ @@ -338,15 +342,15 @@ XSTypeDefinition oldType = null; boolean derivedFrom = false; while (type != null && type != oldType) { - + // If the ancestor type is reached or is the same as this type. if ((ancestorName.equals(type.getName())) - && ((ancestorNS == null && type.getNamespace() == null) + && ((ancestorNS == null && type.getNamespace() == null) || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) { derivedFrom = true; break; } - + // Check if this type is derived from the base by restriction or // extension if (isDerivedByRestriction(ancestorNS, ancestorName, @@ -359,14 +363,14 @@ oldType = type; type = type.getBaseType(); } - + return derivedFrom; } - + /** * Checks if a type is derived from another by restriction. See: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * + * * @param ancestorNS * The namspace of the ancestor type declaration * @param ancestorName @@ -375,32 +379,32 @@ * A short indication the method of derivation * * @param type * The reference type definition - * + * * @return boolean True if the type is derived by restriciton for the * reference type */ private boolean isDerivedByRestriction(String ancestorNS, String ancestorName, int derivationMethod, XSTypeDefinition type) { - + XSTypeDefinition oldType = null; while (type != null && type != oldType) { - + // ancestor is anySimpleType, return false if (ancestorNS != null && ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) && ancestorName.equals(SchemaSymbols.ATTVAL_ANYSIMPLETYPE)) { return false; } - + // if the name and namespace of this type is the same as the // ancestor return true if ((ancestorName.equals(type.getName())) - && (ancestorNS != null && ancestorNS.equals(type.getNamespace())) + && (ancestorNS != null && ancestorNS.equals(type.getNamespace())) || ((type.getNamespace() == null && ancestorNS == null))) { - + return true; } - + // If the base type is a complexType with simpleContent if (type instanceof XSSimpleTypeDecl) { if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) @@ -419,16 +423,16 @@ } oldType = type; type = type.getBaseType(); - + } - + return false; } - + /** * Checks if a type is derived from another by extension. See: * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#TypeInfo-isDerivedFrom - * + * * @param ancestorNS * The namspace of the ancestor type declaration * @param ancestorName @@ -437,13 +441,13 @@ * A short indication the method of derivation * @param type * The reference type definition - * + * * @return boolean True if the type is derived by extension for the * reference type */ private boolean isDerivedByExtension(String ancestorNS, String ancestorName, int derivationMethod, XSTypeDefinition type) { - + boolean extension = false; XSTypeDefinition oldType = null; while (type != null && type != oldType) { @@ -455,21 +459,21 @@ && SchemaSymbols.ATTVAL_ANYTYPE.equals(type.getName())) { break; } - + if ((ancestorName.equals(type.getName())) - && ((ancestorNS == null && type.getNamespace() == null) + && ((ancestorNS == null && type.getNamespace() == null) || (ancestorNS != null && ancestorNS.equals(type.getNamespace())))) { // returns true if atleast one derivation step was extension return extension; } - + // If the base type is a complexType with simpleContent if (type instanceof XSSimpleTypeDecl) { if (ancestorNS.equals(SchemaSymbols.URI_SCHEMAFORSCHEMA) && ancestorName.equals(SchemaSymbols.ATTVAL_ANYTYPE)) { ancestorName = SchemaSymbols.ATTVAL_ANYSIMPLETYPE; } - + // derivationMethod extension will always return false for a // simpleType, // we treat it like a restriction @@ -483,7 +487,7 @@ & ((XSSimpleTypeDecl) type).isDOMDerivedFrom( ancestorNS, ancestorName, derivationMethod); } - + } else { // If the base type is a complex type // At least one derivation step upto the ancestor type should be @@ -495,12 +499,12 @@ oldType = type; type = type.getBaseType(); } - + return false; } - - - + + + public void reset(){ fName = null; fTargetNamespace = null; @@ -670,14 +674,14 @@ public XSObjectList getAnnotations() { return fAnnotations; } - - /** - * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() - */ - public XSNamespaceItem getNamespaceItem() { + + /** + * @see com.sun.org.apache.xerces.internal.xs.XSObject#getNamespaceItem() + */ + public XSNamespaceItem getNamespaceItem() { // REVISIT: implement - return null; - } + return null; + } /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xs.XSComplexTypeDefinition#getAttributeUse(java.lang.String, java.lang.String)
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMBuilder.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMBuilder.java Wed Sep 28 17:10:18 2011 +0100 @@ -36,7 +36,7 @@ * @author Elena Litani, IBM * @author Sandy Gao, IBM * - * @version $Id: CMBuilder.java,v 1.9 2009/08/10 16:52:55 spericas Exp $ + * @version $Id: CMBuilder.java,v 1.11 2010/08/06 23:49:43 joehw Exp $ */ public class CMBuilder { @@ -129,7 +129,7 @@ fLeafCount = 0; fParticleCount = 0; // convert particle tree to CM tree - CMNode node = buildSyntaxTree(particle, true); + CMNode node = useRepeatingLeafNodes(particle) ? buildCompactSyntaxTree(particle) : buildSyntaxTree(particle, true); if (node == null) return null; // build DFA content model from the CM tree @@ -323,4 +323,128 @@ return node; } + + // A special version of buildSyntaxTree() which builds a compact syntax tree + // containing compound leaf nodes which carry occurence information. This method + // for building the syntax tree is chosen over buildSyntaxTree() when + // useRepeatingLeafNodes() returns true. + private CMNode buildCompactSyntaxTree(XSParticleDecl particle) { + int maxOccurs = particle.fMaxOccurs; + int minOccurs = particle.fMinOccurs; + short type = particle.fType; + CMNode nodeRet = null; + + if ((type == XSParticleDecl.PARTICLE_WILDCARD) || + (type == XSParticleDecl.PARTICLE_ELEMENT)) { + return buildCompactSyntaxTree2(particle, minOccurs, maxOccurs); + } + else if (type == XSParticleDecl.PARTICLE_MODELGROUP) { + XSModelGroupImpl group = (XSModelGroupImpl)particle.fValue; + if (group.fParticleCount == 1 && (minOccurs != 1 || maxOccurs != 1)) { + return buildCompactSyntaxTree2(group.fParticles[0], minOccurs, maxOccurs); + } + else { + CMNode temp = null; + + // when the model group is a choice of more than one particles, but + // only one of the particle is not empty, (for example + // <choice> + // <sequence/> + // <element name="e"/> + // </choice> + // ) we can't not return that one particle ("e"). instead, we should + // treat such particle as optional ("e?"). + // the following int variable keeps track of the number of non-empty children + int count = 0; + for (int i = 0; i < group.fParticleCount; i++) { + // first convert each child to a CM tree + temp = buildCompactSyntaxTree(group.fParticles[i]); + // then combine them using binary operation + if (temp != null) { + ++count; + if (nodeRet == null) { + nodeRet = temp; + } + else { + nodeRet = fNodeFactory.getCMBinOpNode(group.fCompositor, nodeRet, temp); + } + } + } + if (nodeRet != null) { + // when the group is "choice" and the group has one or more empty children, + // we need to create a zero-or-one (optional) node for the non-empty particles. + if (group.fCompositor == XSModelGroupImpl.MODELGROUP_CHOICE && count < group.fParticleCount) { + nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, nodeRet); + } + } + } + } + return nodeRet; + } + + private CMNode buildCompactSyntaxTree2(XSParticleDecl particle, int minOccurs, int maxOccurs) { + // Convert element and wildcard particles to leaf nodes. Wrap repeating particles in a CMUniOpNode. + CMNode nodeRet = null; + if (minOccurs == 1 && maxOccurs == 1) { + nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue, fParticleCount++, fLeafCount++); + } + else if (minOccurs == 0 && maxOccurs == 1) { + // zero or one + nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue, fParticleCount++, fLeafCount++); + nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_ONE, nodeRet); + } + else if (minOccurs == 0 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) { + // zero or more + nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue, fParticleCount++, fLeafCount++); + nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_MORE, nodeRet); + } + else if (minOccurs == 1 && maxOccurs==SchemaSymbols.OCCURRENCE_UNBOUNDED) { + // one or more + nodeRet = fNodeFactory.getCMLeafNode(particle.fType, particle.fValue, fParticleCount++, fLeafCount++); + nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, nodeRet); + } + else { + // {n,m}: Instead of expanding this out, create a compound leaf node which carries the + // occurence information and wrap it in the appropriate CMUniOpNode. + nodeRet = fNodeFactory.getCMRepeatingLeafNode(particle.fType, particle.fValue, minOccurs, maxOccurs, fParticleCount++, fLeafCount++); + if (minOccurs == 0) { + nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ZERO_OR_MORE, nodeRet); + } + else { + nodeRet = fNodeFactory.getCMUniOpNode(XSParticleDecl.PARTICLE_ONE_OR_MORE, nodeRet); + } + } + return nodeRet; + } + + // This method checks if this particle can be transformed into a compact syntax + // tree containing compound leaf nodes which carry occurence information. Currently + // it returns true if each model group has minOccurs/maxOccurs == 1 or + // contains only one element/wildcard particle with minOccurs/maxOccurs == 1. + private boolean useRepeatingLeafNodes(XSParticleDecl particle) { + int maxOccurs = particle.fMaxOccurs; + int minOccurs = particle.fMinOccurs; + short type = particle.fType; + + if (type == XSParticleDecl.PARTICLE_MODELGROUP) { + XSModelGroupImpl group = (XSModelGroupImpl) particle.fValue; + if (minOccurs != 1 || maxOccurs != 1) { + if (group.fParticleCount == 1) { + XSParticleDecl particle2 = (XSParticleDecl) group.fParticles[0]; + short type2 = particle2.fType; + return ((type2 == XSParticleDecl.PARTICLE_ELEMENT || + type2 == XSParticleDecl.PARTICLE_WILDCARD) && + particle2.fMinOccurs == 1 && + particle2.fMaxOccurs == 1); + } + return (group.fParticleCount == 0); + } + for (int i = 0; i < group.fParticleCount; ++i) { + if (!useRepeatingLeafNodes(group.fParticles[i])) { + return false; + } + } + } + return true; + } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/CMNodeFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -35,6 +35,7 @@ * * @author Neeraj Bajaj * + * @version $Id: CMNodeFactory.java,v 1.6 2010/08/06 23:49:43 joehw Exp $ */ public class CMNodeFactory { @@ -89,14 +90,23 @@ }//reset() public CMNode getCMLeafNode(int type, Object leaf, int id, int position) { + nodeCountCheck(); return new XSCMLeaf(type, leaf, id, position) ; } + public CMNode getCMRepeatingLeafNode(int type, Object leaf, + int minOccurs, int maxOccurs, int id, int position) { + nodeCountCheck(); + return new XSCMRepeatingLeaf(type, leaf, minOccurs, maxOccurs, id, position); + } + public CMNode getCMUniOpNode(int type, CMNode childNode) { + nodeCountCheck(); return new XSCMUniOp(type, childNode) ; } public CMNode getCMBinOpNode(int type, CMNode leftNode, CMNode rightNode) { + nodeCountCheck() ; return new XSCMBinOp(type, leftNode, rightNode) ; } @@ -138,7 +148,7 @@ // Xerces properties if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { - final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); + final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); if (suffixLength == Constants.SECURITY_MANAGER_PROPERTY.length() && propertyId.endsWith(Constants.SECURITY_MANAGER_PROPERTY)) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/XSCMRepeatingLeaf.java Wed Sep 28 17:10:18 2011 +0100 @@ -0,0 +1,52 @@ +/* + * reserved comment block + * DO NOT REMOVE OR ALTER! + */ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.sun.org.apache.xerces.internal.impl.xs.models; + +/** + * A compound content model leaf node which carries occurence information. + * + * @xerces.internal + * + * @author Michael Glavassevich, IBM + * @version $Id: XSCMRepeatingLeaf.java,v 1.1 2010/08/06 23:49:43 joehw Exp $ + */ +public final class XSCMRepeatingLeaf extends XSCMLeaf { + + private final int fMinOccurs; + private final int fMaxOccurs; + + public XSCMRepeatingLeaf(int type, Object leaf, + int minOccurs, int maxOccurs, int id, int position) { + super(type, leaf, id, position); + fMinOccurs = minOccurs; + fMaxOccurs = maxOccurs; + } + + final int getMinOccurs() { + return fMinOccurs; + } + + final int getMaxOccurs() { + return fMaxOccurs; + } +} +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/models/XSDFACM.java Wed Sep 28 17:10:18 2011 +0100 @@ -23,6 +23,7 @@ import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.impl.dtd.models.CMNode; import com.sun.org.apache.xerces.internal.impl.dtd.models.CMStateSet; +import com.sun.org.apache.xerces.internal.impl.xs.SchemaSymbols; import com.sun.org.apache.xerces.internal.impl.xs.SubstitutionGroupHandler; import com.sun.org.apache.xerces.internal.impl.xs.XSElementDecl; import com.sun.org.apache.xerces.internal.impl.xs.XSParticleDecl; @@ -33,6 +34,7 @@ import java.util.Vector; import java.util.ArrayList; +import java.util.HashMap; /** * DFAContentModel is the implementation of XSCMValidator that does @@ -43,7 +45,7 @@ * @xerces.internal * * @author Neil Graham, IBM - * @version $Id: XSDFACM.java,v 1.7 2009/07/28 15:18:12 spericas Exp $ + * @version $Id: XSDFACM.java,v 1.9 2010/08/06 23:49:43 joehw Exp $ */ public class XSDFACM implements XSCMValidator { @@ -137,6 +139,27 @@ * positions in the second dimension of the transition table. */ private int fTransTable[][] = null; + /** + * Array containing occurence information for looping states + * which use counters to check minOccurs/maxOccurs. + */ + private Occurence [] fCountingStates = null; + static final class Occurence { + final int minOccurs; + final int maxOccurs; + final int elemIndex; + public Occurence (XSCMRepeatingLeaf leaf, int elemIndex) { + minOccurs = leaf.getMinOccurs(); + maxOccurs = leaf.getMaxOccurs(); + this.elemIndex = elemIndex; + } + public String toString() { + return "minOccurs=" + minOccurs + + ";maxOccurs=" + + ((maxOccurs != SchemaSymbols.OCCURRENCE_UNBOUNDED) + ? Integer.toString(maxOccurs) : "unbounded"); + } + } /** * The number of valid entries in the transition table, and in the other @@ -282,7 +305,7 @@ } } else if (type == XSParticleDecl.PARTICLE_WILDCARD) { - if(((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) { + if (((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) { matchingDecl = fElemMap[elemIndex]; // Increment counter if constant space algorithm applies if (fElemMapCounter[elemIndex] >= 0) { @@ -301,6 +324,66 @@ return findMatchingDecl(curElem, subGroupHandler); } + if (fCountingStates != null) { + Occurence o = fCountingStates[curState]; + if (o != null) { + if (curState == nextState) { + if (++state[2] > o.maxOccurs && + o.maxOccurs != SchemaSymbols.OCCURRENCE_UNBOUNDED) { + // It's likely that we looped too many times on the current state + // however it's possible that we actually matched another particle + // which allows the same name. + // + // Consider: + // + // <xs:sequence> + // <xs:element name="foo" type="xs:string" minOccurs="3" maxOccurs="3"/> + // <xs:element name="foo" type="xs:string" fixed="bar"/> + // </xs:sequence> + // + // and + // + // <xs:sequence> + // <xs:element name="foo" type="xs:string" minOccurs="3" maxOccurs="3"/> + // <xs:any namespace="##any" processContents="skip"/> + // </xs:sequence> + // + // In the DFA there will be two transitions from the current state which + // allow "foo". Note that this is not a UPA violation. The ambiguity of which + // transition to take is resolved by the current value of the counter. Since + // we've already seen enough instances of the first "foo" perhaps there is + // another element declaration or wildcard deeper in the element map which + // matches. + return findMatchingDecl(curElem, state, subGroupHandler, elemIndex); + } + } + else if (state[2] < o.minOccurs) { + // not enough loops on the current state. + state[1] = state[0]; + state[0] = XSCMValidator.FIRST_ERROR; + return findMatchingDecl(curElem, subGroupHandler); + } + else { + // Exiting a counting state. If we're entering a new + // counting state, reset the counter. + o = fCountingStates[nextState]; + if (o != null) { + state[2] = (elemIndex == o.elemIndex) ? 1 : 0; + } + } + } + else { + o = fCountingStates[nextState]; + if (o != null) { + // Entering a new counting state. Reset the counter. + // If we've already seen one instance of the looping + // particle set the counter to 1, otherwise set it + // to 0. + state[2] = (elemIndex == o.elemIndex) ? 1 : 0; + } + } + } + state[0] = nextState; return matchingDecl; } // oneTransition(QName, int[], SubstitutionGroupHandler): Object @@ -323,24 +406,79 @@ } return null; - } + } // findMatchingDecl(QName, SubstitutionGroupHandler): Object + + Object findMatchingDecl(QName curElem, int[] state, SubstitutionGroupHandler subGroupHandler, int elemIndex) { + + int curState = state[0]; + int nextState = 0; + Object matchingDecl = null; + + while (++elemIndex < fElemMapSize) { + nextState = fTransTable[curState][elemIndex]; + if (nextState == -1) + continue; + int type = fElemMapType[elemIndex] ; + if (type == XSParticleDecl.PARTICLE_ELEMENT) { + matchingDecl = subGroupHandler.getMatchingElemDecl(curElem, (XSElementDecl)fElemMap[elemIndex]); + if (matchingDecl != null) { + break; + } + } + else if (type == XSParticleDecl.PARTICLE_WILDCARD) { + if (((XSWildcardDecl)fElemMap[elemIndex]).allowNamespace(curElem.uri)) { + matchingDecl = fElemMap[elemIndex]; + break; + } + } + } + + // if we still can't find a match, set the state to FIRST_ERROR and return null + if (elemIndex == fElemMapSize) { + state[1] = state[0]; + state[0] = XSCMValidator.FIRST_ERROR; + return findMatchingDecl(curElem, subGroupHandler); + } + + // if we found a match, set the next state and reset the + // counter if the next state is a counting state. + state[0] = nextState; + final Occurence o = fCountingStates[nextState]; + if (o != null) { + state[2] = (elemIndex == o.elemIndex) ? 1 : 0; + } + return matchingDecl; + } // findMatchingDecl(QName, int[], SubstitutionGroupHandler, int): Object // This method returns the start states of the content model. public int[] startContentModel() { - int[] val = new int[2]; - val[0] = 0; // Clear all constant space algorithm counters in use for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { if (fElemMapCounter[elemIndex] != -1) { fElemMapCounter[elemIndex] = 0; } } - return val; + // [0] : the current state + // [1] : if [0] is an error state then the + // last valid state before the error + // [2] : occurence counter for counting states + return new int [3]; } // startContentModel():int[] // this method returns whether the last state was a valid final state public boolean endContentModel(int[] state) { - return fFinalStateFlags[state[0]]; + final int curState = state[0]; + if (fFinalStateFlags[curState]) { + if (fCountingStates != null) { + Occurence o = fCountingStates[curState]; + if (o != null && state[2] < o.minOccurs) { + // not enough loops on the current state to be considered final. + return false; + } + } + return true; + } + return false; } // endContentModel(int[]): boolean // Killed off whatCanGoHere; we may need it for DOM canInsert(...) etc., @@ -461,7 +599,8 @@ fElemMapCounterUpperBound = new int[fLeafCount]; fElemMapSize = 0; - + Occurence [] elemOccurenceMap = null; + for (int outIndex = 0; outIndex < fLeafCount; outIndex++) { // optimization from Henry Zongaro: //fElemMap[outIndex] = new Object (); @@ -476,12 +615,19 @@ // If it was not in the list, then add it, if not the EOC node if (inIndex == fElemMapSize) { - fElemMap[fElemMapSize] = fLeafList[outIndex].getLeaf(); + XSCMLeaf leaf = fLeafList[outIndex]; + fElemMap[fElemMapSize] = leaf.getLeaf(); + if (leaf instanceof XSCMRepeatingLeaf) { + if (elemOccurenceMap == null) { + elemOccurenceMap = new Occurence[fLeafCount]; + } + elemOccurenceMap[fElemMapSize] = new Occurence((XSCMRepeatingLeaf) leaf, fElemMapSize); + } + fElemMapType[fElemMapSize] = fLeafListType[outIndex]; fElemMapId[fElemMapSize] = id; // Init counters and bounds for a{n,m} algorithm - XSCMLeaf leaf = fLeafList[outIndex]; int[] bounds = (int[]) leaf.getUserData(); if (bounds != null) { fElemMapCounter[fElemMapSize] = 0; @@ -573,7 +719,7 @@ * a large content model such as, "(t001+|t002+|.... |t500+)". */ - java.util.Hashtable stateTable = new java.util.Hashtable(); + HashMap stateTable = new HashMap(); /* Optimization(Jan, 2001) */ @@ -692,11 +838,9 @@ int[][] newTransTable = new int[newSize][]; // Copy over all of the existing content - for (int expIndex = 0; expIndex < curArraySize; expIndex++) { - newToDo[expIndex] = statesToDo[expIndex]; - newFinalFlags[expIndex] = fFinalStateFlags[expIndex]; - newTransTable[expIndex] = fTransTable[expIndex]; - } + System.arraycopy(statesToDo, 0, newToDo, 0, curArraySize); + System.arraycopy(fFinalStateFlags, 0, newFinalFlags, 0, curArraySize); + System.arraycopy(fTransTable, 0, newTransTable, 0, curArraySize); // Store the new array size curArraySize = newSize; @@ -709,6 +853,23 @@ } // + // Fill in the occurence information for each looping state + // if we're using counters. + // + if (elemOccurenceMap != null) { + fCountingStates = new Occurence[curState]; + for (int i = 0; i < curState; ++i) { + int [] transitions = fTransTable[i]; + for (int j = 0; j < transitions.length; ++j) { + if (i == transitions[j]) { + fCountingStates[i] = elemOccurenceMap[j]; + break; + } + } + } + } + + // // And now we can say bye bye to the temp representation since we've // built the DFA. // @@ -945,10 +1106,26 @@ if (fTransTable[i][j] != -1 && fTransTable[i][k] != -1) { if (conflictTable[j][k] == 0) { - conflictTable[j][k] = XSConstraints.overlapUPA - (fElemMap[j],fElemMap[k], - subGroupHandler) ? - (byte)1 : (byte)-1; + if (XSConstraints.overlapUPA + (fElemMap[j], fElemMap[k], + subGroupHandler)) { + if (fCountingStates != null) { + Occurence o = fCountingStates[i]; + // If "i" is a counting state and exactly one of the transitions + // loops back to "i" then the two particles do not overlap if + // minOccurs == maxOccurs. + if (o != null && + fTransTable[i][j] == i ^ fTransTable[i][k] == i && + o.minOccurs == o.maxOccurs) { + conflictTable[j][k] = (byte) -1; + continue; + } + } + conflictTable[j][k] = (byte) 1; + } + else { + conflictTable[j][k] = (byte) -1; + } } } } @@ -996,11 +1173,32 @@ int curState = state[0]; if (curState < 0) curState = state[1]; + Occurence o = (fCountingStates != null) ? + fCountingStates[curState] : null; + int count = state[2]; Vector ret = new Vector(); for (int elemIndex = 0; elemIndex < fElemMapSize; elemIndex++) { - if (fTransTable[curState][elemIndex] != -1) + int nextState = fTransTable[curState][elemIndex]; + if (nextState != -1) { + if (o != null) { + if (curState == nextState) { + // Do not include transitions which loop back to the + // current state if we've looped the maximum number + // of times or greater. + if (count >= o.maxOccurs && + o.maxOccurs != SchemaSymbols.OCCURRENCE_UNBOUNDED) { + continue; + } + } + // Do not include transitions which advance past the + // current state if we have not looped enough times. + else if (count < o.minOccurs) { + continue; + } + } ret.addElement(fElemMap[elemIndex]); + } } return ret; }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/opti/SchemaDOMParser.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/opti/SchemaDOMParser.java Wed Sep 28 17:10:18 2011 +0100 @@ -41,46 +41,51 @@ import org.w3c.dom.Document; /** - * @xerces.internal - * + * @xerces.internal + * * @author Rahul Srivastava, Sun Microsystems Inc. * @author Sandy Gao, IBM * + * @version $Id: SchemaDOMParser.java,v 1.6 2010/07/23 02:09:29 joehw Exp $ */ public class SchemaDOMParser extends DefaultXMLDocumentHandler { - + // // Data // - + /** Property identifier: error reporter. */ public static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; - + /** Feature identifier: generate synthetic annotations. */ public static final String GENERATE_SYNTHETIC_ANNOTATION = Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE; - + // the locator containing line/column information protected XMLLocator fLocator; - + // namespace context, needed for producing // representations of annotations protected NamespaceContext fNamespaceContext = null; - + SchemaDOM schemaDOM; - + XMLParserConfiguration config; - + // // Constructors // - + /** Default constructor. */ public SchemaDOMParser(XMLParserConfiguration config) { this.config = config; + config.setDocumentHandler(this); + config.setDTDHandler(this); + config.setDTDContentModelHandler(this); + } - + // where an annotation element itself begins // -1 means not in an annotation's scope private int fAnnotationDepth = -1; @@ -91,25 +96,25 @@ private int fDepth = -1; // Use to report the error when characters are not allowed. XMLErrorReporter fErrorReporter; - + // fields for generate-synthetic annotations feature private boolean fGenerateSyntheticAnnotation = false; private BooleanStack fHasNonSchemaAttributes = new BooleanStack(); private BooleanStack fSawAnnotation = new BooleanStack(); private XMLAttributes fEmptyAttr = new XMLAttributesImpl(); - + // // XMLDocumentHandler methods // - - public void startDocument(XMLLocator locator, String encoding, + + public void startDocument(XMLLocator locator, String encoding, NamespaceContext namespaceContext, Augmentations augs) throws XNIException { fErrorReporter = (XMLErrorReporter)config.getProperty(ERROR_REPORTER); fGenerateSyntheticAnnotation = config.getFeature(GENERATE_SYNTHETIC_ANNOTATION); fHasNonSchemaAttributes.clear(); fSawAnnotation.clear(); - schemaDOM = new SchemaDOM(); + schemaDOM = new SchemaDOM(); fAnnotationDepth = -1; fInnerAnnotationDepth = -1; fDepth = -1; @@ -117,7 +122,7 @@ fNamespaceContext = namespaceContext; schemaDOM.setDocumentURI(locator.getExpandedSystemId()); } // startDocument(XMLLocator,String,NamespaceContext, Augmentations) - + /** * The end of the document. * @param augs Additional information that may include infoset augmentations @@ -128,14 +133,14 @@ // To debug the DOM created uncomment the line below // schemaDOM.printDOM(); } // endDocument() - - + + /** * A comment. - * + * * @param text The text in the comment. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by application to signal an error. */ @@ -144,7 +149,7 @@ schemaDOM.comment(text); } } - + /** * A processing instruction. Processing instructions consist of a * target name and, optionally, text data. The data is only meaningful @@ -155,11 +160,11 @@ * element attributes but are <strong>not</strong> parsed or presented * to the application as anything other than text. The application is * responsible for parsing the data. - * + * * @param target The target. * @param data The data or null if none specified. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ @@ -169,13 +174,13 @@ schemaDOM.processingInstruction(target, data.toString()); } } - + /** * Character content. - * + * * @param text The content. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ @@ -204,23 +209,23 @@ else { schemaDOM.characters(text); } - + } - - + + /** * The start of an element. - * + * * @param element The name of the element. * @param attributes The element attributes. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ public void startElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { - + fDepth++; // while it is true that non-whitespace character data // may only occur in appInfo or documentation @@ -238,7 +243,7 @@ } fAnnotationDepth = fDepth; schemaDOM.startAnnotation(element, attributes, fNamespaceContext); - } + } else if (element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && fGenerateSyntheticAnnotation) { fSawAnnotation.push(false); fHasNonSchemaAttributes.push(hasNonSchemaAttributes(element, attributes)); @@ -251,47 +256,47 @@ // avoid falling through; don't call startElement in this case return; } - schemaDOM.startElement(element, attributes, + schemaDOM.startElement(element, attributes, fLocator.getLineNumber(), fLocator.getColumnNumber(), fLocator.getCharacterOffset()); - + } - - + + /** * An empty element. - * + * * @param element The name of the element. * @param attributes The element attributes. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ public void emptyElement(QName element, XMLAttributes attributes, Augmentations augs) throws XNIException { - - if (fGenerateSyntheticAnnotation && fAnnotationDepth == -1 && - element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && element.localpart != SchemaSymbols.ELT_ANNOTATION && hasNonSchemaAttributes(element, attributes)) { - + + if (fGenerateSyntheticAnnotation && fAnnotationDepth == -1 && + element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && element.localpart != SchemaSymbols.ELT_ANNOTATION && hasNonSchemaAttributes(element, attributes)) { + schemaDOM.startElement(element, attributes, fLocator.getLineNumber(), fLocator.getColumnNumber(), fLocator.getCharacterOffset()); - + attributes.removeAllAttributes(); String schemaPrefix = fNamespaceContext.getPrefix(SchemaSymbols.URI_SCHEMAFORSCHEMA); QName annQName = new QName(schemaPrefix, SchemaSymbols.ELT_ANNOTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_ANNOTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); schemaDOM.startAnnotation(annQName, attributes, fNamespaceContext); QName elemQName = new QName(schemaPrefix, SchemaSymbols.ELT_DOCUMENTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_DOCUMENTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); schemaDOM.startAnnotationElement(elemQName, attributes); - schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); + schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); schemaDOM.endSyntheticAnnotationElement(elemQName, false); schemaDOM.endSyntheticAnnotationElement(annQName, true); - + schemaDOM.endElement(); - + return; } // the order of events that occurs here is: @@ -314,12 +319,12 @@ } else { schemaDOM.startAnnotationElement(element, attributes); } - - schemaDOM.emptyElement(element, attributes, + + schemaDOM.emptyElement(element, attributes, fLocator.getLineNumber(), fLocator.getColumnNumber(), fLocator.getCharacterOffset()); - + if (fAnnotationDepth == -1) { // this is messed up, but a case to consider: if (element.uri == SchemaSymbols.URI_SCHEMAFORSCHEMA && @@ -328,21 +333,21 @@ } } else { schemaDOM.endAnnotationElement(element, false); - } + } } - - + + /** * The end of an element. - * + * * @param element The name of the element. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ public void endElement(QName element, Augmentations augs) throws XNIException { - + // when we reach the endElement of xs:appinfo or xs:documentation, // change fInnerAnnotationDepth to -1 if(fAnnotationDepth > -1) { @@ -367,7 +372,7 @@ schemaDOM.startAnnotation(annQName, fEmptyAttr, fNamespaceContext); QName elemQName = new QName(schemaPrefix, SchemaSymbols.ELT_DOCUMENTATION, schemaPrefix + (schemaPrefix.length() == 0?"":":") + SchemaSymbols.ELT_DOCUMENTATION, SchemaSymbols.URI_SCHEMAFORSCHEMA); schemaDOM.startAnnotationElement(elemQName, fEmptyAttr); - schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); + schemaDOM.characters(new XMLString("SYNTHETIC_ANNOTATION".toCharArray(), 0, 20 )); schemaDOM.endSyntheticAnnotationElement(elemQName, false); schemaDOM.endSyntheticAnnotationElement(annQName, true); } @@ -375,9 +380,9 @@ schemaDOM.endElement(); } fDepth--; - + } - + /** * @param attributes * @return @@ -386,16 +391,16 @@ final int length = attributes.getLength(); for (int i = 0; i < length; ++i) { String uri = attributes.getURI(i); - if (uri != null && uri != SchemaSymbols.URI_SCHEMAFORSCHEMA && + if (uri != null && uri != SchemaSymbols.URI_SCHEMAFORSCHEMA && uri != NamespaceContext.XMLNS_URI && - !(uri == NamespaceContext.XML_URI && + !(uri == NamespaceContext.XML_URI && attributes.getQName(i) == SchemaSymbols.ATT_XML_LANG && element.localpart == SchemaSymbols.ELT_SCHEMA)) { return true; } } return false; } - + /** * Ignorable whitespace. For this method to be called, the document * source must have some way of determining that the text containing @@ -403,10 +408,10 @@ * example, the validator can determine if a length of whitespace * characters in the document are ignorable based on the element * content model. - * + * * @param text The ignorable whitespace. * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ @@ -416,12 +421,12 @@ schemaDOM.characters(text); } } - + /** * The start of a CDATA section. - * + * * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ @@ -431,12 +436,12 @@ schemaDOM.startAnnotationCDATA(); } } - + /** * The end of a CDATA section. - * + * * @param augs Additional information that may include infoset augmentations - * + * * @exception XNIException * Thrown by handler to signal an error. */ @@ -446,28 +451,28 @@ schemaDOM.endAnnotationCDATA(); } } - - + + // // other methods // - + /** * Returns the DOM document object. */ public Document getDocument() { return schemaDOM; } - + /** * Delegates to SchemaParsingConfig.setFeature * @param featureId * @param state */ public void setFeature(String featureId, boolean state){ - config.setFeature(featureId, state); + config.setFeature(featureId, state); } - + /** * Delegates to SchemaParsingConfig.getFeature * @param featureId @@ -476,7 +481,7 @@ public boolean getFeature(String featureId){ return config.getFeature(featureId); } - + /** * Delegates to SchemaParsingConfig.setProperty. * @param propertyId @@ -485,7 +490,7 @@ public void setProperty(String propertyId, Object value){ config.setProperty(propertyId, value); } - + /** * Delegates to SchemaParsingConfig.getProperty. * @param propertyId @@ -494,50 +499,42 @@ public Object getProperty(String propertyId){ return config.getProperty(propertyId); } - + /** * Delegates to SchemaParsingConfig.setEntityResolver. * @param er XMLEntityResolver */ public void setEntityResolver(XMLEntityResolver er) { - config.setEntityResolver(er); + config.setEntityResolver(er); } - + /** * Delegates parsing to SchemaParsingConfig - * + * * @param inputSource * @throws IOException */ public void parse(XMLInputSource inputSource) throws IOException { config.parse(inputSource); } - - /** - * Gets the document from SchemaParsingConfig - * @return Document - */ - public Document getDocument2() { - return ((SchemaParsingConfig)config).getDocument(); - } - + /** * Reset SchemaParsingConfig */ public void reset() { - ((SchemaParsingConfig)config).reset(); + ((SchemaParsingConfig)config).reset(); } - + /** * ResetNodePool on SchemaParsingConfig */ public void resetNodePool() { - ((SchemaParsingConfig)config).resetNodePool(); + ((SchemaParsingConfig)config).resetNodePool(); } - + /** * A simple boolean based stack. - * + * * @xerces.internal */ private static final class BooleanStack { @@ -551,11 +548,11 @@ /** Stack data. */ private boolean[] fData; - + // // Constructor // - + public BooleanStack () {} //
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/opti/SchemaParsingConfig.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/opti/SchemaParsingConfig.java Wed Sep 28 17:10:18 2011 +0100 @@ -24,10 +24,14 @@ import java.util.Locale; import com.sun.org.apache.xerces.internal.impl.Constants; +import com.sun.org.apache.xerces.internal.impl.XML11DTDScannerImpl; +import com.sun.org.apache.xerces.internal.impl.XML11NSDocumentScannerImpl; import com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl; +import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.impl.XMLEntityManager; import com.sun.org.apache.xerces.internal.impl.XMLErrorReporter; import com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl; +import com.sun.org.apache.xerces.internal.impl.XMLVersionDetector; import com.sun.org.apache.xerces.internal.impl.dv.DTDDVFactory; import com.sun.org.apache.xerces.internal.impl.msg.XMLMessageFormatter; import com.sun.org.apache.xerces.internal.impl.validation.ValidationManager; @@ -44,22 +48,24 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLDocumentScanner; import com.sun.org.apache.xerces.internal.xni.parser.XMLInputSource; import com.sun.org.apache.xerces.internal.xni.parser.XMLPullParserConfiguration; -import org.w3c.dom.Document; - /** * @xerces.internal * * @author Rahul Srivastava, Sun Microsystems Inc. * + * @version $Id: SchemaParsingConfig.java,v 1.6 2010/07/23 02:09:29 joehw Exp $ */ public class SchemaParsingConfig extends BasicParserConfiguration -implements XMLPullParserConfiguration { + implements XMLPullParserConfiguration { // // Constants // + protected final static String XML11_DATATYPE_VALIDATOR_FACTORY = + "com.sun.org.apache.xerces.internal.impl.dv.dtd.XML11DTDDVFactoryImpl"; + // feature identifiers /** Feature identifier: warn on duplicate attribute definition. */ @@ -93,18 +99,16 @@ protected static final String NOTIFY_CHAR_REFS = Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE; - /** Feature identifier: expose schema normalized value */ protected static final String NORMALIZE_DATA = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_NORMALIZED_VALUE; - /** Feature identifier: send element default value via characters() */ protected static final String SCHEMA_ELEMENT_DEFAULT = Constants.XERCES_FEATURE_PREFIX + Constants.SCHEMA_ELEMENT_DEFAULT; /** Feature identifier: generate synthetic annotations. */ - protected static final String GENERATE_SYNTHETIC_ANNOTATION = + protected static final String GENERATE_SYNTHETIC_ANNOTATIONS = Constants.XERCES_FEATURE_PREFIX + Constants.GENERATE_SYNTHETIC_ANNOTATIONS_FEATURE; @@ -149,6 +153,10 @@ protected static final String SCHEMA_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY; + /** Property identifier: locale. */ + protected static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + // debugging @@ -159,35 +167,61 @@ // Data // - // components (non-configurable) + // + // XML 1.0 components + // + + /** The XML 1.0 Datatype validator factory. */ + protected final DTDDVFactory fDatatypeValidatorFactory; + + /** The XML 1.0 Document scanner. */ + protected final XMLNSDocumentScannerImpl fNamespaceScanner; + + /** The XML 1.0 DTD scanner. */ + protected final XMLDTDScannerImpl fDTDScanner; + + // + // XML 1.1 components + // + + /** The XML 1.1 Datatype validator factory. */ + protected DTDDVFactory fXML11DatatypeFactory = null; + + /** The XML 1.1 Document scanner. */ + protected XML11NSDocumentScannerImpl fXML11NSDocScanner = null; + + /** The XML 1.1 DTD scanner. **/ + protected XML11DTDScannerImpl fXML11DTDScanner = null; + + // common components (non-configurable) + + /** Current Datatype validator factory. */ + protected DTDDVFactory fCurrentDVFactory; + + /** Current scanner */ + protected XMLDocumentScanner fCurrentScanner; + + /** Current DTD scanner. */ + protected XMLDTDScanner fCurrentDTDScanner; /** Grammar pool. */ protected XMLGrammarPool fGrammarPool; - /** Datatype validator factory. */ - protected DTDDVFactory fDatatypeValidatorFactory; + /** XML version detector. */ + protected final XMLVersionDetector fVersionDetector; - // components (configurable) + // common components (configurable) /** Error reporter. */ - protected XMLErrorReporter fErrorReporter; + protected final XMLErrorReporter fErrorReporter; /** Entity manager. */ - protected XMLEntityManager fEntityManager; - - /** Document scanner. */ - protected XMLDocumentScanner fScanner; + protected final XMLEntityManager fEntityManager; /** Input Source */ protected XMLInputSource fInputSource; - /** DTD scanner. */ - protected XMLDTDScanner fDTDScanner; - - - protected SchemaDOMParser fSchemaDOMParser; - - protected ValidationManager fValidationManager; + protected final ValidationManager fValidationManager; // state /** Locator */ @@ -200,6 +234,15 @@ */ protected boolean fParseInProgress = false; + /** + * fConfigUpdated is set to true if there has been any change to the configuration settings, + * i.e a feature or a property was changed. + */ + protected boolean fConfigUpdated = false; + + /** Flag indiciating whether XML11 components have been initialized. */ + private boolean f11Initialized = false; + // // Constructors // @@ -256,7 +299,7 @@ PARSER_SETTINGS, WARN_ON_DUPLICATE_ATTDEF, WARN_ON_UNDECLARED_ELEMDEF, ALLOW_JAVA_ENCODINGS, CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, NOTIFY_BUILTIN_REFS, - NOTIFY_CHAR_REFS, GENERATE_SYNTHETIC_ANNOTATION + NOTIFY_CHAR_REFS, GENERATE_SYNTHETIC_ANNOTATIONS }; addRecognizedFeatures(recognizedFeatures); fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); @@ -269,7 +312,7 @@ fFeatures.put(LOAD_EXTERNAL_DTD, Boolean.TRUE); fFeatures.put(NOTIFY_BUILTIN_REFS, Boolean.FALSE); fFeatures.put(NOTIFY_CHAR_REFS, Boolean.FALSE); - fFeatures.put(GENERATE_SYNTHETIC_ANNOTATION, Boolean.FALSE); + fFeatures.put(GENERATE_SYNTHETIC_ANNOTATIONS, Boolean.FALSE); // add default recognized properties final String[] recognizedProperties = { @@ -282,12 +325,13 @@ XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER, - GENERATE_SYNTHETIC_ANNOTATION + GENERATE_SYNTHETIC_ANNOTATIONS, + LOCALE }; addRecognizedProperties(recognizedProperties); fGrammarPool = grammarPool; - if(fGrammarPool != null){ + if (fGrammarPool != null) { setProperty(XMLGRAMMAR_POOL, fGrammarPool); } @@ -300,22 +344,23 @@ fProperties.put(ERROR_REPORTER, fErrorReporter); addComponent(fErrorReporter); - fScanner = new XMLNSDocumentScannerImpl(); - fProperties.put(DOCUMENT_SCANNER, fScanner); - addComponent((XMLComponent)fScanner); + fNamespaceScanner = new XMLNSDocumentScannerImpl(); + fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); + addRecognizedParamsAndSetDefaults(fNamespaceScanner); fDTDScanner = new XMLDTDScannerImpl(); fProperties.put(DTD_SCANNER, fDTDScanner); - addComponent((XMLComponent)fDTDScanner); + addRecognizedParamsAndSetDefaults(fDTDScanner); - - fDatatypeValidatorFactory = DTDDVFactory.getInstance();; + fDatatypeValidatorFactory = DTDDVFactory.getInstance(); fProperties.put(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory); fValidationManager = new ValidationManager(); fProperties.put(VALIDATION_MANAGER, fValidationManager); + fVersionDetector = new XMLVersionDetector(); + // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { XMLMessageFormatter xmft = new XMLMessageFormatter(); @@ -344,6 +389,126 @@ // /** + * Returns the state of a feature. + * + * @param featureId The feature identifier. + * @return true if the feature is supported + * + * @throws XMLConfigurationException Thrown for configuration error. + * In general, components should + * only throw this exception if + * it is <strong>really</strong> + * a critical error. + */ + public boolean getFeature(String featureId) + throws XMLConfigurationException { + // make this feature special + if (featureId.equals(PARSER_SETTINGS)) { + return fConfigUpdated; + } + return super.getFeature(featureId); + + } // getFeature(String):boolean + + /** + * Set the state of a feature. + * + * Set the state of any feature in a SAX2 parser. The parser + * might not recognize the feature, and if it does recognize + * it, it might not be able to fulfill the request. + * + * @param featureId The unique identifier (URI) of the feature. + * @param state The requested state of the feature (true or false). + * + * @exception com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException If the + * requested feature is not known. + */ + public void setFeature(String featureId, boolean state) + throws XMLConfigurationException { + + fConfigUpdated = true; + + // forward to every XML 1.0 component + fNamespaceScanner.setFeature(featureId, state); + fDTDScanner.setFeature(featureId, state); + + // forward to every XML 1.1 component + if (f11Initialized) { + try { + fXML11DTDScanner.setFeature(featureId, state); + } + // ignore the exception. + catch (Exception e) {} + try { + fXML11NSDocScanner.setFeature(featureId, state); + } + // ignore the exception + catch (Exception e) {} + } + + // save state if noone "objects" + super.setFeature(featureId, state); + + } // setFeature(String,boolean) + + /** + * Returns the value of a property. + * + * @param propertyId The property identifier. + * @return the value of the property + * + * @throws XMLConfigurationException Thrown for configuration error. + * In general, components should + * only throw this exception if + * it is <strong>really</strong> + * a critical error. + */ + public Object getProperty(String propertyId) + throws XMLConfigurationException { + if (LOCALE.equals(propertyId)) { + return getLocale(); + } + return super.getProperty(propertyId); + } + + /** + * setProperty + * + * @param propertyId + * @param value + */ + public void setProperty(String propertyId, Object value) + throws XMLConfigurationException { + + fConfigUpdated = true; + if (LOCALE.equals(propertyId)) { + setLocale((Locale) value); + } + + // forward to every XML 1.0 component + fNamespaceScanner.setProperty(propertyId, value); + fDTDScanner.setProperty(propertyId, value); + + // forward to every XML 1.1 component + if (f11Initialized) { + try { + fXML11DTDScanner.setProperty(propertyId, value); + } + // ignore the exception. + catch (Exception e) {} + try { + fXML11NSDocScanner.setProperty(propertyId, value); + } + // ignore the exception + catch (Exception e) {} + } + + // store value if noone "objects" + super.setProperty(propertyId, value); + + } // setProperty(String,Object) + + /** * Set the locale to use for messages. * * @param locale The locale object to use for localization of messages. @@ -405,11 +570,34 @@ public boolean parse(boolean complete) throws XNIException, IOException { // // reset and configure pipeline and set InputSource. - if (fInputSource !=null) { + if (fInputSource != null) { try { + fValidationManager.reset(); + fVersionDetector.reset(this); + reset(); + + short version = fVersionDetector.determineDocVersion(fInputSource); + // XML 1.0 + if (version == Constants.XML_VERSION_1_0) { + configurePipeline(); + resetXML10(); + } + // XML 1.1 + else if (version == Constants.XML_VERSION_1_1) { + initXML11Components(); + configureXML11Pipeline(); + resetXML11(); + } + // Unrecoverable error reported during version detection + else { + return false; + } + + // mark configuration as fixed + fConfigUpdated = false; + // resets and sets the pipeline. - reset(); - fScanner.setInputSource(fInputSource); + fVersionDetector.startDocumentParsing((XMLEntityHandler) fCurrentScanner, version); fInputSource = null; } catch (XNIException ex) { @@ -435,7 +623,7 @@ } try { - return fScanner.scanDocument(complete); + return fCurrentScanner.scanDocument(complete); } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) @@ -532,35 +720,82 @@ */ public void reset() throws XNIException { - // set handlers - if (fSchemaDOMParser == null) - fSchemaDOMParser = new SchemaDOMParser(this); - fDocumentHandler = fSchemaDOMParser; - fDTDHandler = fSchemaDOMParser; - fDTDContentModelHandler = fSchemaDOMParser; - - // configure the pipeline and initialize the components - configurePipeline(); + // initialize the common components super.reset(); } // reset() - /** Configures the pipeline. */ + /** Configures the XML 1.0 pipeline. */ protected void configurePipeline() { + if (fCurrentDVFactory != fDatatypeValidatorFactory) { + fCurrentDVFactory = fDatatypeValidatorFactory; + // use XML 1.0 datatype library + setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); + } + // setup document pipeline - fScanner.setDocumentHandler(fDocumentHandler); - fDocumentHandler.setDocumentSource(fScanner); - fLastComponent = fScanner; + if (fCurrentScanner != fNamespaceScanner) { + fCurrentScanner = fNamespaceScanner; + setProperty(DOCUMENT_SCANNER, fCurrentScanner); + } + fNamespaceScanner.setDocumentHandler(fDocumentHandler); + if (fDocumentHandler != null) { + fDocumentHandler.setDocumentSource(fNamespaceScanner); + } + fLastComponent = fNamespaceScanner; // setup dtd pipeline - if (fDTDScanner != null) { - fDTDScanner.setDTDHandler(fDTDHandler); - fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); + if (fCurrentDTDScanner != fDTDScanner) { + fCurrentDTDScanner = fDTDScanner; + setProperty(DTD_SCANNER, fCurrentDTDScanner); + } + fDTDScanner.setDTDHandler(fDTDHandler); + if (fDTDHandler != null) { + fDTDHandler.setDTDSource(fDTDScanner); + } + fDTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); + if (fDTDContentModelHandler != null) { + fDTDContentModelHandler.setDTDContentModelSource(fDTDScanner); + } + + } // configurePipeline() + + /** Configures the XML 1.1 pipeline. */ + protected void configureXML11Pipeline() { + + if (fCurrentDVFactory != fXML11DatatypeFactory) { + fCurrentDVFactory = fXML11DatatypeFactory; + // use XML 1.1 datatype library + setProperty(DATATYPE_VALIDATOR_FACTORY, fCurrentDVFactory); } + // setup document pipeline + if (fCurrentScanner != fXML11NSDocScanner) { + fCurrentScanner = fXML11NSDocScanner; + setProperty(DOCUMENT_SCANNER, fCurrentScanner); + } + fXML11NSDocScanner.setDocumentHandler(fDocumentHandler); + if (fDocumentHandler != null) { + fDocumentHandler.setDocumentSource(fXML11NSDocScanner); + } + fLastComponent = fXML11NSDocScanner; - } // configurePipeline() + // setup dtd pipeline + if (fCurrentDTDScanner != fXML11DTDScanner) { + fCurrentDTDScanner = fXML11DTDScanner; + setProperty(DTD_SCANNER, fCurrentDTDScanner); + } + fXML11DTDScanner.setDTDHandler(fDTDHandler); + if (fDTDHandler != null) { + fDTDHandler.setDTDSource(fXML11DTDScanner); + } + fXML11DTDScanner.setDTDContentModelHandler(fDTDContentModelHandler); + if (fDTDContentModelHandler != null) { + fDTDContentModelHandler.setDTDContentModelSource(fXML11DTDScanner); + } + + } // configureXML11Pipeline() // features and properties @@ -577,7 +812,7 @@ * a critical error. */ protected void checkFeature(String featureId) - throws XMLConfigurationException { + throws XMLConfigurationException { // // Xerces Features @@ -661,7 +896,7 @@ * a critical error. */ protected void checkProperty(String propertyId) - throws XMLConfigurationException { + throws XMLConfigurationException { // // Xerces Properties @@ -693,20 +928,104 @@ } // checkProperty(String) + /** + * Adds all of the component's recognized features and properties + * to the list of default recognized features and properties, and + * sets default values on the configuration for features and + * properties which were previously absent from the configuration. + * + * @param component The component whose recognized features + * and properties will be added to the configuration + */ + private void addRecognizedParamsAndSetDefaults(XMLComponent component) { + // register component's recognized features + String[] recognizedFeatures = component.getRecognizedFeatures(); + addRecognizedFeatures(recognizedFeatures); + + // register component's recognized properties + String[] recognizedProperties = component.getRecognizedProperties(); + addRecognizedProperties(recognizedProperties); + + // set default values + if (recognizedFeatures != null) { + for (int i = 0; i < recognizedFeatures.length; ++i) { + String featureId = recognizedFeatures[i]; + Boolean state = component.getFeatureDefault(featureId); + if (state != null) { + // Do not overwrite values already set on the configuration. + if (!fFeatures.containsKey(featureId)) { + fFeatures.put(featureId, state); + // For newly added components who recognize this feature + // but did not offer a default value, we need to make + // sure these components will get an opportunity to read + // the value before parsing begins. + fConfigUpdated = true; + } + } + } + } + if (recognizedProperties != null) { + for (int i = 0; i < recognizedProperties.length; ++i) { + String propertyId = recognizedProperties[i]; + Object value = component.getPropertyDefault(propertyId); + if (value != null) { + // Do not overwrite values already set on the configuration. + if (!fProperties.containsKey(propertyId)) { + fProperties.put(propertyId, value); + // For newly added components who recognize this property + // but did not offer a default value, we need to make + // sure these components will get an opportunity to read + // the value before parsing begins. + fConfigUpdated = true; + } + } + } + } + } + + /** + * Reset all XML 1.0 components before parsing + */ + protected final void resetXML10() throws XNIException { + // Reset XML 1.0 components + fNamespaceScanner.reset(this); + fDTDScanner.reset(this); + } // resetXML10() + + /** + * Reset all XML 1.1 components before parsing + */ + protected final void resetXML11() throws XNIException { + // Reset XML 1.1 components + fXML11NSDocScanner.reset(this); + fXML11DTDScanner.reset(this); + } // resetXML11() // // other methods // - /** Returns the Document object. */ - public Document getDocument() { - return fSchemaDOMParser.getDocument(); - } - /** */ public void resetNodePool() { // REVISIT: to implement: introduce a node pool to reuse DTM nodes. // reset this pool here. } + + private void initXML11Components() { + if (!f11Initialized) { + // create datatype factory + fXML11DatatypeFactory = DTDDVFactory.getInstance(XML11_DATATYPE_VALIDATOR_FACTORY); + + // setup XML 1.1 DTD pipeline + fXML11DTDScanner = new XML11DTDScannerImpl(); + addRecognizedParamsAndSetDefaults(fXML11DTDScanner); + + // setup XML 1.1. document pipeline - namespace aware + fXML11NSDocScanner = new XML11NSDocumentScannerImpl(); + addRecognizedParamsAndSetDefaults(fXML11NSDocScanner); + + f11Initialized = true; + } + } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDAbstractTraverser.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDAbstractTraverser.java Wed Sep 28 17:10:18 2011 +0100 @@ -20,6 +20,7 @@ package com.sun.org.apache.xerces.internal.impl.xs.traversers; +import java.util.Locale; import java.util.Vector; import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException; @@ -52,17 +53,18 @@ * other <code>XSD???Traverser</code>s. It holds the common data and provide * a unified way to initialize these data. * - * @xerces.internal + * @xerces.internal * * @author Elena Litani, IBM * @author Rahul Srivastava, Sun Microsystems Inc. * @author Neeraj Bajaj, Sun Microsystems Inc. * + * @version $Id: XSDAbstractTraverser.java,v 1.6 2010/07/23 02:09:30 joehw Exp $ */ abstract class XSDAbstractTraverser { - + protected static final String NO_NAME = "(no name)"; - + // Flags for checkOccurrences to indicate any special // restrictions on minOccurs and maxOccurs relating to "all". // NOT_ALL_CONTEXT - not processing an <all> @@ -70,35 +72,36 @@ // GROUP_REF_WITH_ALL - processing <group> reference that contained <all> // CHILD_OF_GROUP - processing a child of a model group definition // PROCESSING_ALL_GP - processing an <all> group itself - + protected static final int NOT_ALL_CONTEXT = 0; protected static final int PROCESSING_ALL_EL = 1; protected static final int GROUP_REF_WITH_ALL = 2; protected static final int CHILD_OF_GROUP = 4; protected static final int PROCESSING_ALL_GP = 8; - + //Shared data protected XSDHandler fSchemaHandler = null; protected SymbolTable fSymbolTable = null; protected XSAttributeChecker fAttrChecker = null; protected boolean fValidateAnnotations = false; - + // used to validate default/fixed attribute values ValidationState fValidationState = new ValidationState(); - + XSDAbstractTraverser (XSDHandler handler, XSAttributeChecker attrChecker) { fSchemaHandler = handler; fAttrChecker = attrChecker; } - - void reset(SymbolTable symbolTable, boolean validateAnnotations) { + + void reset(SymbolTable symbolTable, boolean validateAnnotations, Locale locale) { fSymbolTable = symbolTable; fValidateAnnotations = validateAnnotations; fValidationState.setExtraChecking(false); fValidationState.setSymbolTable(symbolTable); + fValidationState.setLocale(locale); } - + // traverse the annotation declaration // REVISIT: how to pass the parentAttrs? as DOM attributes? // as name/value pairs (string)? in parsed form? @@ -108,13 +111,13 @@ // General Attribute Checking Object[] attrValues = fAttrChecker.checkAttributes(annotationDecl, isGlobal, schemaDoc); fAttrChecker.returnAttrArray(attrValues, schemaDoc); - + String contents = null; Element child = DOMUtil.getFirstChildElement(annotationDecl); if (child != null) { do { String name = DOMUtil.getLocalName(child); - + // the only valid children of "annotation" are // "appinfo" and "documentation" if (!((name.equals(SchemaSymbols.ELT_APPINFO)) || @@ -126,13 +129,13 @@ contents = ((Text)textContent).getData(); } } - + // General Attribute Checking // There is no difference between global or local appinfo/documentation, // so we assume it's always global. attrValues = fAttrChecker.checkAttributes(child, true, schemaDoc); fAttrChecker.returnAttrArray(attrValues, schemaDoc); - + child = DOMUtil.getNextSiblingElement(child); } while (child != null); @@ -141,7 +144,7 @@ // <appinfo> children the text child is stored on the first child of its // parent. Only if the annotation is the first child will we find the // text node there. See SchemaDOM. We need to store the string representation - // in a consistent place so it can be reliably retrieved, perhaps as + // in a consistent place so it can be reliably retrieved, perhaps as // user data. -- mrglavas else { Node textContent = annotationDecl.getFirstChild(); @@ -152,7 +155,7 @@ // if contents was null, must have been some kind of error; // nothing to contribute to PSVI if (contents == null) return null; - + // find the grammar; fSchemaHandler must be known! SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace); // fish out local attributes passed from parent @@ -208,14 +211,14 @@ } return new XSAnnotationImpl(contents, grammar); } - + } - + XSAnnotationImpl traverseSyntheticAnnotation(Element annotationParent, String initialContent, Object[] parentAttrs, boolean isGlobal, XSDocumentInfo schemaDoc) { - + String contents = initialContent; - + // find the grammar; fSchemaHandler must be known! SchemaGrammar grammar = fSchemaHandler.getGrammar(schemaDoc.fTargetNamespace); // fish out local attributes passed from parent @@ -268,35 +271,35 @@ return new XSAnnotationImpl(contents, grammar); } } - + // the QName simple type used to resolve qnames private static final XSSimpleType fQNameDV = (XSSimpleType)SchemaGrammar.SG_SchemaNS.getGlobalTypeDecl(SchemaSymbols.ATTVAL_QNAME); // Temp data structures to be re-used in traversing facets private StringBuffer fPattern = new StringBuffer(); private final XSFacets xsFacets = new XSFacets(); - + class FacetInfo { XSFacets facetdata; Element nodeAfterFacets; short fPresentFacets; short fFixedFacets; } - + FacetInfo traverseFacets(Element content, XSSimpleType baseValidator, XSDocumentInfo schemaDoc) { - + short facetsPresent = 0 ; - short facetsFixed = 0; // facets that have fixed="true" + short facetsFixed = 0; // facets that have fixed="true" String facet; boolean hasQName = containsQName(baseValidator); Vector enumData = null; XSObjectListImpl enumAnnotations = null; XSObjectListImpl patternAnnotations = null; - Vector enumNSDecls = hasQName ? new Vector() : null; + Vector enumNSDecls = hasQName ? new Vector() : null; int currentFacet = 0; xsFacets.reset(); - while (content != null) { + while (content != null) { // General Attribute Checking Object[] attrs = null; facet = DOMUtil.getLocalName(content); @@ -304,7 +307,7 @@ attrs = fAttrChecker.checkAttributes(content, false, schemaDoc, hasQName); String enumVal = (String)attrs[XSAttributeChecker.ATTIDX_VALUE]; NamespaceSupport nsDecls = (NamespaceSupport)attrs[XSAttributeChecker.ATTIDX_ENUMNSDECLS]; - + // for NOTATION types, need to check whether there is a notation // declared with the same name as the enumeration value. if (baseValidator.getVariety() == XSSimpleType.VARIETY_ATOMIC && @@ -331,10 +334,10 @@ if (hasQName) enumNSDecls.addElement(nsDecls); Element child = DOMUtil.getFirstChildElement( content ); - + if (child != null) { // traverse annotation if any - + if (DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { enumAnnotations.add(enumAnnotations.getLength()-1,traverseAnnotationDecl(child, attrs, false, schemaDoc)); child = DOMUtil.getNextSiblingElement(child); @@ -381,7 +384,7 @@ reportSchemaError("s4s-elt-must-match.1", new Object[]{"pattern", "(annotation?)", DOMUtil.getLocalName(child)}, child); } } - + } else { if (facet.equals(SchemaSymbols.ELT_MINLENGTH)) { @@ -417,9 +420,9 @@ else { break; // a non-facet } - + attrs = fAttrChecker.checkAttributes(content, false, schemaDoc); - + // check for duplicate facets if ((facetsPresent & currentFacet) != 0) { reportSchemaError("src-single-facet-value", new Object[]{facet}, content); @@ -462,7 +465,7 @@ break; } } - + Element child = DOMUtil.getFirstChildElement( content ); if (child != null) { // traverse annotation if any @@ -500,8 +503,8 @@ xsFacets.lengthAnnotation = annotation; break; } - - + + child = DOMUtil.getNextSiblingElement(child); } else { @@ -561,9 +564,9 @@ xsFacets.pattern = fPattern.toString(); xsFacets.patternAnnotations = patternAnnotations; } - + fPattern.setLength(0); - + FacetInfo fi = new FacetInfo(); fi.facetdata = xsFacets; fi.nodeAfterFacets = content; @@ -571,8 +574,8 @@ fi.fFixedFacets = facetsFixed; return fi; } - - + + // return whether QName/NOTATION is part of the given type private boolean containsQName(XSSimpleType type) { if (type.getVariety() == XSSimpleType.VARIETY_ATOMIC) { @@ -592,7 +595,7 @@ } return false; } - + // // Traverse a set of attribute and attribute group elements // Needed by complexType and attributeGroup traversal @@ -601,12 +604,12 @@ Element traverseAttrsAndAttrGrps(Element firstAttr, XSAttributeGroupDecl attrGrp, XSDocumentInfo schemaDoc, SchemaGrammar grammar, XSComplexTypeDecl enclosingCT) { - + Element child=null; XSAttributeGroupDecl tempAttrGrp = null; XSAttributeUseImpl tempAttrUse = null; String childName; - + for (child=firstAttr; child!=null; child=DOMUtil.getNextSiblingElement(child)) { childName = DOMUtil.getLocalName(child); if (childName.equals(SchemaSymbols.ELT_ATTRIBUTE)) { @@ -657,7 +660,7 @@ reportSchemaError(code, new Object[]{name, oneAttrUse.fAttrDecl.getName()}, child); } } - + if (tempAttrGrp.fAttributeWC != null) { if (attrGrp.fAttributeWC == null) { attrGrp.fAttributeWC = tempAttrGrp.fAttributeWC; @@ -677,7 +680,7 @@ else break; } // for - + if (child != null) { childName = DOMUtil.getLocalName(child); if (childName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) { @@ -699,16 +702,16 @@ child = DOMUtil.getNextSiblingElement(child); } } - + // Success return child; - + } - + void reportSchemaError (String key, Object[] args, Element ele) { fSchemaHandler.reportSchemaError(key, args, ele); } - + /** * Element/Attribute traversers call this method to check whether * the type is NOTATION without enumeration facet @@ -722,23 +725,23 @@ } } } - + // Checks constraints for minOccurs, maxOccurs protected XSParticleDecl checkOccurrences(XSParticleDecl particle, String particleName, Element parent, int allContextFlags, long defaultVals) { - + int min = particle.fMinOccurs; int max = particle.fMaxOccurs; boolean defaultMin = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MINOCCURS)) != 0; boolean defaultMax = (defaultVals & (1 << XSAttributeChecker.ATTIDX_MAXOCCURS)) != 0; - + boolean processingAllEl = ((allContextFlags & PROCESSING_ALL_EL) != 0); boolean processingAllGP = ((allContextFlags & PROCESSING_ALL_GP) != 0); boolean groupRefWithAll = ((allContextFlags & GROUP_REF_WITH_ALL) != 0); boolean isGroupChild = ((allContextFlags & CHILD_OF_GROUP) != 0); - + // Neither minOccurs nor maxOccurs may be specified // for the child of a model group definition. if (isGroupChild) { @@ -753,13 +756,13 @@ max = 1; } } - + // If minOccurs=maxOccurs=0, no component is specified if (min == 0 && max== 0) { particle.fType = XSParticleDecl.PARTICLE_EMPTY; return null; } - + // For the elements referenced in an <all>, minOccurs attribute // must be zero or one, and maxOccurs attribute must be one. // For a complex type definition that contains an <all> or a @@ -782,13 +785,13 @@ max = 1; } } - + particle.fMaxOccurs = min; particle.fMaxOccurs = max; - + return particle; } - + // this is not terribly performant! private static String processAttValue(String original) { // normally, nothing will happen
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDComplexTypeTraverser.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDComplexTypeTraverser.java Wed Sep 28 17:10:18 2011 +0100 @@ -58,16 +58,17 @@ * ((group | all | choice | sequence)?, * ((attribute | attributeGroup)*, anyAttribute?)))) * </complexType> - * - * @xerces.internal - * + * + * @xerces.internal + * + * @version $Id: XSDComplexTypeTraverser.java,v 1.6 2010/07/20 20:25:22 joehw Exp $ */ class XSDComplexTypeTraverser extends XSDAbstractParticleTraverser { - + // size of stack to hold globals: private final static int GLOBAL_NUM = 11; - + // globals for building XSComplexTypeDecls private String fName = null; private String fTargetNamespace = null; @@ -82,27 +83,27 @@ private boolean fIsAbstract = false; private XSComplexTypeDecl fComplexTypeDecl = null; private XSAnnotationImpl [] fAnnotations = null; - + private XSParticleDecl fEmptyParticle = null; - + // our own little stack to retain state when getGlobalDecls is called: private Object [] fGlobalStore = null; private int fGlobalStorePos = 0; - + XSDComplexTypeTraverser (XSDHandler handler, XSAttributeChecker gAttrCheck) { super(handler, gAttrCheck); } - - + + private static final boolean DEBUG=false; - + private SchemaDVFactory schemaFactory = SchemaDVFactory.getInstance(); - + private class ComplexTypeRecoverableError extends Exception { - - private static final long serialVersionUID = 3762247556666831417L; - + + private static final long serialVersionUID = 6802729912091130335L; + Object[] errorSubstText=null; Element errorElem = null; ComplexTypeRecoverableError() { @@ -113,9 +114,9 @@ errorSubstText=args; errorElem = e; } - + } - + /** * Traverse local complexType declarations * @@ -127,8 +128,8 @@ XSComplexTypeDecl traverseLocal(Element complexTypeNode, XSDocumentInfo schemaDoc, SchemaGrammar grammar) { - - + + Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, false, schemaDoc); String complexTypeName = genAnonTypeName(complexTypeNode); @@ -140,10 +141,10 @@ grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode)); type.setIsAnonymous(); fAttrChecker.returnAttrArray(attrValues, schemaDoc); - + return type; } - + /** * Traverse global complexType declarations * @@ -155,7 +156,7 @@ XSComplexTypeDecl traverseGlobal (Element complexTypeNode, XSDocumentInfo schemaDoc, SchemaGrammar grammar) { - + Object[] attrValues = fAttrChecker.checkAttributes(complexTypeNode, true, schemaDoc); String complexTypeName = (String) attrValues[XSAttributeChecker.ATTIDX_NAME]; @@ -171,38 +172,38 @@ // need to add the type to the grammar for later constraint checking grammar.addComplexTypeDecl(type, fSchemaHandler.element2Locator(complexTypeNode)); fAttrChecker.returnAttrArray(attrValues, schemaDoc); - + return type; } - - + + private XSComplexTypeDecl traverseComplexTypeDecl(Element complexTypeDecl, String complexTypeName, Object[] attrValues, XSDocumentInfo schemaDoc, SchemaGrammar grammar) { - + fComplexTypeDecl = new XSComplexTypeDecl(); fAttrGrp = new XSAttributeGroupDecl(); Boolean abstractAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_ABSTRACT]; XInt blockAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_BLOCK]; Boolean mixedAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_MIXED]; XInt finalAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_FINAL]; - + fName = complexTypeName; fComplexTypeDecl.setName(fName); fTargetNamespace = schemaDoc.fTargetNamespace; - + fBlock = blockAtt == null ? schemaDoc.fBlockDefault : blockAtt.shortValue(); fFinal = finalAtt == null ? schemaDoc.fFinalDefault : finalAtt.shortValue(); //discard valid Block/Final 'Default' values that are invalid for Block/Final fBlock &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION); fFinal &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION); - + fIsAbstract = (abstractAtt != null && abstractAtt.booleanValue()); - + Element child = null; - + try { // --------------------------------------------------------------- // First, handle any ANNOTATION declaration and get next child @@ -238,7 +239,7 @@ // // EMPTY complexType with complexContent // - + // set the base to the anyType fBaseType = SchemaGrammar.fAnyType; processComplexContent(child, mixedAtt.booleanValue(), false, @@ -276,45 +277,45 @@ // GROUP, ALL, SEQUENCE or CHOICE, followed by optional attributes // Note that it's possible that only attributes are specified. // - + // set the base to the anyType fBaseType = SchemaGrammar.fAnyType; processComplexContent(child, mixedAtt.booleanValue(), false, schemaDoc, grammar); } - + } catch (ComplexTypeRecoverableError e) { handleComplexTypeError(e.getMessage(), e.errorSubstText, e.errorElem); } - + if (DEBUG) { System.out.println(fName); } fComplexTypeDecl.setValues(fName, fTargetNamespace, fBaseType, fDerivedBy, fFinal, fBlock, fContentType, fIsAbstract, - fAttrGrp, fXSSimpleType, fParticle, new XSObjectListImpl(fAnnotations, + fAttrGrp, fXSSimpleType, fParticle, new XSObjectListImpl(fAnnotations, fAnnotations == null? 0 : fAnnotations.length)); return fComplexTypeDecl; } - - + + private void traverseSimpleContent(Element simpleContentElement, XSDocumentInfo schemaDoc, SchemaGrammar grammar) throws ComplexTypeRecoverableError { - - + + Object[] simpleContentAttrValues = fAttrChecker.checkAttributes(simpleContentElement, false, schemaDoc); - + // ----------------------------------------------------------------------- // Set content type // ----------------------------------------------------------------------- fContentType = XSComplexTypeDecl.CONTENTTYPE_SIMPLE; fParticle = null; - + Element simpleContent = DOMUtil.getFirstChildElement(simpleContentElement); if (simpleContent != null && DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) { addAnnotation(traverseAnnotationDecl(simpleContent, simpleContentAttrValues, false, schemaDoc)); @@ -326,7 +327,7 @@ addAnnotation(traverseSyntheticAnnotation(simpleContentElement, text, simpleContentAttrValues, false, schemaDoc)); } } - + // If there are no children, return if (simpleContent==null) { fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); @@ -334,7 +335,7 @@ new Object[]{fName,SchemaSymbols.ELT_SIMPLECONTENT}, simpleContentElement); } - + // ----------------------------------------------------------------------- // The content should be either "restriction" or "extension" // ----------------------------------------------------------------------- @@ -357,12 +358,12 @@ new Object[]{fName,siblingName}, elemTmp); } - + Object [] derivationTypeAttrValues = fAttrChecker.checkAttributes(simpleContent, false, schemaDoc); QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE]; - - + + // ----------------------------------------------------------------------- // Need a base type. // ----------------------------------------------------------------------- @@ -372,7 +373,7 @@ throw new ComplexTypeRecoverableError("s4s-att-must-appear", new Object[]{simpleContentName, "base"}, simpleContent); } - + XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, baseTypeName, simpleContent); @@ -381,16 +382,16 @@ fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); throw new ComplexTypeRecoverableError(); } - + fBaseType = type; - + XSSimpleType baseValidator = null; XSComplexTypeDecl baseComplexType = null; int baseFinalSet = 0; - + // If the base type is complex, it must have simpleContent if ((type.getTypeCategory() == XSTypeDefinition.COMPLEX_TYPE)) { - + baseComplexType = (XSComplexTypeDecl)type; baseFinalSet = baseComplexType.getFinal(); // base is a CT with simple content (both restriction and extension are OK) @@ -420,7 +421,7 @@ } baseFinalSet=baseValidator.getFinal(); } - + // ----------------------------------------------------------------------- // Check that the base permits the derivation // ----------------------------------------------------------------------- @@ -432,7 +433,7 @@ throw new ComplexTypeRecoverableError(errorKey, new Object[]{fName, fBaseType.getName()}, simpleContent); } - + // ----------------------------------------------------------------------- // Skip over any potential annotations // ----------------------------------------------------------------------- @@ -440,7 +441,7 @@ simpleContent = DOMUtil.getFirstChildElement(simpleContent); if (simpleContent != null) { // traverse annotation if any - + if (DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)) { addAnnotation(traverseAnnotationDecl(simpleContent, derivationTypeAttrValues, false, schemaDoc)); simpleContent = DOMUtil.getNextSiblingElement(simpleContent); @@ -451,7 +452,7 @@ addAnnotation(traverseSyntheticAnnotation(scElement, text, derivationTypeAttrValues, false, schemaDoc)); } } - + if (simpleContent !=null && DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_ANNOTATION)){ fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); @@ -467,19 +468,19 @@ addAnnotation(traverseSyntheticAnnotation(scElement, text, derivationTypeAttrValues, false, schemaDoc)); } } - + // ----------------------------------------------------------------------- // Process a RESTRICTION // ----------------------------------------------------------------------- if (fDerivedBy == XSConstants.DERIVATION_RESTRICTION) { - + // ----------------------------------------------------------------------- // There may be a simple type definition in the restriction element // The data type validator will be based on it, if specified // ----------------------------------------------------------------------- if (simpleContent !=null && DOMUtil.getLocalName(simpleContent).equals(SchemaSymbols.ELT_SIMPLETYPE )) { - + XSSimpleType dv = fSchemaHandler.fSimpleTypeTraverser.traverseLocal( simpleContent, schemaDoc, grammar); if (dv == null) { @@ -489,7 +490,7 @@ } //check that this datatype validator is validly derived from the base //according to derivation-ok-restriction 5.1.2.1 - + if (baseValidator != null && !XSConstraints.checkSimpleDerivationOk(dv, baseValidator, baseValidator.getFinal())) { @@ -502,7 +503,7 @@ baseValidator = dv; simpleContent = DOMUtil.getNextSiblingElement(simpleContent); } - + // this only happens when restricting a mixed/emptiable CT // but there is no <simpleType>, which is required if (baseValidator == null) { @@ -511,7 +512,7 @@ throw new ComplexTypeRecoverableError("src-ct.2.2", new Object[]{fName}, simpleContent); } - + // ----------------------------------------------------------------------- // Traverse any facets // ----------------------------------------------------------------------- @@ -519,7 +520,7 @@ XSFacets facetData = null; short presentFacets = 0 ; short fixedFacets = 0 ; - + if (simpleContent!=null) { FacetInfo fi = traverseFacets(simpleContent, baseValidator, schemaDoc); attrNode = fi.nodeAfterFacets; @@ -527,7 +528,7 @@ presentFacets = fi.fPresentFacets; fixedFacets = fi.fFixedFacets; } - + fXSSimpleType = schemaFactory.createTypeRestriction(null,schemaDoc.fTargetNamespace,(short)0,baseValidator,null); try{ fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport); @@ -535,7 +536,7 @@ }catch(InvalidDatatypeFacetException ex){ reportSchemaError(ex.getKey(), ex.getArgs(), simpleContent); } - + // ----------------------------------------------------------------------- // Traverse any attributes // ----------------------------------------------------------------------- @@ -557,7 +558,7 @@ node); } } - + try { mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, false, simpleContentElement); } catch (ComplexTypeRecoverableError e) { @@ -567,7 +568,7 @@ } // Prohibited uses must be removed after merge for RESTRICTION fAttrGrp.removeProhibitedAttrs(); - + Object[] errArgs=fAttrGrp.validRestrictionOf(fName, baseComplexType.getAttrGrp()); if (errArgs != null) { fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); @@ -575,7 +576,7 @@ throw new ComplexTypeRecoverableError((String)errArgs[errArgs.length-1], errArgs, attrNode); } - + } // ----------------------------------------------------------------------- // Process a EXTENSION @@ -596,7 +597,7 @@ } Element node=traverseAttrsAndAttrGrps(attrNode,fAttrGrp, schemaDoc,grammar,fComplexTypeDecl); - + if (node!=null) { fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); @@ -607,7 +608,7 @@ // Remove prohibited uses. Should be done prior to any merge. fAttrGrp.removeProhibitedAttrs(); } - + if (baseComplexType != null) { try { mergeAttributes(baseComplexType.getAttrGrp(), fAttrGrp, fName, true, simpleContentElement); @@ -623,17 +624,17 @@ fAttrChecker.returnAttrArray(simpleContentAttrValues, schemaDoc); fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); } - + private void traverseComplexContent(Element complexContentElement, boolean mixedOnType, XSDocumentInfo schemaDoc, SchemaGrammar grammar) throws ComplexTypeRecoverableError { - - + + Object[] complexContentAttrValues = fAttrChecker.checkAttributes(complexContentElement, false, schemaDoc); - - + + // ----------------------------------------------------------------------- // Determine if this is mixed content // ----------------------------------------------------------------------- @@ -642,14 +643,14 @@ if (mixedAtt != null) { mixedContent = mixedAtt.booleanValue(); } - - + + // ----------------------------------------------------------------------- // Since the type must have complex content, set the simple type validators // to null // ----------------------------------------------------------------------- fXSSimpleType = null; - + Element complexContent = DOMUtil.getFirstChildElement(complexContentElement); if (complexContent != null && DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) { addAnnotation(traverseAnnotationDecl(complexContent, complexContentAttrValues, false, schemaDoc)); @@ -661,7 +662,7 @@ addAnnotation(traverseSyntheticAnnotation(complexContentElement, text, complexContentAttrValues, false, schemaDoc)); } } - + // If there are no children, return if (complexContent==null) { fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); @@ -669,7 +670,7 @@ new Object[]{fName,SchemaSymbols.ELT_COMPLEXCONTENT}, complexContentElement); } - + // ----------------------------------------------------------------------- // The content should be either "restriction" or "extension" // ----------------------------------------------------------------------- @@ -690,12 +691,12 @@ throw new ComplexTypeRecoverableError("s4s-elt-invalid-content.1", new Object[]{fName, siblingName}, elemTmp); } - + Object[] derivationTypeAttrValues = fAttrChecker.checkAttributes(complexContent, false, schemaDoc); QName baseTypeName = (QName) derivationTypeAttrValues[XSAttributeChecker.ATTIDX_BASE]; - - + + // ----------------------------------------------------------------------- // Need a base type. Check that it's a complex type // ----------------------------------------------------------------------- @@ -705,18 +706,18 @@ throw new ComplexTypeRecoverableError("s4s-att-must-appear", new Object[]{complexContentName, "base"}, complexContent); } - + XSTypeDefinition type = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, baseTypeName, complexContent); - + if (type==null) { fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); throw new ComplexTypeRecoverableError(); } - + if (! (type instanceof XSComplexTypeDecl)) { fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); @@ -725,7 +726,7 @@ } XSComplexTypeDecl baseType = (XSComplexTypeDecl)type; fBaseType = baseType; - + // ----------------------------------------------------------------------- // Check that the base permits the derivation // ----------------------------------------------------------------------- @@ -737,12 +738,12 @@ throw new ComplexTypeRecoverableError(errorKey, new Object[]{fName, fBaseType.getName()}, complexContent); } - + // ----------------------------------------------------------------------- // Skip over any potential annotations // ----------------------------------------------------------------------- complexContent = DOMUtil.getFirstChildElement(complexContent); - + if (complexContent != null) { // traverse annotation if any if (DOMUtil.getLocalName(complexContent).equals(SchemaSymbols.ELT_ANNOTATION)) { @@ -781,20 +782,20 @@ fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); throw e; } - + // ----------------------------------------------------------------------- // Compose the final content and attribute uses // ----------------------------------------------------------------------- XSParticleDecl baseContent = (XSParticleDecl)baseType.getParticle(); if (fDerivedBy==XSConstants.DERIVATION_RESTRICTION) { - + // This is an RESTRICTION - + // N.B. derivation-ok-restriction.5.3 is checked under schema // full checking. That's because we need to wait until locals are // traversed so that occurrence information is correct. - - + + if (fContentType == XSComplexTypeDecl.CONTENTTYPE_MIXED && baseType.getContentType() != XSComplexTypeDecl.CONTENTTYPE_MIXED) { fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); @@ -803,7 +804,7 @@ new Object[]{fName, baseType.getName()}, complexContent); } - + try { mergeAttributes(baseType.getAttrGrp(), fAttrGrp, fName, false, complexContent); } catch (ComplexTypeRecoverableError e) { @@ -813,7 +814,7 @@ } // Remove prohibited uses. Must be done after merge for RESTRICTION. fAttrGrp.removeProhibitedAttrs(); - + if (baseType != SchemaGrammar.fAnyType) { Object[] errArgs = fAttrGrp.validRestrictionOf(fName, baseType.getAttrGrp()); if (errArgs != null) { @@ -825,9 +826,9 @@ } } else { - + // This is an EXTENSION - + // Create the particle if (fParticle == null) { fContentType = baseType.getContentType(); @@ -854,7 +855,7 @@ throw new ComplexTypeRecoverableError("cos-ct-extends.1.4.3.2.2.1.b", new Object[]{fName}, complexContent); } - + // if the content of either type is an "all" model group, error. if (fParticle.fType == XSParticleDecl.PARTICLE_MODELGROUP && ((XSModelGroupImpl)fParticle.fValue).fCompositor == XSModelGroupImpl.MODELGROUP_ALL || @@ -876,10 +877,10 @@ XSParticleDecl particle = new XSParticleDecl(); particle.fType = XSParticleDecl.PARTICLE_MODELGROUP; particle.fValue = group; - + fParticle = particle; } - + // Remove prohibited uses. Must be done before merge for EXTENSION. fAttrGrp.removeProhibitedAttrs(); try { @@ -889,16 +890,16 @@ fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); throw e; } - + } - + // and *finally* we can legitimately return the attributes! fAttrChecker.returnAttrArray(complexContentAttrValues, schemaDoc); fAttrChecker.returnAttrArray(derivationTypeAttrValues, schemaDoc); - + } // end of traverseComplexContent - - + + // This method merges attribute uses from the base, into the derived set. // The first duplicate attribute, if any, is returned. // LM: may want to merge with attributeGroup processing. @@ -908,7 +909,7 @@ boolean extension, Element elem) throws ComplexTypeRecoverableError { - + XSObjectList attrUseS = fromAttrGrp.getAttributeUses(); XSAttributeUseImpl duplicateAttrUse = null, oneAttrUse = null; int attrCount = attrUseS.getLength(); @@ -917,7 +918,7 @@ XSAttributeUse existingAttrUse = toAttrGrp.getAttributeUse(oneAttrUse.fAttrDecl.getNamespace(), oneAttrUse.fAttrDecl.getName()); if (existingAttrUse == null) { - + String idName = toAttrGrp.addAttributeUse(oneAttrUse); if (idName != null) { throw new ComplexTypeRecoverableError("ct-props-correct.5", @@ -941,18 +942,18 @@ else if (fromAttrGrp.fAttributeWC != null) { toAttrGrp.fAttributeWC = toAttrGrp.fAttributeWC.performUnionWith(fromAttrGrp.fAttributeWC, toAttrGrp.fAttributeWC.fProcessContents); } - + } } - + private void processComplexContent(Element complexContentChild, boolean isMixed, boolean isDerivation, XSDocumentInfo schemaDoc, SchemaGrammar grammar) throws ComplexTypeRecoverableError { - + Element attrNode = null; XSParticleDecl particle = null; - + // whether there is a particle with empty model group boolean emptyParticle = false; if (complexContentChild != null) { @@ -960,12 +961,12 @@ // GROUP, ALL, SEQUENCE or CHOICE, followed by attributes, if specified. // Note that it's possible that only attributes are specified. // ------------------------------------------------------------- - - + + String childName = DOMUtil.getLocalName(complexContentChild); - + if (childName.equals(SchemaSymbols.ELT_GROUP)) { - + particle = fSchemaHandler.fGroupTraverser.traverseLocal(complexContentChild, schemaDoc, grammar); attrNode = DOMUtil.getNextSiblingElement(complexContentChild); @@ -1005,7 +1006,7 @@ attrNode = complexContentChild; } } - + // if the particle is empty because there is no non-annotation chidren, // we need to make the particle itself null (so that the effective // content is empty). @@ -1024,7 +1025,7 @@ // child != null means we might have seen an element with // minOccurs == maxOccurs == 0 } - + if (particle == null && isMixed) { if (fEmptyParticle == null) { XSModelGroupImpl group = new XSModelGroupImpl(); @@ -1038,7 +1039,7 @@ particle = fEmptyParticle; } fParticle = particle; - + // ----------------------------------------------------------------------- // Set the content type // ----------------------------------------------------------------------- @@ -1048,8 +1049,8 @@ fContentType = XSComplexTypeDecl.CONTENTTYPE_MIXED; else fContentType = XSComplexTypeDecl.CONTENTTYPE_ELEMENT; - - + + // ------------------------------------------------------------- // Now, process attributes // ------------------------------------------------------------- @@ -1072,15 +1073,15 @@ fAttrGrp.removeProhibitedAttrs(); } } - - - + + + } // end processComplexContent - - + + private boolean isAttrOrAttrGroup(Element e) { String elementName = DOMUtil.getLocalName(e); - + if (elementName.equals(SchemaSymbols.ELT_ATTRIBUTE) || elementName.equals(SchemaSymbols.ELT_ATTRIBUTEGROUP) || elementName.equals(SchemaSymbols.ELT_ANYATTRIBUTE)) @@ -1088,19 +1089,19 @@ else return false; } - + private void traverseSimpleContentDecl(Element simpleContentDecl) { } - + private void traverseComplexContentDecl(Element complexContentDecl, boolean mixedOnComplexTypeDecl) { } - + /* * Generate a name for an anonymous type */ private String genAnonTypeName(Element complexTypeDecl) { - + // Generate a unique name for the anonymous type by concatenating together the // names of parent nodes // The name is quite good for debugging/error purposes, but we may want to @@ -1113,15 +1114,15 @@ } return typeName.toString(); } - - + + private void handleComplexTypeError(String messageId,Object[] args, Element e) { - + if (messageId!=null) { reportSchemaError(messageId, args, e); } - + // // Mock up the typeInfo structure so that there won't be problems during // validation @@ -1132,11 +1133,11 @@ // REVISIT: do we need to remove all attribute uses already added into // the attribute group? maybe it's ok to leave them there. -SG fAttrGrp.fAttributeWC = getErrorWildcard(); - + return; - + } - + private XSParticleDecl getErrorContent() { XSParticleDecl particle = new XSParticleDecl(); particle.fType = XSParticleDecl.PARTICLE_WILDCARD; @@ -1151,16 +1152,16 @@ XSParticleDecl errorContent = new XSParticleDecl(); errorContent.fType = XSParticleDecl.PARTICLE_MODELGROUP; errorContent.fValue = group; - + return errorContent; } - + private XSWildcardDecl getErrorWildcard() { XSWildcardDecl errorWildcard = new XSWildcardDecl(); errorWildcard.fProcessContents = XSWildcardDecl.PC_SKIP; return errorWildcard; } - + private void contentBackup() { if(fGlobalStore == null) { fGlobalStore = new Object [GLOBAL_NUM]; @@ -1184,7 +1185,7 @@ fGlobalStore[fGlobalStorePos++] = fXSSimpleType; fGlobalStore[fGlobalStorePos++] = fAnnotations; } - + private void contentRestore() { fAnnotations = (XSAnnotationImpl [])fGlobalStore[--fGlobalStorePos]; fXSSimpleType = (XSSimpleType)fGlobalStore[--fGlobalStorePos]; @@ -1202,7 +1203,7 @@ fIsAbstract = ((Boolean)fGlobalStore[--fGlobalStorePos]).booleanValue(); fComplexTypeDecl = (XSComplexTypeDecl)fGlobalStore[--fGlobalStorePos]; } - + private void addAnnotation(XSAnnotationImpl annotation) { if(annotation == null) return;
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDElementTraverser.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDElementTraverser.java Wed Sep 28 17:10:18 2011 +0100 @@ -20,6 +20,8 @@ package com.sun.org.apache.xerces.internal.impl.xs.traversers; +import java.util.Locale; + import com.sun.org.apache.xerces.internal.impl.dv.ValidatedInfo; import com.sun.org.apache.xerces.internal.impl.dv.XSSimpleType; import com.sun.org.apache.xerces.internal.impl.xs.SchemaGrammar; @@ -60,24 +62,25 @@ * Content: (annotation?, ((simpleType | complexType)?, (unique | key | keyref)*)) * </element> * - * @xerces.internal + * @xerces.internal * * @author Sandy Gao, IBM * + * @version $Id: XSDElementTraverser.java,v 1.7 2010/07/23 02:09:30 joehw Exp $ */ class XSDElementTraverser extends XSDAbstractTraverser { - + protected final XSElementDecl fTempElementDecl = new XSElementDecl(); - + // this controls what happens when a local element is encountered. // We may not encounter all local elements when first parsing. boolean fDeferTraversingLocalElements; - + XSDElementTraverser (XSDHandler handler, XSAttributeChecker gAttrCheck) { super(handler, gAttrCheck); } - + /** * Traverse a locally declared element (or an element reference). * @@ -96,7 +99,7 @@ SchemaGrammar grammar, int allContextFlags, XSObject parent) { - + XSParticleDecl particle = null; if (fSchemaHandler.fDeclPool !=null) { particle = fSchemaHandler.fDeclPool.getParticleDecl(); @@ -126,10 +129,10 @@ if (particle.fType == XSParticleDecl.PARTICLE_EMPTY) particle = null; } - + return particle; } - + /** * Traverse a locally declared element (or an element reference). * @@ -145,23 +148,23 @@ int allContextFlags, XSObject parent, String[] localNSDecls) { - + if (localNSDecls != null) { schemaDoc.fNamespaceSupport.setEffectiveContext(localNSDecls); } - + // General Attribute Checking Object[] attrValues = fAttrChecker.checkAttributes(elmDecl, false, schemaDoc); - + QName refAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_REF]; XInt minAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_MINOCCURS]; XInt maxAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_MAXOCCURS]; - + XSElementDecl element = null; if (elmDecl.getAttributeNode(SchemaSymbols.ATT_REF) != null) { if (refAtt != null) { element = (XSElementDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ELEMENT_TYPE, refAtt, elmDecl); - + Element child = DOMUtil.getFirstChildElement(elmDecl); if (child != null && DOMUtil.getLocalName(child).equals(SchemaSymbols.ELT_ANNOTATION)) { // REVISIT: put this somewhere @@ -181,7 +184,7 @@ } else { element = traverseNamedElement(elmDecl, attrValues, schemaDoc, grammar, false, parent); } - + particle.fMinOccurs = minAtt.intValue(); particle.fMaxOccurs = maxAtt.intValue(); if (element != null) { @@ -195,10 +198,10 @@ checkOccurrences(particle, SchemaSymbols.ELT_ELEMENT, (Element)elmDecl.getParentNode(), allContextFlags, defaultVals.longValue()); - + fAttrChecker.returnAttrArray(attrValues, schemaDoc); } - + /** * Traverse a globally declared element. * @@ -210,16 +213,16 @@ XSElementDecl traverseGlobal(Element elmDecl, XSDocumentInfo schemaDoc, SchemaGrammar grammar) { - + // General Attribute Checking' Object[] attrValues = fAttrChecker.checkAttributes(elmDecl, true, schemaDoc); XSElementDecl element = traverseNamedElement(elmDecl, attrValues, schemaDoc, grammar, true, null); fAttrChecker.returnAttrArray(attrValues, schemaDoc); return element; - + } - + /** * Traverse a globally declared element. * @@ -236,7 +239,7 @@ SchemaGrammar grammar, boolean isGlobal, XSObject parent) { - + Boolean abstractAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_ABSTRACT]; XInt blockAtt = (XInt) attrValues[XSAttributeChecker.ATTIDX_BLOCK]; String defaultAtt = (String) attrValues[XSAttributeChecker.ATTIDX_DEFAULT]; @@ -247,9 +250,9 @@ Boolean nillableAtt = (Boolean) attrValues[XSAttributeChecker.ATTIDX_NILLABLE]; QName subGroupAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_SUBSGROUP]; QName typeAtt = (QName) attrValues[XSAttributeChecker.ATTIDX_TYPE]; - + // Step 1: get declaration information - + XSElementDecl element = null; if (fSchemaHandler.fDeclPool !=null) { element = fSchemaHandler.fDeclPool.getElementDecl(); @@ -259,7 +262,7 @@ // get 'name' if (nameAtt != null) element.fName = fSymbolTable.addSymbol(nameAtt); - + // get 'target namespace' if (isGlobal) { element.fTargetNamespace = schemaDoc.fTargetNamespace; @@ -268,7 +271,7 @@ else { if (parent instanceof XSComplexTypeDecl) element.setIsLocal((XSComplexTypeDecl)parent); - + if (formAtt != null) { if (formAtt.intValue() == SchemaSymbols.FORM_QUALIFIED) element.fTargetNamespace = schemaDoc.fTargetNamespace; @@ -280,7 +283,7 @@ element.fTargetNamespace = null; } } - + // get 'block', 'final', 'nillable', 'abstract' if (blockAtt == null) { // use defaults @@ -308,12 +311,12 @@ element.fFinal = finalAtt == null ? schemaDoc.fFinalDefault : finalAtt.shortValue(); // discard valid Final 'Default' values that are invalid for Final element.fFinal &= (XSConstants.DERIVATION_EXTENSION | XSConstants.DERIVATION_RESTRICTION); - + if (nillableAtt.booleanValue()) element.setIsNillable(); if (abstractAtt != null && abstractAtt.booleanValue()) element.setIsAbstract(); - + // get 'value constraint' if (fixedAtt != null) { element.fDefault = new ValidatedInfo(); @@ -326,12 +329,12 @@ } else { element.setConstraintType(XSConstants.VC_NONE); } - + // get 'substitutionGroup affiliation' if (subGroupAtt != null) { element.fSubGroup = (XSElementDecl)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.ELEMENT_TYPE, subGroupAtt, elmDecl); } - + // get 'annotation' Element child = DOMUtil.getFirstChildElement(elmDecl); XSAnnotationImpl annotation = null; @@ -346,15 +349,15 @@ } } element.fAnnotation = annotation; - + // get 'type definition' XSTypeDefinition elementType = null; boolean haveAnonType = false; - + // Handle Anonymous type if there is one if (child != null) { String childName = DOMUtil.getLocalName(child); - + if (childName.equals(SchemaSymbols.ELT_COMPLEXTYPE)) { elementType = fSchemaHandler.fComplexTypeTraverser.traverseLocal(child, schemaDoc, grammar); haveAnonType = true; @@ -366,25 +369,25 @@ child = DOMUtil.getNextSiblingElement(child); } } - + // Handler type attribute if (elementType == null && typeAtt != null) { elementType = (XSTypeDefinition)fSchemaHandler.getGlobalDecl(schemaDoc, XSDHandler.TYPEDECL_TYPE, typeAtt, elmDecl); } - + // Get it from the substitutionGroup declaration if (elementType == null && element.fSubGroup != null) { elementType = element.fSubGroup.fType; } - + if (elementType == null) { elementType = SchemaGrammar.fAnyType; } - + element.fType = elementType; - + // get 'identity constraint' - + // see if there's something here; it had better be key, keyref or unique. if (child != null) { String childName = DOMUtil.getLocalName(child); @@ -392,7 +395,7 @@ (childName.equals(SchemaSymbols.ELT_KEY) || childName.equals(SchemaSymbols.ELT_KEYREF) || childName.equals(SchemaSymbols.ELT_UNIQUE))) { - + if (childName.equals(SchemaSymbols.ELT_KEY) || childName.equals(SchemaSymbols.ELT_UNIQUE)) { // need to set <key>/<unique> to hidden before traversing it, @@ -415,13 +418,13 @@ } } } - + // Step 2: register the element decl to the grammar if (isGlobal && nameAtt != null) grammar.addGlobalElementDecl(element); - + // Step 3: check against schema for schemas - + // required attributes if (nameAtt == null) { if (isGlobal) @@ -430,39 +433,39 @@ reportSchemaError("src-element.2.1", null, elmDecl); nameAtt = NO_NAME; } - + // element if (child != null) { reportSchemaError("s4s-elt-must-match.1", new Object[]{nameAtt, "(annotation?, (simpleType | complexType)?, (unique | key | keyref)*))", DOMUtil.getLocalName(child)}, child); } - + // Step 4: check 3.3.3 constraints - + // src-element - + // 1 default and fixed must not both be present. if (defaultAtt != null && fixedAtt != null) { reportSchemaError("src-element.1", new Object[]{nameAtt}, elmDecl); } - + // 2 If the item's parent is not <schema>, then all of the following must be true: // 2.1 One of ref or name must be present, but not both. // This is checked in XSAttributeChecker - + // 2.2 If ref is present, then all of <complexType>, <simpleType>, <key>, <keyref>, <unique>, nillable, default, fixed, form, block and type must be absent, i.e. only minOccurs, maxOccurs, id are allowed in addition to ref, along with <annotation>. // Attributes are checked in XSAttributeChecker, elements are checked in "traverse" method - + // 3 type and either <simpleType> or <complexType> are mutually exclusive. if (haveAnonType && (typeAtt != null)) { reportSchemaError("src-element.3", new Object[]{nameAtt}, elmDecl); } - + // Step 5: check 3.3.6 constraints // check for NOTATION type checkNotationType(nameAtt, elementType, elmDecl); - + // e-props-correct - + // 2 If there is a {value constraint}, the canonical lexical representation of its value must be valid with respect to the {type definition} as defined in Element Default Valid (Immediate) (3.3.6). if (element.fDefault != null) { fValidationState.setNamespaceSupport(schemaDoc.fNamespaceSupport); @@ -471,14 +474,14 @@ element.setConstraintType(XSConstants.VC_NONE); } } - + // 4 If there is an {substitution group affiliation}, the {type definition} of the element declaration must be validly derived from the {type definition} of the {substitution group affiliation}, given the value of the {substitution group exclusions} of the {substitution group affiliation}, as defined in Type Derivation OK (Complex) (3.4.6) (if the {type definition} is complex) or as defined in Type Derivation OK (Simple) (3.14.6) (if the {type definition} is simple). if (element.fSubGroup != null) { if (!XSConstraints.checkTypeDerivationOk(element.fType, element.fSubGroup.fType, element.fSubGroup.fFinal)) { reportSchemaError ("e-props-correct.4", new Object[]{nameAtt, subGroupAtt.prefix+":"+subGroupAtt.localpart}, elmDecl); } } - + // 5 If the {type definition} or {type definition}'s {content type} is or is derived from ID then there must not be a {value constraint}. if (element.fDefault != null) { if ((elementType.getTypeCategory() == XSTypeDefinition.SIMPLE_TYPE && @@ -488,17 +491,17 @@ reportSchemaError ("e-props-correct.5", new Object[]{element.fName}, elmDecl); } } - + // Element without a name. Return null. if (element.fName == null) return null; - + return element; } - - void reset(SymbolTable symbolTable, boolean validateAnnotations) { - super.reset(symbolTable, validateAnnotations); + + void reset(SymbolTable symbolTable, boolean validateAnnotations, Locale locale) { + super.reset(symbolTable, validateAnnotations, locale); fDeferTraversingLocalElements = true; } // reset() - + }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java Wed Sep 28 17:10:18 2011 +0100 @@ -24,6 +24,7 @@ import java.io.StringReader; import java.util.ArrayList; import java.util.Hashtable; +import java.util.Locale; import java.util.Stack; import java.util.Vector; @@ -93,7 +94,7 @@ * @author Neil Graham, IBM * @author Pavani Mukthipudi, Sun Microsystems * - * @version $Id: XSDHandler.java,v 1.5 2007/07/29 20:47:06 joehw Exp $ + * @version $Id: XSDHandler.java,v 1.7 2010/07/23 02:09:30 joehw Exp $ */ public class XSDHandler { @@ -174,7 +175,11 @@ private static final String SECURE_PROCESSING = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; - + + /** Property identifier: locale. */ + protected static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + protected static final boolean DEBUG_NODE_POOL = false; // Data @@ -657,6 +662,9 @@ /** Set error handler. **/ XMLErrorHandler errorHandler = fErrorReporter.getErrorHandler(); fAnnotationValidator.setProperty(ERROR_HANDLER, (errorHandler != null) ? errorHandler : new DefaultErrorHandler()); + /** Set locale. **/ + Locale locale = fErrorReporter.getLocale(); + fAnnotationValidator.setProperty(LOCALE, locale); } /** @@ -1804,7 +1812,8 @@ } fSchemaParser.parse(schemaSource); - schemaElement = fSchemaParser.getDocument2() == null ? null: DOMUtil.getRoot(fSchemaParser.getDocument2()); + Document schemaDocument = fSchemaParser.getDocument(); + schemaElement = schemaDocument != null ? DOMUtil.getRoot(schemaDocument) : null; // now we need to store the mapping information from system id // to the document. also from the document to the system id. @@ -1926,17 +1935,18 @@ } // reset traversers + Locale locale = fErrorReporter.getLocale(); fAttributeChecker.reset(fSymbolTable); - fAttributeGroupTraverser.reset(fSymbolTable, fValidateAnnotations); - fAttributeTraverser.reset(fSymbolTable, fValidateAnnotations); - fComplexTypeTraverser.reset(fSymbolTable, fValidateAnnotations); - fElementTraverser.reset(fSymbolTable, fValidateAnnotations); - fGroupTraverser.reset(fSymbolTable, fValidateAnnotations); - fKeyrefTraverser.reset(fSymbolTable, fValidateAnnotations); - fNotationTraverser.reset(fSymbolTable, fValidateAnnotations); - fSimpleTypeTraverser.reset(fSymbolTable, fValidateAnnotations); - fUniqueOrKeyTraverser.reset(fSymbolTable, fValidateAnnotations); - fWildCardTraverser.reset(fSymbolTable, fValidateAnnotations); + fAttributeGroupTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fAttributeTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fComplexTypeTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fElementTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fGroupTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fKeyrefTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fNotationTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fSimpleTypeTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fUniqueOrKeyTraverser.reset(fSymbolTable, fValidateAnnotations, locale); + fWildCardTraverser.reset(fSymbolTable, fValidateAnnotations, locale); fRedefinedRestrictedAttributeGroupRegistry.clear(); fRedefinedRestrictedGroupRegistry.clear(); @@ -1972,13 +1982,20 @@ XMLErrorHandler currErrorHandler = fErrorReporter.getErrorHandler(); // Setting a parser property can be much more expensive // than checking its value. Don't set the ERROR_HANDLER - // property unless it's actually changed. + // or LOCALE properties unless they've actually changed. if (currErrorHandler != fSchemaParser.getProperty(ERROR_HANDLER)) { fSchemaParser.setProperty(ERROR_HANDLER, (currErrorHandler != null) ? currErrorHandler : new DefaultErrorHandler()); if (fAnnotationValidator != null) { fAnnotationValidator.setProperty(ERROR_HANDLER, (currErrorHandler != null) ? currErrorHandler : new DefaultErrorHandler()); } } + Locale currentLocale = fErrorReporter.getLocale(); + if (currentLocale != fSchemaParser.getProperty(LOCALE)) { + fSchemaParser.setProperty(LOCALE, currentLocale); + if (fAnnotationValidator != null) { + fAnnotationValidator.setProperty(LOCALE, currentLocale); + } + } } catch (XMLConfigurationException e) { }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DatatypeFactoryImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DatatypeFactoryImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -31,7 +31,7 @@ /** * <p>Factory that creates new <code>javax.xml.datatype</code> <code>Object</code>s that map XML to/from Java <code>Object</code>s.</p> - * + * * <p id="DatatypeFactory.newInstance">{@link #newInstance()} is used to create a new <code>DatatypeFactory</code>. * The following implementation resolution mechanisms are used in the following order:</p> * <ol> @@ -54,67 +54,68 @@ * {@link #DATATYPEFACTORY_IMPLEMENTATION_CLASS}, "<code>javax.xml.datatype.DatatypeFactoryImpl</code>". * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. * </li> - * </ol> - * + * </ol> + * * @author <a href="mailto:Joseph.Fialli@Sun.COM">Joseph Fialli</a> * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> + * @version $Id: DatatypeFactoryImpl.java,v 1.6 2010/05/19 05:02:55 joehw Exp $ */ public class DatatypeFactoryImpl - extends DatatypeFactory { - - /** - * <p>Public constructor is empty..</p> - * - * <p>Use {@link DatatypeFactory#newInstance()} to create a <code>DatatypeFactory</code>.</p> - */ - public DatatypeFactoryImpl() { - } + extends DatatypeFactory { + + /** + * <p>Public constructor is empty..</p> + * + * <p>Use {@link DatatypeFactory#newInstance()} to create a <code>DatatypeFactory</code>.</p> + */ + public DatatypeFactoryImpl() { + } - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS", - * as defined in XML Schema 1.0 section 3.2.6.1.</p> - * - * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> - * <blockquote> - * duration represents a duration of time. - * The value space of duration is a six-dimensional space where the coordinates designate the - * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. - * These components are ordered in their significance by their order of appearance i.e. as - * year, month, day, hour, minute, and second. - * </blockquote> + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS", + * as defined in XML Schema 1.0 section 3.2.6.1.</p> + * + * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> + * <blockquote> + * duration represents a duration of time. + * The value space of duration is a six-dimensional space where the coordinates designate the + * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. + * These components are ordered in their significance by their order of appearance i.e. as + * year, month, day, hour, minute, and second. + * </blockquote> * <p>All six values are set and availabe from the created {@link Duration}</p> - * + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * - * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>. - * - * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>. - * - * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>. - * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>. - */ - public Duration newDuration(final String lexicalRepresentation) { - - return new DurationImpl(lexicalRepresentation); - } - - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as milliseconds.</p> - * - * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> - * <blockquote> - * duration represents a duration of time. - * The value space of duration is a six-dimensional space where the coordinates designate the - * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. - * These components are ordered in their significance by their order of appearance i.e. as - * year, month, day, hour, minute, and second. - * </blockquote> + * + * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>. + * + * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>. + */ + public Duration newDuration(final String lexicalRepresentation) { + + return new DurationImpl(lexicalRepresentation); + } + + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as milliseconds.</p> + * + * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> + * <blockquote> + * duration represents a duration of time. + * The value space of duration is a six-dimensional space where the coordinates designate the + * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. + * These components are ordered in their significance by their order of appearance i.e. as + * year, month, day, hour, minute, and second. + * </blockquote> * <p>All six values are set by computing their values from the specified milliseconds * and are availabe using the <code>get</code> methods of the created {@link Duration}. * The values conform to and are defined by:</p> @@ -125,93 +126,395 @@ * </li> * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> * </ul> - * - * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., - * {@link java.util.Calendar#YEAR} = 1970, - * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, - * {@link java.util.Calendar#DATE} = 1, etc. - * This is important as there are variations in the Gregorian Calendar, - * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p> - * - * @param durationInMilliseconds Duration in milliseconds to create. - * - * @return New <code>Duration</code> representing <code>durationInMilliseconds</code>. - */ - public Duration newDuration(final long durationInMilliseconds) { + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p> + * + * @param durationInMilliseconds Duration in milliseconds to create. + * + * @return New <code>Duration</code> representing <code>durationInMilliseconds</code>. + */ + public Duration newDuration(final long durationInMilliseconds) { + + return new DurationImpl(durationInMilliseconds); + } + + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> + * + * <p>The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param years of this <code>Duration</code> + * @param months of this <code>Duration</code> + * @param days of this <code>Duration</code> + * @param hours of this <code>Duration</code> + * @param minutes of this <code>Duration</code> + * @param seconds of this <code>Duration</code> + * + * @return New <code>Duration</code> created from the specified values. + * + * @throws IllegalArgumentException If values are not a valid representation of a <code>Duration</code>. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If any values are <code>null</code>. + * + * @see #newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, + * BigInteger hours, BigInteger minutes, BigDecimal seconds) + */ + public Duration newDuration( + final boolean isPositive, + final BigInteger years, + final BigInteger months, + final BigInteger days, + final BigInteger hours, + final BigInteger minutes, + final BigDecimal seconds) { + + return new DurationImpl( + isPositive, + years, + months, + days, + hours, + minutes, + seconds + ); + } + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified + * <code>year</code> and <code>month</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.</p> + * + * <p>A <code>null</code> value indicates that field is not set.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param year Year of <code>Duration</code>. + * @param month Month of <code>Duration</code>. + * + * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if all of the fields (year, month) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public Duration newDurationYearMonth( + final boolean isPositive, + final BigInteger year, + final BigInteger month) { - return new DurationImpl(durationInMilliseconds); - } + return new DurationYearMonthImpl( + isPositive, + year, + month + ); - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> - * + } + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified + * <code>year</code> and <code>month</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param year Year of <code>Duration</code>. + * @param month Month of <code>Duration</code>. + * + * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if any of the fields (year, month) is negative. + */ + @Override + public Duration newDurationYearMonth( + final boolean isPositive, + final int year, + final int month) { + + return new DurationYearMonthImpl( + isPositive, + year, + month); + } + + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation, + * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> + * + * <p>Both values are set and availabe from the created {@link Duration}</p> + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> * - * @param isPositive Set to <code>false</code> to create a negative duration. When the length - * of the duration is zero, this parameter will be ignored. - * @param years of this <code>Duration</code> - * @param months of this <code>Duration</code> - * @param days of this <code>Duration</code> - * @param hours of this <code>Duration</code> - * @param minutes of this <code>Duration</code> - * @param seconds of this <code>Duration</code> - * - * @return New <code>Duration</code> created from the specified values. - * - * @throws IllegalArgumentException If values are not a valid representation of a <code>Duration</code>. - * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException If any values are <code>null</code>. - * - * @see #newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, - * BigInteger hours, BigInteger minutes, BigDecimal seconds) - */ - public Duration newDuration( - final boolean isPositive, - final BigInteger years, - final BigInteger months, - final BigInteger days, - final BigInteger hours, - final BigInteger minutes, - final BigDecimal seconds) { + * @param lexicalRepresentation Lexical representation of a duration. + * + * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of years and months. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + public Duration newDurationYearMonth( + final String lexicalRepresentation) { + + return new DurationYearMonthImpl(lexicalRepresentation); + + } + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> + * + * <p>Both values are set by computing their values from the specified milliseconds + * and are availabe using the <code>get</code> methods of the created {@link Duration}. + * The values conform to and are defined by:</p> + * <ul> + * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> + * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> + * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> + * </li> + * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> + * </ul> + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} can be influenced.</p> + * + * <p>Any remaining milliseconds after determining the year and month are discarded.</p> + * + * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. + * + * @return New <code>Duration</code> created using the specified <code>durationInMilliseconds</code>. + */ + public Duration newDurationYearMonth( + final long durationInMilliseconds) { + + return new DurationYearMonthImpl(durationInMilliseconds); + } + + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation, + * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * + * <p>All four values are set and availabe from the created {@link Duration}</p> + * + * <p>The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.</p> + * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of days and time. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + public Duration newDurationDayTime(final String lexicalRepresentation) { + // lexicalRepresentation must be non-null + if (lexicalRepresentation == null) { + throw new NullPointerException( + "Trying to create an xdt:dayTimeDuration with an invalid" + + " lexical representation of \"null\""); + } + + return new DurationDayTimeImpl(lexicalRepresentation); + } - return new DurationImpl( - isPositive, - years, - months, - days, - hours, - minutes, - seconds - ); - } + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * + * <p>All four values are set by computing their values from the specified milliseconds + * and are availabe using the <code>get</code> methods of the created {@link Duration}. + * The values conform to and are defined by:</p> + * <ul> + * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> + * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> + * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> + * </li> + * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> + * </ul> + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getDays()} can be influenced.</p> + * + * <p>Any remaining milliseconds after determining the day, hour, minute and second are discarded.</p> + * + * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. + * + * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>. + * + * @see <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a> + */ + public Duration newDurationDayTime(final long durationInMilliseconds) { + + return new DurationDayTimeImpl(durationInMilliseconds); + } - /** - * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p> - * + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified + * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * + * <p>The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.</p> + * + * <p>A <code>null</code> value indicates that field is not set.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param day Day of <code>Duration</code>. + * @param hour Hour of <code>Duration</code>. + * @param minute Minute of <code>Duration</code>. + * @param second Second of <code>Duration</code>. + * + * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> + * and <code>second</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if all the fields (day, hour, ...) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public Duration newDurationDayTime( + final boolean isPositive, + final BigInteger day, + final BigInteger hour, + final BigInteger minute, + final BigInteger second) { + + return new DurationDayTimeImpl( + isPositive, + day, + hour, + minute, + (second != null)? new BigDecimal(second):null + ); + } + + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified + * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * + * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param day Day of <code>Duration</code>. + * @param hour Hour of <code>Duration</code>. + * @param minute Minute of <code>Duration</code>. + * @param second Second of <code>Duration</code>. + * + * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> + * and <code>second</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if any of the fields (day, hour, ...) is negative. + */ + public Duration newDurationDayTime( + final boolean isPositive, + final int day, + final int hour, + final int minute, + final int second) { + + return new DurationDayTimeImpl( + isPositive, + day, + hour, + minute, + second + ); + } + + /** + * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p> + * * <p>All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.</p> - * + * * @return New <code>XMLGregorianCalendar</code> with all date/time datatype fields set to * {@link DatatypeConstants#FIELD_UNDEFINED} or null. - */ - public XMLGregorianCalendar newXMLGregorianCalendar() { - - return new XMLGregorianCalendarImpl(); - } - - /** - * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p> - * - * <p>Parsing the lexical string representation is defined in + */ + public XMLGregorianCalendar newXMLGregorianCalendar() { + + return new XMLGregorianCalendarImpl(); + } + + /** + * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p> + * + * <p>Parsing the lexical string representation is defined in * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1, * <em>Lexical Representation</em>.</a></p> - * + * * <p>The string representation may not have any leading and trailing whitespaces.</p> - * + * * <p>The parsing is done field by field so that * the following holds for any lexically correct String x:</p> * <pre> @@ -220,130 +523,130 @@ * <p>Except for the noted lexical/canonical representation mismatches * listed in <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-45"> * XML Schema 1.0 errata, Section 3.2.7.2</a>.</p> - * - * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. - * - * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>. - * - * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>. - * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. - */ - public XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation) { - - return new XMLGregorianCalendarImpl(lexicalRepresentation); - } + * + * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. + * + * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + public XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation) { + + return new XMLGregorianCalendarImpl(lexicalRepresentation); + } + + /** + * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p> + * + * <table border="2" rules="all" cellpadding="2"> + * <thead> + * <tr> + * <th align="center" colspan="2"> + * Field by Field Conversion from + * {@link GregorianCalendar} to an {@link XMLGregorianCalendar} + * </th> + * </tr> + * <tr> + * <th><code>java.util.GregorianCalendar</code> field</th> + * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td> + * <td>{@link XMLGregorianCalendar#setYear(int year)}</td> + * </tr> + * <tr> + * <td><code>MONTH + 1</code></td> + * <td>{@link XMLGregorianCalendar#setMonth(int month)}</td> + * </tr> + * <tr> + * <td><code>DAY_OF_MONTH</code></td> + * <td>{@link XMLGregorianCalendar#setDay(int day)}</td> + * </tr> + * <tr> + * <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td> + * <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td> + * </tr> + * <tr> + * <td> + * <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> + * <em>(in minutes)</em> + * </td> + * <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup> + * </td> + * </tr> + * </tbody> + * </table> + * <p><em>*</em>conversion loss of information. It is not possible to represent + * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the + * XML Schema 1.0 date/time datatype representation.</p> + * + * <p>To compute the return value's <code>TimeZone</code> field, + * <ul> + * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>, + * create a <code>java.util.TimeZone</code> with a custom timezone id + * using the <code>this.getTimezone()</code>.</li> + * <li>else use the <code>GregorianCalendar</code> default timezone value + * for the host is defined as specified by + * <code>java.util.TimeZone.getDefault()</code>.</li></p> + * + * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> + * + * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code> + * + * @throws NullPointerException If <code>cal</code> is <code>null</code>. + */ + public XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal) { + + return new XMLGregorianCalendarImpl(cal); + } - /** - * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p> - * - * <table border="2" rules="all" cellpadding="2"> - * <thead> - * <tr> - * <th align="center" colspan="2"> - * Field by Field Conversion from - * {@link GregorianCalendar} to an {@link XMLGregorianCalendar} - * </th> - * </tr> - * <tr> - * <th><code>java.util.GregorianCalendar</code> field</th> - * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> - * </tr> - * </thead> - * <tbody> - * <tr> - * <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td> - * <td>{@link XMLGregorianCalendar#setYear(int year)}</td> - * </tr> - * <tr> - * <td><code>MONTH + 1</code></td> - * <td>{@link XMLGregorianCalendar#setMonth(int month)}</td> - * </tr> - * <tr> - * <td><code>DAY_OF_MONTH</code></td> - * <td>{@link XMLGregorianCalendar#setDay(int day)}</td> - * </tr> - * <tr> - * <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td> - * <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td> - * </tr> - * <tr> - * <td> - * <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> - * <em>(in minutes)</em> - * </td> - * <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup> - * </td> - * </tr> - * </tbody> - * </table> - * <p><em>*</em>conversion loss of information. It is not possible to represent - * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the - * XML Schema 1.0 date/time datatype representation.</p> - * - * <p>To compute the return value's <code>TimeZone</code> field, - * <ul> - * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>, - * create a <code>java.util.TimeZone</code> with a custom timezone id - * using the <code>this.getTimezone()</code>.</li> - * <li>else use the <code>GregorianCalendar</code> default timezone value - * for the host is defined as specified by - * <code>java.util.TimeZone.getDefault()</code>.</li></p> - * - * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> - * - * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code> - * - * @throws NullPointerException If <code>cal</code> is <code>null</code>. - */ - public XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal) { - - return new XMLGregorianCalendarImpl(cal); - } - - /** - * <p>Constructor allowing for complete value spaces allowed by - * W3C XML Schema 1.0 recommendation for xsd:dateTime and related - * builtin datatypes. Note that <code>year</code> parameter supports - * arbitrarily large numbers and fractionalSecond has infinite - * precision.</p> - * - * @param year of <code>XMLGregorianCalendar</code> to be created. - * @param month of <code>XMLGregorianCalendar</code> to be created. - * @param day of <code>XMLGregorianCalendar</code> to be created. - * @param hour of <code>XMLGregorianCalendar</code> to be created. - * @param minute of <code>XMLGregorianCalendar</code> to be created. - * @param second of <code>XMLGregorianCalendar</code> to be created. - * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created. - * @param timezone of <code>XMLGregorianCalendar</code> to be created. - * - * @return <code>XMLGregorianCalendar</code> created from specified values. - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - * @throws NullPointerException If any parameters are <code>null</code>. - * - */ - public XMLGregorianCalendar newXMLGregorianCalendar( - final BigInteger year, - final int month, - final int day, - final int hour, - final int minute, - final int second, - final BigDecimal fractionalSecond, - final int timezone) { - - return new XMLGregorianCalendarImpl( - year, - month, - day, - hour, - minute, - second, - fractionalSecond, - timezone - ); - } + /** + * <p>Constructor allowing for complete value spaces allowed by + * W3C XML Schema 1.0 recommendation for xsd:dateTime and related + * builtin datatypes. Note that <code>year</code> parameter supports + * arbitrarily large numbers and fractionalSecond has infinite + * precision.</p> + * + * @param year of <code>XMLGregorianCalendar</code> to be created. + * @param month of <code>XMLGregorianCalendar</code> to be created. + * @param day of <code>XMLGregorianCalendar</code> to be created. + * @param hour of <code>XMLGregorianCalendar</code> to be created. + * @param minute of <code>XMLGregorianCalendar</code> to be created. + * @param second of <code>XMLGregorianCalendar</code> to be created. + * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created. + * @param timezone of <code>XMLGregorianCalendar</code> to be created. + * + * @return <code>XMLGregorianCalendar</code> created from specified values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + * @throws NullPointerException If any parameters are <code>null</code>. + * + */ + public XMLGregorianCalendar newXMLGregorianCalendar( + final BigInteger year, + final int month, + final int day, + final int hour, + final int minute, + final int second, + final BigDecimal fractionalSecond, + final int timezone) { + + return new XMLGregorianCalendarImpl( + year, + month, + day, + hour, + minute, + second, + fractionalSecond, + timezone + ); + } }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationDayTimeImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -0,0 +1,204 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 2010 Oracle and/or its affiliates. All rights reserved. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common Development + * and Distribution License("CDDL") (collectively, the "License"). You + * may not use this file except in compliance with the License. You can obtain + * a copy of the License at https://glassfish.dev.java.net/public/CDDL+GPL.html + * or glassfish/bootstrap/legal/LICENSE.txt. See the License for the specific + * language governing permissions and limitations under the License. + * + * When distributing the software, include this License Header Notice in each + * file and include the License file at glassfish/bootstrap/legal/LICENSE.txt. + * Oracle designates this particular file as subject to the "Classpath" exception + * as provided by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the License + * Header, with the fields enclosed by brackets [] replaced by your own + * identifying information: "Portions Copyrighted [year] + * [name of copyright owner]" + * + * Contributor(s): + * + * If you wish your version of this file to be governed by only the CDDL or + * only the GPL Version 2, indicate your decision by adding "[Contributor] + * elects to include this software in this distribution under the [CDDL or GPL + * Version 2] license." If you don't indicate a single choice of license, a + * recipient has the option to distribute your version of this file under + * either the CDDL, the GPL Version 2 or to extend the choice of license to + * its licensees as provided above. However, if you add GPL Version 2 code + * and therefore, elected the GPL Version 2 license, then the option applies + * only if the new code is made subject to such option by the copyright + * holder. + * + */ +package com.sun.org.apache.xerces.internal.jaxp.datatype; + + +import java.math.BigInteger; +import java.math.BigDecimal; +import javax.xml.datatype.DatatypeConstants; + +/** + * <p>Represent a subtype <code>xdt:dayTimeDuration</code> of a <code>Duration</code> + * as specified in <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * + * <p>The DurationYearMonth object represents a period of Gregorian time, + * with a lexical representation, "<em>PnDTnHnMnS</em>" that contains only year and month components. + * </p> + * + * + * @author <a href="mailto:Vikram.Aroskar@Sun.COM">Vikram Aroskar</a> + * @author <a href="mailto:Huizhe.wang@oracle.com">Joe Wang</a> + * @version $Revision: 1.2 $, $Date: 2010/05/19 23:20:06 $ + + * @see XMLGregorianCalendar#add(Duration) + */ + +class DurationDayTimeImpl + extends DurationImpl { + + public DurationDayTimeImpl( + boolean isPositive, + BigInteger days, + BigInteger hours, + BigInteger minutes, + BigDecimal seconds) { + + super(isPositive, null, null, days, hours, minutes, seconds); + convertToCanonicalDayTime(); + } + + public DurationDayTimeImpl( + boolean isPositive, + int days, + int hours, + int minutes, + int seconds) { + + this( + isPositive, + wrap(days), + wrap(hours), + wrap(minutes), + (seconds != DatatypeConstants.FIELD_UNDEFINED ? new BigDecimal(String.valueOf(seconds)) : null)); + } + + /** + * <p>Construct a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation, + * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * + * <p>All four values are set and availabe from the created {@link Duration}</p> + * + * <p>The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.</p> + * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of days and time. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + protected DurationDayTimeImpl(String lexicalRepresentation) { + super(lexicalRepresentation); + + if (getYears() > 0 || getMonths() > 0) { + throw new IllegalArgumentException( + "Trying to create an xdt:dayTimeDuration with an invalid" + + " lexical representation of \"" + lexicalRepresentation + + "\", data model requires a format PnDTnHnMnS."); + } + + convertToCanonicalDayTime(); + } + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * + * <p>All four values are set by computing their values from the specified milliseconds + * and are availabe using the <code>get</code> methods of the created {@link Duration}. + * The values conform to and are defined by:</p> + * <ul> + * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> + * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> + * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> + * </li> + * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> + * </ul> + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getDays()} can be influenced.</p> + * + * <p>Any remaining milliseconds after determining the day, hour, minute and second are discarded.</p> + * + * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. + * + * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>. + * + * @see <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a> + */ + protected DurationDayTimeImpl(final long durationInMilliseconds) { + super(durationInMilliseconds); + convertToCanonicalDayTime(); + // only day, hour, minute, and second should have values + years = null; + months = null; + } + + + /** + * The value space of xs:dayTimeDuration is the set of fractional second values. + * @return fractional second values + */ + public float getValue() { + float sec = (seconds==null)?0:seconds.floatValue(); + return (((((getDays() * 24) + + getHours()) * 60) + + getMinutes())*60) + + sec; + } + + private void convertToCanonicalDayTime() { + + while (getSeconds() >= 60) + { + seconds = seconds.subtract(BigDecimal.valueOf(60)); + minutes = BigInteger.valueOf((long) getMinutes()).add(BigInteger.ONE); + } + + while (getMinutes() >= 60) + { + minutes = minutes.subtract(BigInteger.valueOf(60)); + hours = BigInteger.valueOf((long) getHours()).add(BigInteger.ONE); + } + + while (getHours() >= 24) + { + hours = hours.subtract(BigInteger.valueOf(24)); + days = BigInteger.valueOf((long) getDays()).add(BigInteger.ONE); + } + } + +}
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -39,20 +39,20 @@ /** * <p>Immutable representation of a time span as defined in * the W3C XML Schema 1.0 specification.</p> - * + * * <p>A Duration object represents a period of Gregorian time, * which consists of six fields (years, months, days, hours, * minutes, and seconds) plus a sign (+/-) field.</p> - * + * * <p>The first five fields have non-negative (>=0) integers or null * (which represents that the field is not set), * and the seconds field has a non-negative decimal or null. - * A negative sign indicates a negative duration.</p> - * + * A negative sign indicates a negative duration.</p> + * * <p>This class provides a number of methods that make it easy * to use for the duration datatype of XML Schema 1.0 with * the errata.</p> - * + * * <h2>Order relationship</h2> * <p>Duration objects only have partial order, where two values A and B * maybe either:</p> @@ -65,12 +65,12 @@ * <p>For example, 30 days cannot be meaningfully compared to one month. * The {@link #compare(Duration)} method implements this * relationship.</p> - * + * * <p>See the {@link #isLongerThan(Duration)} method for details about * the order relationship among {@link Duration} objects.</p> - * - * - * + * + * + * * <h2>Operations over Duration</h2> * <p>This class provides a set of basic arithmetic operations, such * as addition, subtraction and multiplication. @@ -78,127 +78,133 @@ * fail for some combinations of operations. For example, you cannot * subtract 15 days from 1 month. See the javadoc of those methods * for detailed conditions where this could happen.</p> - * + * * <p>Also, division of a duration by a number is not provided because * the {@link Duration} class can only deal with finite precision - * decimal numbers. For example, one cannot represent 1 sec divided by 3.</p> - * + * decimal numbers. For example, one cannot represent 1 sec divided by 3.</p> + * * <p>However, you could substitute a division by 3 with multiplying * by numbers such as 0.3 or 0.333.</p> * * - * + * * <h2>Range of allowed values</h2> * <p> * Because some operations of {@link Duration} rely on {@link Calendar} * even though {@link Duration} can hold very large or very small values, * some of the methods may not work correctly on such {@link Duration}s. * The impacted methods document their dependency on {@link Calendar}. - * - * + * + * * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> * @author <a href="mailto:Joseph.Fialli@Sun.com">Joseph Fialli</a> + * @version $Revision: 1.8 $, $Date: 2010/05/19 23:20:06 $ * @see XMLGregorianCalendar#add(Duration) */ class DurationImpl - extends Duration - implements Serializable { - + extends Duration + implements Serializable { + /** * <p>Number of Fields.</p> */ private static final int FIELD_NUM = 6; - + /** * <p>Internal array of value Fields.</p> */ - private static final DatatypeConstants.Field[] FIELDS = new DatatypeConstants.Field[]{ - DatatypeConstants.YEARS, - DatatypeConstants.MONTHS, - DatatypeConstants.DAYS, - DatatypeConstants.HOURS, - DatatypeConstants.MINUTES, - DatatypeConstants.SECONDS - }; + private static final DatatypeConstants.Field[] FIELDS = new DatatypeConstants.Field[]{ + DatatypeConstants.YEARS, + DatatypeConstants.MONTHS, + DatatypeConstants.DAYS, + DatatypeConstants.HOURS, + DatatypeConstants.MINUTES, + DatatypeConstants.SECONDS + }; - /** - * <p>Internal array of value Field ids.</p> - */ - private static final int[] FIELD_IDS = { - DatatypeConstants.YEARS.getId(), - DatatypeConstants.MONTHS.getId(), - DatatypeConstants.DAYS.getId(), - DatatypeConstants.HOURS.getId(), - DatatypeConstants.MINUTES.getId(), - DatatypeConstants.SECONDS.getId() - }; - + /** + * <p>Internal array of value Field ids.</p> + */ + private static final int[] FIELD_IDS = { + DatatypeConstants.YEARS.getId(), + DatatypeConstants.MONTHS.getId(), + DatatypeConstants.DAYS.getId(), + DatatypeConstants.HOURS.getId(), + DatatypeConstants.MINUTES.getId(), + DatatypeConstants.SECONDS.getId() + }; + /** * TimeZone for GMT. */ private static final TimeZone GMT = TimeZone.getTimeZone("GMT"); - /** - * <p>BigDecimal value of 0.</p> - */ - private static final BigDecimal ZERO = BigDecimal.valueOf((long) 0); + /** + * <p>BigDecimal value of 0.</p> + */ + private static final BigDecimal ZERO = BigDecimal.valueOf((long) 0); /** * <p>Indicates the sign. -1, 0 or 1 if the duration is negative, * zero, or positive.</p> */ - private final int signum; - + protected int signum; + /** * <p>Years of this <code>Duration</code>.</p> */ - private final BigInteger years; - + /** + * These were final since Duration is immutable. But new subclasses need + * to be able to set after conversion. It won't break the immutable nature + * of them since there's no other way to set new values to them + */ + protected BigInteger years; + /** * <p>Months of this <code>Duration</code>.</p> */ - private final BigInteger months; - + protected BigInteger months; + /** * <p>Days of this <code>Duration</code>.</p> */ - private final BigInteger days; - + protected BigInteger days; + /** * <p>Hours of this <code>Duration</code>.</p> */ - private final BigInteger hours; - + protected BigInteger hours; + /** * <p>Minutes of this <code>Duration</code>.</p> */ - private final BigInteger minutes; - + protected BigInteger minutes; + /** * <p>Seconds of this <code>Duration</code>.</p> */ - private final BigDecimal seconds; - - /** - * Returns the sign of this duration in -1,0, or 1. - * - * @return - * -1 if this duration is negative, 0 if the duration is zero, - * and 1 if the duration is postive. - */ - public int getSign() { + protected BigDecimal seconds; - return signum; - } + /** + * Returns the sign of this duration in -1,0, or 1. + * + * @return + * -1 if this duration is negative, 0 if the duration is zero, + * and 1 if the duration is postive. + */ + public int getSign() { + + return signum; + } - /** - * TODO: Javadoc - * @param isPositive Sign. - * - * @return 1 if positive, else -1. - */ - private int calcSignum(boolean isPositive) { + /** + * TODO: Javadoc + * @param isPositive Sign. + * + * @return 1 if positive, else -1. + */ + protected int calcSignum(boolean isPositive) { if ((years == null || years.signum() == 0) && (months == null || months.signum() == 0) && (days == null || days.signum() == 0) @@ -215,13 +221,13 @@ } } - + /** * <p>Constructs a new Duration object by specifying each field individually.</p> - * + * * <p>All the parameters are optional as long as at least one field is present. * If specified, parameters have to be zero or positive.</p> - * + * * @param isPositive Set to <code>false</code> to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. * @param years of this <code>Duration</code> @@ -230,7 +236,7 @@ * @param hours of this <code>Duration</code> * @param minutes of this <code>Duration</code> * @param seconds of this <code>Duration</code> - * + * * @throws IllegalArgumentException * If years, months, days, hours, minutes and * seconds parameters are all <code>null</code>. Or if any @@ -244,7 +250,7 @@ BigInteger hours, BigInteger minutes, BigDecimal seconds) { - + this.years = years; this.months = months; this.days = days; @@ -273,48 +279,48 @@ testNonNegative(minutes, DatatypeConstants.MINUTES); testNonNegative(seconds, DatatypeConstants.SECONDS); } - + /** * <p>Makes sure that the given number is non-negative. If it is not, * throw {@link IllegalArgumentException}.</p> - * + * * @param n Number to test. * @param f Field to test. */ - private static void testNonNegative(BigInteger n, DatatypeConstants.Field f) { + protected static void testNonNegative(BigInteger n, DatatypeConstants.Field f) { if (n != null && n.signum() < 0) { - throw new IllegalArgumentException( + throw new IllegalArgumentException( DatatypeMessageFormatter.formatMessage(null, "NegativeField", new Object[]{f.toString()}) ); } } - + /** * <p>Makes sure that the given number is non-negative. If it is not, * throw {@link IllegalArgumentException}.</p> - * + * * @param n Number to test. * @param f Field to test. */ - private static void testNonNegative(BigDecimal n, DatatypeConstants.Field f) { + protected static void testNonNegative(BigDecimal n, DatatypeConstants.Field f) { if (n != null && n.signum() < 0) { - + throw new IllegalArgumentException( - DatatypeMessageFormatter.formatMessage(null, "NegativeField", new Object[]{f.toString()}) + DatatypeMessageFormatter.formatMessage(null, "NegativeField", new Object[]{f.toString()}) ); } } - + /** * <p>Constructs a new Duration object by specifying each field * individually.</p> - * + * * <p>This method is functionally equivalent to * invoking another constructor by wrapping * all non-zero parameters into {@link BigInteger} and {@link BigDecimal}. * Zero value of int parameter is equivalent of null value of - * the corresponding field.</p> - * + * the corresponding field.</p> + * * @see #DurationImpl(boolean, BigInteger, BigInteger, BigInteger, BigInteger, * BigInteger, BigDecimal) */ @@ -333,27 +339,27 @@ wrap(days), wrap(hours), wrap(minutes), - seconds != 0 ? new BigDecimal(String.valueOf(seconds)) : null); + seconds != DatatypeConstants.FIELD_UNDEFINED ? new BigDecimal(String.valueOf(seconds)) : null); } - /** - * TODO: Javadoc - * - * @param i int to convert to BigInteger. - * - * @return BigInteger representation of int. - */ - private static BigInteger wrap(final int i) { - - // field may not be set - if (i == DatatypeConstants.FIELD_UNDEFINED) { - return null; - } - - // int -> BigInteger + /** + * TODO: Javadoc + * + * @param i int to convert to BigInteger. + * + * @return BigInteger representation of int. + */ + protected static BigInteger wrap(final int i) { + + // field may not be set + if (i == DatatypeConstants.FIELD_UNDEFINED) { + return null; + } + + // int -> BigInteger return new BigInteger(String.valueOf(i)); } - + /** * <p>Constructs a new Duration object by specifying the duration * in milliseconds.</p> @@ -417,22 +423,22 @@ * Constructs a new Duration object by * parsing its string representation * "PnYnMnDTnHnMnS" as defined in XML Schema 1.0 section 3.2.6.1. - * + * * <p> * The string representation may not have any leading * and trailing whitespaces. - * + * * <p> * For example, this method parses strings like * "P1D" (1 day), "-PT100S" (-100 sec.), "P1DT12H" (1 days and 12 hours). - * + * * <p> - * The parsing is done field by field so that + * The parsing is done field by field so that * the following holds for any lexically correct string x: * <pre> * new Duration(x).toString().equals(x) * </pre> - * + * * Returns a non-null valid duration object that holds the value * indicated by the lexicalRepresentation parameter. * @@ -447,30 +453,30 @@ protected DurationImpl(String lexicalRepresentation) throws IllegalArgumentException { // only if I could use the JDK1.4 regular expression .... - + final String s = lexicalRepresentation; boolean positive; int[] idx = new int[1]; - int length = s.length(); - boolean timeRequired = false; - - if (lexicalRepresentation == null) { - throw new NullPointerException(); - } + int length = s.length(); + boolean timeRequired = false; - idx[0] = 0; - if (length != idx[0] && s.charAt(idx[0]) == '-') { - idx[0]++; - positive = false; - } else { - positive = true; - } + if (lexicalRepresentation == null) { + throw new NullPointerException(); + } + + idx[0] = 0; + if (length != idx[0] && s.charAt(idx[0]) == '-') { + idx[0]++; + positive = false; + } else { + positive = true; + } + + if (length != idx[0] && s.charAt(idx[0]++) != 'P') { + throw new IllegalArgumentException(s); //,idx[0]-1); + } - if (length != idx[0] && s.charAt(idx[0]++) != 'P') { - throw new IllegalArgumentException(s); //,idx[0]-1); - } - - + // phase 1: chop the string into chunks // (where a chunk is '<number><a symbol>' //-------------------------------------- @@ -483,15 +489,15 @@ datePartsIndex[dateLen] = idx[0]; dateParts[dateLen++] = parsePiece(s, idx); } - - if (length != idx[0]) { - if (s.charAt(idx[0]++) == 'T') { - timeRequired = true; - } else { - throw new IllegalArgumentException(s); // ,idx[0]-1); - } - } - + + if (length != idx[0]) { + if (s.charAt(idx[0]++) == 'T') { + timeRequired = true; + } else { + throw new IllegalArgumentException(s); // ,idx[0]-1); + } + } + int timeLen = 0; String[] timeParts = new String[3]; int[] timePartsIndex = new int[3]; @@ -501,10 +507,10 @@ timePartsIndex[timeLen] = idx[0]; timeParts[timeLen++] = parsePiece(s, idx); } - - if (timeRequired && timeLen == 0) { + + if (timeRequired && timeLen == 0) { throw new IllegalArgumentException(s); // ,idx[0]); - } + } if (length != idx[0]) { throw new IllegalArgumentException(s); // ,idx[0]); @@ -512,12 +518,12 @@ if (dateLen == 0 && timeLen == 0) { throw new IllegalArgumentException(s); // ,idx[0]); } - + // phase 2: check the ordering of chunks //-------------------------------------- organizeParts(s, dateParts, datePartsIndex, dateLen, "YMD"); organizeParts(s, timeParts, timePartsIndex, timeLen, "HMS"); - + // parse into numbers years = parseBigInteger(s, dateParts[0], datePartsIndex[0]); months = parseBigInteger(s, dateParts[1], datePartsIndex[1]); @@ -527,38 +533,38 @@ seconds = parseBigDecimal(s, timeParts[2], timePartsIndex[2]); signum = calcSignum(positive); } - - + + /** * TODO: Javadoc - * + * * @param ch char to test. - * + * * @return true if ch is a digit, else false. */ private static boolean isDigit(char ch) { return '0' <= ch && ch <= '9'; } - + /** * TODO: Javadoc - * + * * @param ch to test. - * + * * @return true if ch is a digit or a period, else false. */ private static boolean isDigitOrPeriod(char ch) { return isDigit(ch) || ch == '.'; } - + /** * TODO: Javadoc - * + * * @param whole String to parse. * @param idx TODO: ??? - * + * * @return Result of parsing. - * + * * @throws IllegalArgumentException If whole cannot be parsed. */ private static String parsePiece(String whole, int[] idx) @@ -576,16 +582,16 @@ return whole.substring(start, idx[0]); } - + /** * TODO: Javadoc. - * + * * @param whole TODO: ??? * @param parts TODO: ??? * @param partsIndex TODO: ??? * @param len TODO: ??? * @param tokens TODO: ??? - * + * * @throws IllegalArgumentException TODO: ??? */ private static void organizeParts( @@ -618,16 +624,16 @@ parts[idx] = null; } } - + /** * TODO: Javadoc - * + * * @param whole TODO: ???. * @param part TODO: ???. * @param index TODO: ???. - * + * * @return TODO: ???. - * + * * @throws IllegalArgumentException TODO: ???. */ private static BigInteger parseBigInteger( @@ -645,16 +651,16 @@ // throw new ParseException( whole, index ); // } } - + /** * TODO: Javadoc. - * + * * @param whole TODO: ???. * @param part TODO: ???. * @param index TODO: ???. - * + * * @return TODO: ???. - * + * * @throws IllegalArgumentException TODO: ???. */ private static BigDecimal parseBigDecimal( @@ -673,7 +679,7 @@ // throw new ParseException( whole, index ); // } } - + /** * <p>Four constants defined for the comparison of durations.</p> */ @@ -683,213 +689,213 @@ XMLGregorianCalendarImpl.parse("1903-03-01T00:00:00Z"), XMLGregorianCalendarImpl.parse("1903-07-01T00:00:00Z") }; - - /** - * <p>Partial order relation comparison with this <code>Duration</code> instance.</p> - * - * <p>Comparison result must be in accordance with - * <a href="http://www.w3.org/TR/xmlschema-2/#duration-order">W3C XML Schema 1.0 Part 2, Section 3.2.7.6.2, - * <i>Order relation on duration</i></a>.</p> - * - * <p>Return:</p> - * <ul> - * <li>{@link DatatypeConstants#LESSER} if this <code>Duration</code> is shorter than <code>duration</code> parameter</li> - * <li>{@link DatatypeConstants#EQUAL} if this <code>Duration</code> is equal to <code>duration</code> parameter</li> - * <li>{@link DatatypeConstants#GREATER} if this <code>Duration</code> is longer than <code>duration</code> parameter</li> - * <li>{@link DatatypeConstants#INDETERMINATE} if a conclusive partial order relation cannot be determined</li> - * </ul> - * - * @param duration to compare - * - * @return the relationship between <code>this</code> <code>Duration</code>and <code>duration</code> parameter as - * {@link DatatypeConstants#LESSER}, {@link DatatypeConstants#EQUAL}, {@link DatatypeConstants#GREATER} - * or {@link DatatypeConstants#INDETERMINATE}. - * - * @throws UnsupportedOperationException If the underlying implementation - * cannot reasonably process the request, e.g. W3C XML Schema allows for - * arbitrarily large/small/precise values, the request may be beyond the - * implementations capability. - * @throws NullPointerException if <code>duration</code> is <code>null</code>. - * - * @see #isShorterThan(Duration) - * @see #isLongerThan(Duration) - */ + + /** + * <p>Partial order relation comparison with this <code>Duration</code> instance.</p> + * + * <p>Comparison result must be in accordance with + * <a href="http://www.w3.org/TR/xmlschema-2/#duration-order">W3C XML Schema 1.0 Part 2, Section 3.2.7.6.2, + * <i>Order relation on duration</i></a>.</p> + * + * <p>Return:</p> + * <ul> + * <li>{@link DatatypeConstants#LESSER} if this <code>Duration</code> is shorter than <code>duration</code> parameter</li> + * <li>{@link DatatypeConstants#EQUAL} if this <code>Duration</code> is equal to <code>duration</code> parameter</li> + * <li>{@link DatatypeConstants#GREATER} if this <code>Duration</code> is longer than <code>duration</code> parameter</li> + * <li>{@link DatatypeConstants#INDETERMINATE} if a conclusive partial order relation cannot be determined</li> + * </ul> + * + * @param duration to compare + * + * @return the relationship between <code>this</code> <code>Duration</code>and <code>duration</code> parameter as + * {@link DatatypeConstants#LESSER}, {@link DatatypeConstants#EQUAL}, {@link DatatypeConstants#GREATER} + * or {@link DatatypeConstants#INDETERMINATE}. + * + * @throws UnsupportedOperationException If the underlying implementation + * cannot reasonably process the request, e.g. W3C XML Schema allows for + * arbitrarily large/small/precise values, the request may be beyond the + * implementations capability. + * @throws NullPointerException if <code>duration</code> is <code>null</code>. + * + * @see #isShorterThan(Duration) + * @see #isLongerThan(Duration) + */ public int compare(Duration rhs) { - - BigInteger maxintAsBigInteger = BigInteger.valueOf((long) Integer.MAX_VALUE); - BigInteger minintAsBigInteger = BigInteger.valueOf((long) Integer.MIN_VALUE); - - // check for fields that are too large in this Duration - if (years != null && years.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", - new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.YEARS.toString(), years.toString()}) - //this.getClass().getName() + "#compare(Duration duration)" - //+ " years too large to be supported by this implementation " - //+ years.toString() - ); - } - if (months != null && months.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", - new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MONTHS.toString(), months.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " months too large to be supported by this implementation " - //+ months.toString() - ); - } - if (days != null && days.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", - new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.DAYS.toString(), days.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " days too large to be supported by this implementation " - //+ days.toString() - ); - } - if (hours != null && hours.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", - new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.HOURS.toString(), hours.toString()}) + + BigInteger maxintAsBigInteger = BigInteger.valueOf((long) Integer.MAX_VALUE); + BigInteger minintAsBigInteger = BigInteger.valueOf((long) Integer.MIN_VALUE); - //this.getClass().getName() + "#compare(Duration duration)" - //+ " hours too large to be supported by this implementation " - //+ hours.toString() - ); - } - if (minutes != null && minutes.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + // check for fields that are too large in this Duration + if (years != null && years.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", + new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.YEARS.toString(), years.toString()}) + //this.getClass().getName() + "#compare(Duration duration)" + //+ " years too large to be supported by this implementation " + //+ years.toString() + ); + } + if (months != null && months.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", + new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MONTHS.toString(), months.toString()}) + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " months too large to be supported by this implementation " + //+ months.toString() + ); + } + if (days != null && days.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", + new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.DAYS.toString(), days.toString()}) + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " days too large to be supported by this implementation " + //+ days.toString() + ); + } + if (hours != null && hours.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", + new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.HOURS.toString(), hours.toString()}) + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " hours too large to be supported by this implementation " + //+ hours.toString() + ); + } + if (minutes != null && minutes.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MINUTES.toString(), minutes.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " minutes too large to be supported by this implementation " - //+ minutes.toString() - ); - } - if (seconds != null && seconds.toBigInteger().compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " minutes too large to be supported by this implementation " + //+ minutes.toString() + ); + } + if (seconds != null && seconds.toBigInteger().compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.SECONDS.toString(), seconds.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " seconds too large to be supported by this implementation " - //+ seconds.toString() - ); - } - - // check for fields that are too large in rhs Duration - BigInteger rhsYears = (BigInteger) rhs.getField(DatatypeConstants.YEARS); - if (rhsYears != null && rhsYears.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " seconds too large to be supported by this implementation " + //+ seconds.toString() + ); + } + + // check for fields that are too large in rhs Duration + BigInteger rhsYears = (BigInteger) rhs.getField(DatatypeConstants.YEARS); + if (rhsYears != null && rhsYears.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.YEARS.toString(), rhsYears.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " years too large to be supported by this implementation " - //+ rhsYears.toString() - ); - } - BigInteger rhsMonths = (BigInteger) rhs.getField(DatatypeConstants.MONTHS); - if (rhsMonths != null && rhsMonths.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " years too large to be supported by this implementation " + //+ rhsYears.toString() + ); + } + BigInteger rhsMonths = (BigInteger) rhs.getField(DatatypeConstants.MONTHS); + if (rhsMonths != null && rhsMonths.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MONTHS.toString(), rhsMonths.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " months too large to be supported by this implementation " - //+ rhsMonths.toString() - ); - } - BigInteger rhsDays = (BigInteger) rhs.getField(DatatypeConstants.DAYS); - if (rhsDays != null && rhsDays.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " months too large to be supported by this implementation " + //+ rhsMonths.toString() + ); + } + BigInteger rhsDays = (BigInteger) rhs.getField(DatatypeConstants.DAYS); + if (rhsDays != null && rhsDays.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.DAYS.toString(), rhsDays.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " days too large to be supported by this implementation " - //+ rhsDays.toString() - ); - } - BigInteger rhsHours = (BigInteger) rhs.getField(DatatypeConstants.HOURS); - if (rhsHours != null && rhsHours.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " days too large to be supported by this implementation " + //+ rhsDays.toString() + ); + } + BigInteger rhsHours = (BigInteger) rhs.getField(DatatypeConstants.HOURS); + if (rhsHours != null && rhsHours.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.HOURS.toString(), rhsHours.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " hours too large to be supported by this implementation " - //+ rhsHours.toString() - ); - } - BigInteger rhsMinutes = (BigInteger) rhs.getField(DatatypeConstants.MINUTES); - if (rhsMinutes != null && rhsMinutes.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " hours too large to be supported by this implementation " + //+ rhsHours.toString() + ); + } + BigInteger rhsMinutes = (BigInteger) rhs.getField(DatatypeConstants.MINUTES); + if (rhsMinutes != null && rhsMinutes.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.MINUTES.toString(), rhsMinutes.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " minutes too large to be supported by this implementation " - //+ rhsMinutes.toString() - ); - } - BigDecimal rhsSecondsAsBigDecimal = (BigDecimal) rhs.getField(DatatypeConstants.SECONDS); - BigInteger rhsSeconds = null; + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " minutes too large to be supported by this implementation " + //+ rhsMinutes.toString() + ); + } + BigDecimal rhsSecondsAsBigDecimal = (BigDecimal) rhs.getField(DatatypeConstants.SECONDS); + BigInteger rhsSeconds = null; if ( rhsSecondsAsBigDecimal != null ) { rhsSeconds = rhsSecondsAsBigDecimal.toBigInteger(); } - if (rhsSeconds != null && rhsSeconds.compareTo(maxintAsBigInteger) == 1) { - throw new UnsupportedOperationException( - DatatypeMessageFormatter.formatMessage(null, "TooLarge", + if (rhsSeconds != null && rhsSeconds.compareTo(maxintAsBigInteger) == 1) { + throw new UnsupportedOperationException( + DatatypeMessageFormatter.formatMessage(null, "TooLarge", new Object[]{this.getClass().getName() + "#compare(Duration duration)" + DatatypeConstants.SECONDS.toString(), rhsSeconds.toString()}) - - //this.getClass().getName() + "#compare(Duration duration)" - //+ " seconds too large to be supported by this implementation " - //+ rhsSeconds.toString() - ); - } + + //this.getClass().getName() + "#compare(Duration duration)" + //+ " seconds too large to be supported by this implementation " + //+ rhsSeconds.toString() + ); + } - // turn this Duration into a GregorianCalendar - GregorianCalendar lhsCalendar = new GregorianCalendar( - 1970, - 1, - 1, - 0, - 0, - 0); - lhsCalendar.add(GregorianCalendar.YEAR, getYears() * getSign()); - lhsCalendar.add(GregorianCalendar.MONTH, getMonths() * getSign()); - lhsCalendar.add(GregorianCalendar.DAY_OF_YEAR, getDays() * getSign()); - lhsCalendar.add(GregorianCalendar.HOUR_OF_DAY, getHours() * getSign()); - lhsCalendar.add(GregorianCalendar.MINUTE, getMinutes() * getSign()); - lhsCalendar.add(GregorianCalendar.SECOND, getSeconds() * getSign()); + // turn this Duration into a GregorianCalendar + GregorianCalendar lhsCalendar = new GregorianCalendar( + 1970, + 1, + 1, + 0, + 0, + 0); + lhsCalendar.add(GregorianCalendar.YEAR, getYears() * getSign()); + lhsCalendar.add(GregorianCalendar.MONTH, getMonths() * getSign()); + lhsCalendar.add(GregorianCalendar.DAY_OF_YEAR, getDays() * getSign()); + lhsCalendar.add(GregorianCalendar.HOUR_OF_DAY, getHours() * getSign()); + lhsCalendar.add(GregorianCalendar.MINUTE, getMinutes() * getSign()); + lhsCalendar.add(GregorianCalendar.SECOND, getSeconds() * getSign()); + + // turn compare Duration into a GregorianCalendar + GregorianCalendar rhsCalendar = new GregorianCalendar( + 1970, + 1, + 1, + 0, + 0, + 0); + rhsCalendar.add(GregorianCalendar.YEAR, rhs.getYears() * rhs.getSign()); + rhsCalendar.add(GregorianCalendar.MONTH, rhs.getMonths() * rhs.getSign()); + rhsCalendar.add(GregorianCalendar.DAY_OF_YEAR, rhs.getDays() * rhs.getSign()); + rhsCalendar.add(GregorianCalendar.HOUR_OF_DAY, rhs.getHours() * rhs.getSign()); + rhsCalendar.add(GregorianCalendar.MINUTE, rhs.getMinutes() * rhs.getSign()); + rhsCalendar.add(GregorianCalendar.SECOND, rhs.getSeconds() * rhs.getSign()); + + + if (lhsCalendar.equals(rhsCalendar)) { + return DatatypeConstants.EQUAL; + } - // turn compare Duration into a GregorianCalendar - GregorianCalendar rhsCalendar = new GregorianCalendar( - 1970, - 1, - 1, - 0, - 0, - 0); - rhsCalendar.add(GregorianCalendar.YEAR, rhs.getYears() * rhs.getSign()); - rhsCalendar.add(GregorianCalendar.MONTH, rhs.getMonths() * rhs.getSign()); - rhsCalendar.add(GregorianCalendar.DAY_OF_YEAR, rhs.getDays() * rhs.getSign()); - rhsCalendar.add(GregorianCalendar.HOUR_OF_DAY, rhs.getHours() * rhs.getSign()); - rhsCalendar.add(GregorianCalendar.MINUTE, rhs.getMinutes() * rhs.getSign()); - rhsCalendar.add(GregorianCalendar.SECOND, rhs.getSeconds() * rhs.getSign()); - - - if (lhsCalendar.equals(rhsCalendar)) { - return DatatypeConstants.EQUAL; - } - - return compareDates(this, rhs); + return compareDates(this, rhs); } - + /** * Compares 2 given durations. (refer to W3C Schema Datatypes "3.2.6 duration") * @@ -903,13 +909,13 @@ * return GREATER_THAN if date1 is greater than OR equal to date2 */ private int compareDates(Duration duration1, Duration duration2) { - - int resultA = DatatypeConstants.INDETERMINATE; + + int resultA = DatatypeConstants.INDETERMINATE; int resultB = DatatypeConstants.INDETERMINATE; - + XMLGregorianCalendar tempA = (XMLGregorianCalendar)TEST_POINTS[0].clone(); XMLGregorianCalendar tempB = (XMLGregorianCalendar)TEST_POINTS[0].clone(); - + //long comparison algorithm is required tempA.add(duration1); tempB.add(duration2); @@ -920,7 +926,7 @@ tempA = (XMLGregorianCalendar)TEST_POINTS[1].clone(); tempB = (XMLGregorianCalendar)TEST_POINTS[1].clone(); - + tempA.add(duration1); tempB.add(duration2); resultB = tempA.compare(tempB); @@ -931,7 +937,7 @@ tempA = (XMLGregorianCalendar)TEST_POINTS[2].clone(); tempB = (XMLGregorianCalendar)TEST_POINTS[2].clone(); - + tempA.add(duration1); tempB.add(duration2); resultB = tempA.compare(tempB); @@ -942,7 +948,7 @@ tempA = (XMLGregorianCalendar)TEST_POINTS[3].clone(); tempB = (XMLGregorianCalendar)TEST_POINTS[3].clone(); - + tempA.add(duration1); tempB.add(duration2); resultB = tempA.compare(tempB); @@ -961,35 +967,35 @@ } return resultA; } - + /** * Returns a hash code consistent with the definition of the equals method. - * - * @see Object#hashCode() + * + * @see Object#hashCode() */ public int hashCode() { // component wise hash is not correct because 1day = 24hours - Calendar cal = TEST_POINTS[0].toGregorianCalendar(); - this.addTo(cal); - return (int) getCalendarTimeInMillis(cal); + Calendar cal = TEST_POINTS[0].toGregorianCalendar(); + this.addTo(cal); + return (int) getCalendarTimeInMillis(cal); } - + /** * Returns a string representation of this duration object. - * + * * <p> * The result is formatter according to the XML Schema 1.0 * spec and can be always parsed back later into the * equivalent duration object by * the {@link #DurationImpl(String)} constructor. - * + * * <p> * Formally, the following holds for any {@link Duration} - * object x. + * object x. * <pre> * new Duration(x.toString()).equals(x) * </pre> - * + * * @return * Always return a non-null valid String object. */ @@ -999,7 +1005,7 @@ buf.append('-'); } buf.append('P'); - + if (years != null) { buf.append(years + "Y"); } @@ -1022,19 +1028,19 @@ buf.append(toString(seconds) + "S"); } } - + return buf.toString(); } /** * <p>Turns {@link BigDecimal} to a string representation.</p> - * + * * <p>Due to a behavior change in the {@link BigDecimal#toString()} * method in JDK1.5, this had to be implemented here.</p> - * + * * @param bd <code>BigDecimal</code> to format as a <code>String</code> - * - * @return <code>String</code> representation of <code>BigDecimal</code> + * + * @return <code>String</code> representation of <code>BigDecimal</code> */ private String toString(BigDecimal bd) { String intString = bd.unscaledValue().toString(); @@ -1065,70 +1071,70 @@ /** * Checks if a field is set. - * + * * A field of a duration object may or may not be present. * This method can be used to test if a field is present. - * + * * @param field * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, * MINUTES, or SECONDS.) * @return * true if the field is present. false if not. - * + * * @throws NullPointerException * If the field parameter is null. */ public boolean isSet(DatatypeConstants.Field field) { - - if (field == null) { + + if (field == null) { String methodName = "javax.xml.datatype.Duration" + "#isSet(DatatypeConstants.Field field)" ; - throw new NullPointerException( + throw new NullPointerException( //"cannot be called with field == null" - DatatypeMessageFormatter.formatMessage(null, "FieldCannotBeNull", new Object[]{methodName}) - ); - } + DatatypeMessageFormatter.formatMessage(null, "FieldCannotBeNull", new Object[]{methodName}) + ); + } + + if (field == DatatypeConstants.YEARS) { + return years != null; + } - if (field == DatatypeConstants.YEARS) { - return years != null; - } + if (field == DatatypeConstants.MONTHS) { + return months != null; + } - if (field == DatatypeConstants.MONTHS) { - return months != null; - } - - if (field == DatatypeConstants.DAYS) { - return days != null; - } + if (field == DatatypeConstants.DAYS) { + return days != null; + } - if (field == DatatypeConstants.HOURS) { - return hours != null; - } - - if (field == DatatypeConstants.MINUTES) { - return minutes != null; - } + if (field == DatatypeConstants.HOURS) { + return hours != null; + } - if (field == DatatypeConstants.SECONDS) { - return seconds != null; - } + if (field == DatatypeConstants.MINUTES) { + return minutes != null; + } + + if (field == DatatypeConstants.SECONDS) { + return seconds != null; + } String methodName = "javax.xml.datatype.Duration" + "#isSet(DatatypeConstants.Field field)"; - + throw new IllegalArgumentException( - DatatypeMessageFormatter.formatMessage(null,"UnknownField", new Object[]{methodName, field.toString()}) - ); - + DatatypeMessageFormatter.formatMessage(null,"UnknownField", new Object[]{methodName, field.toString()}) + ); + } - + /** - * Gets the value of a field. - * + * Gets the value of a field. + * * Fields of a duration object may contain arbitrary large value. * Therefore this method is designed to return a {@link Number} object. - * + * * In case of YEARS, MONTHS, DAYS, HOURS, and MINUTES, the returned * number will be a non-negative integer. In case of seconds, * the returned number may be a non-negative decimal value. - * + * * @param field * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, * MINUTES, or SECONDS.) @@ -1138,73 +1144,73 @@ * represents its value. If it is not present, return null. * For YEARS, MONTHS, DAYS, HOURS, and MINUTES, this method * returns a {@link BigInteger} object. For SECONDS, this - * method returns a {@link BigDecimal}. - * + * method returns a {@link BigDecimal}. + * * @throws NullPointerException * If the field parameter is null. */ public Number getField(DatatypeConstants.Field field) { - if (field == null) { + if (field == null) { String methodName = "javax.xml.datatype.Duration" + "#isSet(DatatypeConstants.Field field) " ; - - throw new NullPointerException( + + throw new NullPointerException( DatatypeMessageFormatter.formatMessage(null,"FieldCannotBeNull", new Object[]{methodName}) ); - } - - if (field == DatatypeConstants.YEARS) { - return years; - } + } + + if (field == DatatypeConstants.YEARS) { + return years; + } - if (field == DatatypeConstants.MONTHS) { - return months; - } + if (field == DatatypeConstants.MONTHS) { + return months; + } - if (field == DatatypeConstants.DAYS) { - return days; - } + if (field == DatatypeConstants.DAYS) { + return days; + } - if (field == DatatypeConstants.HOURS) { - return hours; - } - - if (field == DatatypeConstants.MINUTES) { - return minutes; - } + if (field == DatatypeConstants.HOURS) { + return hours; + } - if (field == DatatypeConstants.SECONDS) { - return seconds; - } - /** - throw new IllegalArgumentException( - "javax.xml.datatype.Duration" - + "#(getSet(DatatypeConstants.Field field) called with an unknown field: " - + field.toString() - ); + if (field == DatatypeConstants.MINUTES) { + return minutes; + } + + if (field == DatatypeConstants.SECONDS) { + return seconds; + } + /** + throw new IllegalArgumentException( + "javax.xml.datatype.Duration" + + "#(getSet(DatatypeConstants.Field field) called with an unknown field: " + + field.toString() + ); */ String methodName = "javax.xml.datatype.Duration" + "#(getSet(DatatypeConstants.Field field)"; - + throw new IllegalArgumentException( - DatatypeMessageFormatter.formatMessage(null,"UnknownField", new Object[]{methodName, field.toString()}) - ); - + DatatypeMessageFormatter.formatMessage(null,"UnknownField", new Object[]{methodName, field.toString()}) + ); + } - + /** * Obtains the value of the YEARS field as an integer value, * or 0 if not present. - * + * * <p> - * This method is a convenience method around the + * This method is a convenience method around the * {@link #getField(DatatypeConstants.Field)} method. - * + * * <p> * Note that since this method returns <tt>int</tt>, this * method will return an incorrect value for {@link Duration}s * with the year field that goes beyond the range of <tt>int</tt>. * Use <code>getField(YEARS)</code> to avoid possible loss of precision.</p> - * + * * @return * If the YEARS field is present, return * its value as an integer by using the {@link Number#intValue()} @@ -1213,68 +1219,68 @@ public int getYears() { return getInt(DatatypeConstants.YEARS); } - + /** * Obtains the value of the MONTHS field as an integer value, * or 0 if not present. - * + * * This method works just like {@link #getYears()} except * that this method works on the MONTHS field. - * + * * @return Months of this <code>Duration</code>. */ public int getMonths() { return getInt(DatatypeConstants.MONTHS); } - + /** * Obtains the value of the DAYS field as an integer value, * or 0 if not present. - * + * * This method works just like {@link #getYears()} except * that this method works on the DAYS field. - * + * * @return Days of this <code>Duration</code>. */ public int getDays() { return getInt(DatatypeConstants.DAYS); } - + /** * Obtains the value of the HOURS field as an integer value, * or 0 if not present. - * + * * This method works just like {@link #getYears()} except * that this method works on the HOURS field. - * + * * @return Hours of this <code>Duration</code>. - * + * */ public int getHours() { return getInt(DatatypeConstants.HOURS); } - + /** * Obtains the value of the MINUTES field as an integer value, * or 0 if not present. - * + * * This method works just like {@link #getYears()} except * that this method works on the MINUTES field. - * + * * @return Minutes of this <code>Duration</code>. - * + * */ public int getMinutes() { return getInt(DatatypeConstants.MINUTES); } - + /** * Obtains the value of the SECONDS field as an integer value, * or 0 if not present. - * + * * This method works just like {@link #getYears()} except * that this method works on the SECONDS field. - * + * * @return seconds in the integer value. The fraction of seconds * will be discarded (for example, if the actual value is 2.5, * this method returns 2) @@ -1282,14 +1288,14 @@ public int getSeconds() { return getInt(DatatypeConstants.SECONDS); } - + /** * <p>Return the requested field value as an int.</p> - * + * * <p>If field is not set, i.e. == null, 0 is returned.</p> - * + * * @param field To get value for. - * + * * @return int value of field or 0 if field is not set. */ private int getInt(DatatypeConstants.Field field) { @@ -1300,36 +1306,36 @@ return n.intValue(); } } - + /** * <p>Returns the length of the duration in milli-seconds.</p> - * + * * <p>If the seconds field carries more digits than milli-second order, - * those will be simply discarded (or in other words, rounded to zero.) + * those will be simply discarded (or in other words, rounded to zero.) * For example, for any Calendar value <code>x<code>,</p> * <pre> * <code>new Duration("PT10.00099S").getTimeInMills(x) == 10000</code>. * <code>new Duration("-PT10.00099S").getTimeInMills(x) == -10000</code>. * </pre> - * + * * <p> * Note that this method uses the {@link #addTo(Calendar)} method, * which may work incorectly with {@link Duration} objects with * very large values in its fields. See the {@link #addTo(Calendar)} * method for details. - * + * * @param startInstant * The length of a month/year varies. The <code>startInstant</code> is * used to disambiguate this variance. Specifically, this method * returns the difference between <code>startInstant</code> and * <code>startInstant+duration</code> - * + * * @return milliseconds between <code>startInstant</code> and * <code>startInstant</code> plus this <code>Duration</code> * - * @throws NullPointerException if <code>startInstant</code> parameter + * @throws NullPointerException if <code>startInstant</code> parameter * is null. - * + * */ public long getTimeInMillis(final Calendar startInstant) { Calendar cal = (Calendar) startInstant.clone(); @@ -1337,33 +1343,33 @@ return getCalendarTimeInMillis(cal) - getCalendarTimeInMillis(startInstant); } - + /** * <p>Returns the length of the duration in milli-seconds.</p> - * + * * <p>If the seconds field carries more digits than milli-second order, * those will be simply discarded (or in other words, rounded to zero.) - * For example, for any <code>Date</code> value <code>x<code>,</p> + * For example, for any <code>Date</code> value <code>x<code>,</p> * <pre> * <code>new Duration("PT10.00099S").getTimeInMills(x) == 10000</code>. * <code>new Duration("-PT10.00099S").getTimeInMills(x) == -10000</code>. * </pre> - * + * * <p> * Note that this method uses the {@link #addTo(Date)} method, * which may work incorectly with {@link Duration} objects with * very large values in its fields. See the {@link #addTo(Date)} * method for details. - * + * * @param startInstant * The length of a month/year varies. The <code>startInstant</code> is * used to disambiguate this variance. Specifically, this method * returns the difference between <code>startInstant</code> and * <code>startInstant+duration</code>. - * + * * @throws NullPointerException * If the startInstant parameter is null. - * + * * @return milliseconds between <code>startInstant</code> and * <code>startInstant</code> plus this <code>Duration</code> * @@ -1375,15 +1381,15 @@ this.addTo(cal); return getCalendarTimeInMillis(cal) - startInstant.getTime(); } - + // /** // * Returns an equivalent but "normalized" duration value. -// * +// * // * Intuitively, the normalization moves YEARS into // * MONTHS (by x12) and moves DAYS, HOURS, and MINUTES fields // * into SECONDS (by x86400, x3600, and x60 respectively.) -// * -// * +// * +// * // * Formally, this method satisfies the following conditions: // * <ul> // * <li>x.normalize().equals(x) @@ -1392,58 +1398,58 @@ // * <li>!x.normalize().isSet(Duration.HOURS) // * <li>!x.normalize().isSet(Duration.MINUTES) // * </ul> -// * +// * // * @return -// * always return a non-null valid value. +// * always return a non-null valid value. // */ // public Duration normalize() { // return null; // } - + /** * <p>Converts the years and months fields into the days field * by using a specific time instant as the reference point.</p> - * + * * <p>For example, duration of one month normalizes to 31 days * given the start time instance "July 8th 2003, 17:40:32".</p> - * + * * <p>Formally, the computation is done as follows:</p> * <ol> * <li>The given Calendar object is cloned. * <li>The years, months and days fields will be added to * the {@link Calendar} object - * by using the {@link Calendar#add(int,int)} method. + * by using the {@link Calendar#add(int,int)} method. * <li>The difference between two Calendars are computed in terms of days. * <li>The computed days, along with the hours, minutes and seconds * fields of this duration object is used to construct a new * Duration object. * </ol> - * + * * <p>Note that since the Calendar class uses <code>int</code> to * hold the value of year and month, this method may produce * an unexpected result if this duration object holds * a very large value in the years or months fields.</p> * * @param startTimeInstant <code>Calendar</code> reference point. - * + * * @return <code>Duration</code> of years and months of this <code>Duration</code> as days. - * + * * @throws NullPointerException If the startTimeInstant parameter is null. */ public Duration normalizeWith(Calendar startTimeInstant) { - + Calendar c = (Calendar) startTimeInstant.clone(); - - // using int may cause overflow, but + + // using int may cause overflow, but // Calendar internally treats value as int anyways. - c.add(Calendar.YEAR, getYears() * signum); + c.add(Calendar.YEAR, getYears() * signum); c.add(Calendar.MONTH, getMonths() * signum); c.add(Calendar.DAY_OF_MONTH, getDays() * signum); - + // obtain the difference in terms of days long diff = getCalendarTimeInMillis(c) - getCalendarTimeInMillis(startTimeInstant); int days = (int) (diff / (1000L * 60L * 60L * 24L)); - + return new DurationImpl( days >= 0, null, @@ -1453,31 +1459,31 @@ (BigInteger) getField(DatatypeConstants.MINUTES), (BigDecimal) getField(DatatypeConstants.SECONDS)); } - + /** * <p>Computes a new duration whose value is <code>factor</code> times * longer than the value of this duration.</p> - * + * * <p>This method is provided for the convenience. * It is functionally equivalent to the following code:</p> * <pre> * multiply(new BigDecimal(String.valueOf(factor))) * </pre> - * + * * @param factor Factor times longer of new <code>Duration</code> to create. - * + * * @return New <code>Duration</code> that is <code>factor</code>times longer than this <code>Duration</code>. - * + * * @see #multiply(BigDecimal) */ public Duration multiply(int factor) { return multiply(BigDecimal.valueOf(factor)); } - + /** * Computes a new duration whose value is <code>factor</code> times * longer than the value of this duration. - * + * * <p> * For example, * <pre> @@ -1485,12 +1491,12 @@ * "PT1M" (1 min) * "0.3" = "PT18S" (18 seconds) * "P1M" (1 month) * "1.5" = IllegalStateException * </pre> - * + * * <p> * Since the {@link Duration} class is immutable, this method * doesn't change the value of this object. It simply computes * a new Duration object and returns it. - * + * * <p> * The operation will be performed field by field with the precision * of {@link BigDecimal}. Since all the fields except seconds are @@ -1501,23 +1507,23 @@ * which will be carried down to "PT12H" (12 hours). * When fractions of month cannot be meaningfully carried down * to days, or year to months, this will cause an - * {@link IllegalStateException} to be thrown. + * {@link IllegalStateException} to be thrown. * For example if you multiple one month by 0.5.</p> - * + * * <p> * To avoid {@link IllegalStateException}, use * the {@link #normalizeWith(Calendar)} method to remove the years * and months fields. - * + * * @param factor to multiply by - * + * * @return * returns a non-null valid {@link Duration} object * - * @throws IllegalStateException if operation produces fraction in + * @throws IllegalStateException if operation produces fraction in * the months field. * - * @throws NullPointerException if the <code>factor</code> parameter is + * @throws NullPointerException if the <code>factor</code> parameter is * <code>null</code>. * */ @@ -1525,15 +1531,15 @@ BigDecimal carry = ZERO; int factorSign = factor.signum(); factor = factor.abs(); - + BigDecimal[] buf = new BigDecimal[6]; - + for (int i = 0; i < 5; i++) { BigDecimal bd = getFieldAsBigDecimal(FIELDS[i]); bd = bd.multiply(factor).add(carry); - + buf[i] = bd.setScale(0, BigDecimal.ROUND_DOWN); - + bd = bd.subtract(buf[i]); if (i == 1) { if (bd.signum() != 0) { @@ -1545,13 +1551,13 @@ carry = bd.multiply(FACTORS[i]); } } - + if (seconds != null) { buf[5] = seconds.multiply(factor).add(carry); } else { buf[5] = carry; } - + return new DurationImpl( this.signum * factorSign >= 0, toBigInteger(buf[0], null == years), @@ -1561,14 +1567,14 @@ toBigInteger(buf[4], null == minutes), (buf[5].signum() == 0 && seconds == null) ? null : buf[5]); } - + /** * <p>Gets the value of the field as a {@link BigDecimal}.</p> - * + * * <p>If the field is unset, return 0.</p> - * + * * @param f Field to get value for. - * + * * @return non-null valid {@link BigDecimal}. */ private BigDecimal getFieldAsBigDecimal(DatatypeConstants.Field f) { @@ -1587,13 +1593,13 @@ } } } - + /** * <p>BigInteger value of BigDecimal value.</p> - * + * * @param value Value to convert. * @param canBeNull Can returned value be null? - * + * * @return BigInteger value of BigDecimal, possibly null. */ private static BigInteger toBigInteger( @@ -1605,7 +1611,7 @@ return value.unscaledValue(); } } - + /** * 1 unit of FIELDS[i] is equivalent to <code>FACTORS[i]</code> unit of * FIELDS[i+1]. @@ -1616,11 +1622,11 @@ BigDecimal.valueOf(24), BigDecimal.valueOf(60), BigDecimal.valueOf(60) - }; - + }; + /** * <p>Computes a new duration whose value is <code>this+rhs</code>.</p> - * + * * <p>For example,</p> * <pre> * "1 day" + "-3 days" = "-2 days" @@ -1629,11 +1635,11 @@ * "15 hours" + "-3 days" = "-(2 days,9 hours)" * "1 year" + "-1 day" = IllegalStateException * </pre> - * + * * <p>Since there's no way to meaningfully subtract 1 day from 1 month, * there are cases where the operation fails in - * {@link IllegalStateException}.</p> - * + * {@link IllegalStateException}.</p> + * * <p> * Formally, the computation is defined as follows.</p> * <p> @@ -1641,54 +1647,54 @@ * are both positive without losing generality (i.e., * <code>(-X)+Y=Y-X</code>, <code>X+(-Y)=X-Y</code>, * <code>(-X)+(-Y)=-(X+Y)</code>) - * + * * <p> - * Addition of two positive {@link Duration}s are simply defined as + * Addition of two positive {@link Duration}s are simply defined as * field by field addition where missing fields are treated as 0. * <p> * A field of the resulting {@link Duration} will be unset if and - * only if respective fields of two input {@link Duration}s are unset. + * only if respective fields of two input {@link Duration}s are unset. * <p> * Note that <code>lhs.add(rhs)</code> will be always successful if * <code>lhs.signum()*rhs.signum()!=-1</code> or both of them are * normalized.</p> - * + * * @param rhs <code>Duration</code> to add to this <code>Duration</code> - * + * * @return * non-null valid Duration object. - * + * * @throws NullPointerException * If the rhs parameter is null. * @throws IllegalStateException * If two durations cannot be meaningfully added. For * example, adding negative one day to one month causes * this exception. - * - * + * + * * @see #subtract(Duration) */ public Duration add(final Duration rhs) { Duration lhs = this; BigDecimal[] buf = new BigDecimal[6]; - + buf[0] = sanitize((BigInteger) lhs.getField(DatatypeConstants.YEARS), - lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.YEARS), rhs.getSign())); + lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.YEARS), rhs.getSign())); buf[1] = sanitize((BigInteger) lhs.getField(DatatypeConstants.MONTHS), - lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.MONTHS), rhs.getSign())); + lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.MONTHS), rhs.getSign())); buf[2] = sanitize((BigInteger) lhs.getField(DatatypeConstants.DAYS), - lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.DAYS), rhs.getSign())); + lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.DAYS), rhs.getSign())); buf[3] = sanitize((BigInteger) lhs.getField(DatatypeConstants.HOURS), - lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.HOURS), rhs.getSign())); + lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.HOURS), rhs.getSign())); buf[4] = sanitize((BigInteger) lhs.getField(DatatypeConstants.MINUTES), - lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.MINUTES), rhs.getSign())); + lhs.getSign()).add(sanitize((BigInteger) rhs.getField(DatatypeConstants.MINUTES), rhs.getSign())); buf[5] = sanitize((BigDecimal) lhs.getField(DatatypeConstants.SECONDS), - lhs.getSign()).add(sanitize((BigDecimal) rhs.getField(DatatypeConstants.SECONDS), rhs.getSign())); - + lhs.getSign()).add(sanitize((BigDecimal) rhs.getField(DatatypeConstants.SECONDS), rhs.getSign())); + // align sign alignSigns(buf, 0, 2); // Y,M alignSigns(buf, 2, 6); // D,h,m,s - + // make sure that the sign bit is consistent across all 6 fields. int s = 0; for (int i = 0; i < 6; i++) { @@ -1699,28 +1705,28 @@ s = buf[i].signum(); } } - + return new DurationImpl( s >= 0, toBigInteger(sanitize(buf[0], s), - lhs.getField(DatatypeConstants.YEARS) == null && rhs.getField(DatatypeConstants.YEARS) == null), + lhs.getField(DatatypeConstants.YEARS) == null && rhs.getField(DatatypeConstants.YEARS) == null), toBigInteger(sanitize(buf[1], s), - lhs.getField(DatatypeConstants.MONTHS) == null && rhs.getField(DatatypeConstants.MONTHS) == null), + lhs.getField(DatatypeConstants.MONTHS) == null && rhs.getField(DatatypeConstants.MONTHS) == null), toBigInteger(sanitize(buf[2], s), - lhs.getField(DatatypeConstants.DAYS) == null && rhs.getField(DatatypeConstants.DAYS) == null), + lhs.getField(DatatypeConstants.DAYS) == null && rhs.getField(DatatypeConstants.DAYS) == null), toBigInteger(sanitize(buf[3], s), - lhs.getField(DatatypeConstants.HOURS) == null && rhs.getField(DatatypeConstants.HOURS) == null), + lhs.getField(DatatypeConstants.HOURS) == null && rhs.getField(DatatypeConstants.HOURS) == null), toBigInteger(sanitize(buf[4], s), - lhs.getField(DatatypeConstants.MINUTES) == null && rhs.getField(DatatypeConstants.MINUTES) == null), + lhs.getField(DatatypeConstants.MINUTES) == null && rhs.getField(DatatypeConstants.MINUTES) == null), (buf[5].signum() == 0 && lhs.getField(DatatypeConstants.SECONDS) == null && rhs.getField(DatatypeConstants.SECONDS) == null) ? null : sanitize(buf[5], s)); } - + private static void alignSigns(BigDecimal[] buf, int start, int end) { // align sign boolean touched; - + do { // repeat until all the sign bits become consistent touched = false; int s = 0; // sign of the left fields @@ -1749,7 +1755,7 @@ } } while (touched); } - + /** * Compute <code>value*signum</code> where value==null is treated as * value==0. @@ -1767,13 +1773,13 @@ } return new BigDecimal(value.negate()); } - + /** * <p>Compute <code>value*signum</code> where <code>value==null</code> is treated as <code>value==0</code></p>. - * + * * @param value Value to sanitize. * @param signum 0 to sanitize to 0, > 0 to sanitize to <code>value</code>, < 0 to sanitize to negative <code>value</code>. - * + * * @return non-null {@link BigDecimal}. */ static BigDecimal sanitize(BigDecimal value, int signum) { @@ -1785,10 +1791,10 @@ } return value.negate(); } - + /** * <p>Computes a new duration whose value is <code>this-rhs</code>.</p> - * + * * <p>For example:</p> * <pre> * "1 day" - "-3 days" = "4 days" @@ -1797,57 +1803,57 @@ * "15 hours" - "-3 days" = "3 days and 15 hours" * "1 year" - "-1 day" = "1 year and 1 day" * </pre> - * + * * <p>Since there's no way to meaningfully subtract 1 day from 1 month, - * there are cases where the operation fails in {@link IllegalStateException}.</p> - * + * there are cases where the operation fails in {@link IllegalStateException}.</p> + * * <p>Formally the computation is defined as follows. * First, we can assume that two {@link Duration}s are both positive * without losing generality. (i.e., * <code>(-X)-Y=-(X+Y)</code>, <code>X-(-Y)=X+Y</code>, * <code>(-X)-(-Y)=-(X-Y)</code>)</p> - * + * * <p>Then two durations are subtracted field by field. * If the sign of any non-zero field <tt>F</tt> is different from * the sign of the most significant field, * 1 (if <tt>F</tt> is negative) or -1 (otherwise) * will be borrowed from the next bigger unit of <tt>F</tt>.</p> - * + * * <p>This process is repeated until all the non-zero fields have - * the same sign.</p> - * + * the same sign.</p> + * * <p>If a borrow occurs in the days field (in other words, if * the computation needs to borrow 1 or -1 month to compensate * days), then the computation fails by throwing an * {@link IllegalStateException}.</p> - * + * * @param rhs <code>Duration</code> to substract from this <code>Duration</code>. - * + * * @return New <code>Duration</code> created from subtracting <code>rhs</code> from this <code>Duration</code>. - * + * * @throws IllegalStateException * If two durations cannot be meaningfully subtracted. For * example, subtracting one day from one month causes * this exception. - * + * * @throws NullPointerException * If the rhs parameter is null. - * + * * @see #add(Duration) */ public Duration subtract(final Duration rhs) { return add(rhs.negate()); } - + /** * Returns a new {@link Duration} object whose * value is <code>-this</code>. - * + * * <p> * Since the {@link Duration} class is immutable, this method * doesn't change the value of this object. It simply computes * a new Duration object and returns it. - * + * * @return * always return a non-null valid {@link Duration} object. */ @@ -1861,10 +1867,10 @@ minutes, seconds); } - + /** * Returns the sign of this duration in -1,0, or 1. - * + * * @return * -1 if this duration is negative, 0 if the duration is zero, * and 1 if the duration is postive. @@ -1872,33 +1878,33 @@ public int signum() { return signum; } - - + + /** * Adds this duration to a {@link Calendar} object. - * + * * <p> * Calls {@link java.util.Calendar#add(int,int)} in the * order of YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS, and MILLISECONDS * if those fields are present. Because the {@link Calendar} class * uses int to hold values, there are cases where this method * won't work correctly (for example if values of fields - * exceed the range of int.) + * exceed the range of int.) * </p> - * + * * <p> * Also, since this duration class is a Gregorian duration, this * method will not work correctly if the given {@link Calendar} - * object is based on some other calendar systems. + * object is based on some other calendar systems. * </p> - * + * * <p> * Any fractional parts of this {@link Duration} object * beyond milliseconds will be simply ignored. For example, if * this duration is "P1.23456S", then 1 is added to SECONDS, - * 234 is added to MILLISECONDS, and the rest will be unused. + * 234 is added to MILLISECONDS, and the rest will be unused. * </p> - * + * * <p> * Note that because {@link Calendar#add(int, int)} is using * <tt>int</tt>, {@link Duration} with values beyond the @@ -1907,7 +1913,7 @@ * {@link XMLGregorianCalendar#add(Duration)} provides the same * basic operation as this method while avoiding * the overflow/underflow issues. - * + * * @param calendar * A calendar object whose value will be modified. * @throws NullPointerException @@ -1928,23 +1934,23 @@ calendar.add(Calendar.MILLISECOND, millisec * signum); } } - + /** * Adds this duration to a {@link Date} object. - * + * * <p> * The given date is first converted into * a {@link java.util.GregorianCalendar}, then the duration * is added exactly like the {@link #addTo(Calendar)} method. - * + * * <p> * The updated time instant is then converted back into a * {@link Date} object and used to update the given {@link Date} object. - * + * * <p> * This somewhat redundant computation is necessary to unambiguously * determine the duration of months and years. - * + * * @param date * A date object whose value will be modified. * @throws NullPointerException @@ -1956,19 +1962,19 @@ this.addTo(cal); date.setTime(getCalendarTimeInMillis(cal)); } - + /** * <p>Stream Unique Identifier.</p> - * + * * <p>TODO: Serialization should use the XML string representation as * the serialization format to ensure future compatibility.</p> */ - private static final long serialVersionUID = 1L; - + private static final long serialVersionUID = 1L; + /** * Writes {@link Duration} as a lexical representation * for maximum future compatibility. - * + * * @return * An object that encapsulates the string * returned by <code>this.toString()</code>. @@ -1976,10 +1982,10 @@ private Object writeReplace() throws IOException { return new DurationStream(this.toString()); } - + /** * Representation of {@link Duration} in the object stream. - * + * * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) */ private static class DurationStream implements Serializable { @@ -1988,7 +1994,7 @@ private DurationStream(String _lexical) { this.lexical = _lexical; } - + private Object readResolve() throws ObjectStreamException { // try { return new DurationImpl(lexical); @@ -1996,15 +2002,15 @@ // throw new StreamCorruptedException("unable to parse "+lexical+" as duration"); // } } - - private static final long serialVersionUID = 1L; + + private static final long serialVersionUID = 1L; } - + /** * Calls the {@link Calendar#getTimeInMillis} method. * Prior to JDK1.4, this method was protected and therefore * cannot be invoked directly. - * + * * In future, this should be replaced by * <code>cal.getTimeInMillis()</code> */ @@ -2012,3 +2018,4 @@ return cal.getTime().getTime(); } } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/DurationYearMonthImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xerces.internal.jaxp.datatype; + +import java.math.BigInteger; +import javax.xml.datatype.DatatypeConstants; + + +/** + * <p>Represent a subtype <code>xdt:yearMonthDuration</code> of a <code>Duration</code> + * as specified in <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * + * <p>The DurationYearMonth object represents a period of Gregorian time, + * with a lexical representation, "<em>PnYnM</em>" that contains only year and month components. + * </p> + * + * + * @author <a href="mailto:Vikram.Aroskar@Sun.COM">Vikram Aroskar</a> + * @author <a href="mailto:Huizhe.wang@oracle.com">Joe Wang</a> + * @version $Revision: 1.1 $, $Date: 2010/05/19 05:02:55 $ + + * @see XMLGregorianCalendar#add(Duration) + */ + +class DurationYearMonthImpl + extends DurationImpl { + + + /** + * <p>Constructs a new Duration object by specifying each field individually.</p> + * + * <p>All the parameters are optional as long as at least one field is present. + * If specified, parameters have to be zero or positive.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param years of this <code>Duration</code> + * @param months of this <code>Duration</code> + * + * @throws IllegalArgumentException + * If years, months parameters are all <code>null</code>. Or if any + * of those parameters are negative. + */ + public DurationYearMonthImpl( + boolean isPositive, + BigInteger years, + BigInteger months) { + + super(isPositive, years, months, null, null, null, null); + convertToCanonicalYearMonth(); + } + /** + * <p>Construct a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified + * <code>year</code> and <code>month</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param year Year of <code>Duration</code>. + * @param month Month of <code>Duration</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if any of the fields (year, month) is negative. + */ + protected DurationYearMonthImpl( + final boolean isPositive, + final int years, + final int months) { + + this(isPositive, + wrap(years), + wrap(months)); + + + } + + + /** + * <p>Construct a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> + * + * <p>Both values are set by computing their values from the specified milliseconds + * and are availabe using the <code>get</code> methods of the created {@link Duration}. + * The values conform to and are defined by:</p> + * <ul> + * <li>ISO 8601:2000(E) Section 5.5.3.2 Alternative format</li> + * <li><a href="http://www.w3.org/TR/xmlschema-2/#isoformats"> + * W3C XML Schema 1.0 Part 2, Appendix D, ISO 8601 Date and Time Formats</a> + * </li> + * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> + * </ul> + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} can be influenced.</p> + * + * <p>Any remaining milliseconds after determining the year and month are discarded.</p> + * + * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. + */ + protected DurationYearMonthImpl(long durationInMilliseconds) { + + super(durationInMilliseconds); + convertToCanonicalYearMonth(); + //Any remaining milliseconds after determining the year and month are discarded. + days = null; + hours = null; + minutes = null; + seconds = null; + signum = calcSignum((signum<0)?false:true); + } + + + /** + * <p>Construct a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation, + * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> + * + * <p>Both values are set and availabe from the created {@link Duration}</p> + * + * <p>The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.</p> + * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of years and months. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + protected DurationYearMonthImpl(String lexicalRepresentation) { + super(lexicalRepresentation); + if (getDays() > 0 || getHours() > 0 + || getMinutes() > 0 || getSeconds() > 0) { + throw new IllegalArgumentException( + "Trying to create an xdt:yearMonthDuration with an invalid" + + " lexical representation of \"" + lexicalRepresentation + + "\", data model requires PnYnM."); + } + convertToCanonicalYearMonth(); + } + + /** + * The value space of xs:yearMonthDuration is the set of xs:integer month values. + * @return the value of yearMonthDuration + */ + public int getValue() { + return getYears() * 12 + getMonths(); + } + + private void convertToCanonicalYearMonth() { + while (getMonths() >= 12) + { + months = months.subtract(BigInteger.valueOf(12)); + years = BigInteger.valueOf((long) getYears()).add(BigInteger.ONE); + } + } +} +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -182,13 +182,14 @@ * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> * @author <a href="mailto:Joseph.Fialli@Sun.com">Joseph Fialli</a> * @author <a href="mailto:Sunitha.Reddy@Sun.com">Sunitha Reddy</a> + * @version $Revision: 1.12 $, $Date: 2010/07/07 04:24:52 $ * @see javax.xml.datatype.Duration * @since 1.5 */ public class XMLGregorianCalendarImpl - extends XMLGregorianCalendar - implements Serializable, Cloneable { + extends XMLGregorianCalendar + implements Serializable, Cloneable { /** * <p>Eon of this <code>XMLGregorianCalendar</code>.</p> @@ -245,7 +246,7 @@ * GregorianCalendar.setChange(PURE_GREGORIAN_CHANGE). </p> */ private static final Date PURE_GREGORIAN_CHANGE = - new Date(Long.MIN_VALUE); + new Date(Long.MIN_VALUE); /** * Year index for MIN_ and MAX_FIELD_VALUES. @@ -292,14 +293,14 @@ * field names indexed by YEAR..TIMEZONE. */ private static final String FIELD_NAME[] = { - "Year", - "Month", - "Day", - "Hour", - "Minute", - "Second", - "Millisecond", - "Timezone" + "Year", + "Month", + "Day", + "Hour", + "Minute", + "Second", + "Millisecond", + "Timezone" }; /** @@ -323,16 +324,16 @@ * @see #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar) */ public static final XMLGregorianCalendar LEAP_YEAR_DEFAULT = - createDateTime( - 400, //year - DatatypeConstants.JANUARY, //month - 1, // day - 0, // hour - 0, // minute - 0, // second - DatatypeConstants.FIELD_UNDEFINED, // milliseconds - DatatypeConstants.FIELD_UNDEFINED // timezone - ); + createDateTime( + 400, //year + DatatypeConstants.JANUARY, //month + 1, // day + 0, // hour + 0, // minute + 0, // second + DatatypeConstants.FIELD_UNDEFINED, // milliseconds + DatatypeConstants.FIELD_UNDEFINED // timezone + ); // Constructors @@ -381,7 +382,7 @@ } else if (lexRepLength == 4 // --MM || lexRepLength == 5 // --MMZ || lexRepLength == 10) { // --MMSHH:MM - // gMonth, --MM(z?), + // gMonth, --MM(z?), // per XML Schema Errata, used to be --MM--(z?) format = "--%M" + "%z"; } else { @@ -474,14 +475,14 @@ BigDecimal fractionalSecond, int timezone) { - setYear(year); + setYear(year); setMonth(month); setDay(day); setTime(hour, minute, second, fractionalSecond); - setTimezone(timezone); + setTimezone(timezone); - // check for validity - if (!isValid()) { + // check for validity + if (!isValid()) { throw new IllegalArgumentException( DatatypeMessageFormatter.formatMessage(null, @@ -489,9 +490,9 @@ new Object[] { year, new Integer(month), new Integer(day), new Integer(hour), new Integer(minute), new Integer(second), fractionalSecond, new Integer(timezone)}) - ); + ); - /** + /** String yearString = "null"; if (year != null) { yearString = year.toString(); @@ -514,7 +515,7 @@ ); */ - } + } } @@ -542,17 +543,17 @@ int hour, int minute, int second, - int millisecond, + int millisecond, int timezone) { - setYear(year); + setYear(year); setMonth(month); setDay(day); setTime(hour, minute, second); - setTimezone(timezone); - setMillisecond(millisecond); + setTimezone(timezone); + setMillisecond(millisecond); - if (!isValid()) { + if (!isValid()) { throw new IllegalArgumentException( DatatypeMessageFormatter.formatMessage(null, @@ -560,7 +561,7 @@ new Object[] { new Integer(year), new Integer(month), new Integer(day), new Integer(hour), new Integer(minute), new Integer(second), new Integer(millisecond), new Integer(timezone)}) - ); + ); /* throw new IllegalArgumentException( "year = " + year @@ -575,66 +576,66 @@ ); */ - } + } } - /** - * <p>Convert a <code>java.util.GregorianCalendar</code> to XML Schema 1.0 - * representation.</p> - * - * <table border="2" rules="all" cellpadding="2"> - * <thead> - * <tr> - * <th align="center" colspan="2"> - * Field by Field Conversion from - * <code>java.util.GregorianCalendar</code> to this class - * </th> - * </tr> - * </thead> - * <tbody> - * <tr> - * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> - * <th><code>java.util.GregorianCalendar</code> field</th> - * </tr> - * <tr> - * <th>{@link #setYear(int)}</th> - * <th><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></th> - * </tr> - * <tr> - * <th>{@link #setMonth(int)}</th> - * <th><code>MONTH + 1</code></th> - * </tr> - * <tr> - * <th>{@link #setDay(int)}</th> - * <th><code>DAY_OF_MONTH</code></th> - * </tr> - * <tr> - * <th>{@link #setTime(int,int,int, BigDecimal)}</th> - * <th><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></th> - * </tr> - * <tr> - * <th>{@link #setTimezone(int)}<i>*</i></th> - * <th><code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> - * <i>(in minutes)</i> - * </th> - * </tr> - * </tbody> - * </table> - * <p><i>*</i>conversion loss of information. It is not possible to represent - * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the - * XML Schema 1.0 date/time datatype representation.</p> - * - * <p>To compute the return value's <code>TimeZone</code> field, - * <ul> - * <li>when <code>this.getTimezone() != DatatypeConstants.FIELD_UNDEFINED</code>, - * create a <code>java.util.TimeZone</code> with a custom timezone id - * using the <code>this.getTimezone()</code>.</li> - * <li>else use the <code>GregorianCalendar</code> default timezone value - * for the host is defined as specified by - * <code>java.util.TimeZone.getDefault()</code>.</li></p> - * - * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> - */ + /** + * <p>Convert a <code>java.util.GregorianCalendar</code> to XML Schema 1.0 + * representation.</p> + * + * <table border="2" rules="all" cellpadding="2"> + * <thead> + * <tr> + * <th align="center" colspan="2"> + * Field by Field Conversion from + * <code>java.util.GregorianCalendar</code> to this class + * </th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> + * <th><code>java.util.GregorianCalendar</code> field</th> + * </tr> + * <tr> + * <th>{@link #setYear(int)}</th> + * <th><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></th> + * </tr> + * <tr> + * <th>{@link #setMonth(int)}</th> + * <th><code>MONTH + 1</code></th> + * </tr> + * <tr> + * <th>{@link #setDay(int)}</th> + * <th><code>DAY_OF_MONTH</code></th> + * </tr> + * <tr> + * <th>{@link #setTime(int,int,int, BigDecimal)}</th> + * <th><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></th> + * </tr> + * <tr> + * <th>{@link #setTimezone(int)}<i>*</i></th> + * <th><code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> + * <i>(in minutes)</i> + * </th> + * </tr> + * </tbody> + * </table> + * <p><i>*</i>conversion loss of information. It is not possible to represent + * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the + * XML Schema 1.0 date/time datatype representation.</p> + * + * <p>To compute the return value's <code>TimeZone</code> field, + * <ul> + * <li>when <code>this.getTimezone() != DatatypeConstants.FIELD_UNDEFINED</code>, + * create a <code>java.util.TimeZone</code> with a custom timezone id + * using the <code>this.getTimezone()</code>.</li> + * <li>else use the <code>GregorianCalendar</code> default timezone value + * for the host is defined as specified by + * <code>java.util.TimeZone.getDefault()</code>.</li></p> + * + * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> + */ public XMLGregorianCalendarImpl(GregorianCalendar cal) { int year = cal.get(Calendar.YEAR); @@ -735,7 +736,7 @@ minute, second, DatatypeConstants.FIELD_UNDEFINED, //millisecond - DatatypeConstants.FIELD_UNDEFINED //timezone + DatatypeConstants.FIELD_UNDEFINED //timezone ); } @@ -813,7 +814,7 @@ DatatypeConstants.FIELD_UNDEFINED, // hour DatatypeConstants.FIELD_UNDEFINED, // minute DatatypeConstants.FIELD_UNDEFINED, // second - DatatypeConstants.FIELD_UNDEFINED, // millisecond + DatatypeConstants.FIELD_UNDEFINED, // millisecond timezone); } @@ -833,20 +834,20 @@ * <a href="#datetimefieldmapping">date/time field mapping table</a>. */ public static XMLGregorianCalendar createTime( - int hours, - int minutes, - int seconds, - int timezone) { + int hours, + int minutes, + int seconds, + int timezone) { - return new XMLGregorianCalendarImpl( - DatatypeConstants.FIELD_UNDEFINED, // Year - DatatypeConstants.FIELD_UNDEFINED, // Month - DatatypeConstants.FIELD_UNDEFINED, // Day - hours, - minutes, - seconds, - DatatypeConstants.FIELD_UNDEFINED, //Millisecond - timezone); + return new XMLGregorianCalendarImpl( + DatatypeConstants.FIELD_UNDEFINED, // Year + DatatypeConstants.FIELD_UNDEFINED, // Month + DatatypeConstants.FIELD_UNDEFINED, // Day + hours, + minutes, + seconds, + DatatypeConstants.FIELD_UNDEFINED, //Millisecond + timezone); } /** @@ -935,7 +936,7 @@ * @see #getEonAndYear() */ public BigInteger getEon() { - return eon; + return eon; } /** @@ -951,7 +952,7 @@ * @see #getEonAndYear() */ public int getYear() { - return year; + return year; } /** @@ -971,23 +972,23 @@ */ public BigInteger getEonAndYear() { - // both are defined - if (year != DatatypeConstants.FIELD_UNDEFINED - && eon != null) { + // both are defined + if (year != DatatypeConstants.FIELD_UNDEFINED + && eon != null) { - return eon.add(BigInteger.valueOf((long) year)); - } + return eon.add(BigInteger.valueOf((long) year)); + } - // only year is defined - if (year != DatatypeConstants.FIELD_UNDEFINED - && eon == null) { + // only year is defined + if (year != DatatypeConstants.FIELD_UNDEFINED + && eon == null) { - return BigInteger.valueOf((long) year); - } + return BigInteger.valueOf((long) year); + } - // neither are defined - // or only eon is defined which is not valid without a year - return null; + // neither are defined + // or only eon is defined which is not valid without a year + return null; } /** @@ -1000,7 +1001,7 @@ * */ public int getMonth() { - return month; + return month; } /** @@ -1071,7 +1072,7 @@ * @see #setTime(int, int, int) */ public int getSecond() { - return second; + return second; } /** @@ -1138,7 +1139,7 @@ * @see #setTime(int, int, int, BigDecimal) */ public BigDecimal getFractionalSecond() { - return fractionalSecond; + return fractionalSecond; } // setters @@ -1259,7 +1260,7 @@ * <a href="#datetimefieldmapping">date/time field mapping table</a>. */ public void setTimezone(int offset) { - if(offset<-14*60 || 14*60<offset) + if(offset<-14*60 || 14*60<offset) if(offset!=DatatypeConstants.FIELD_UNDEFINED) invalidFieldValue(TIMEZONE,offset); this.timezone = offset; @@ -1291,7 +1292,7 @@ new Object[]{ new Integer(value), FIELD_NAME[field]}) ); } - + private void testHour() { // http://www.w3.org/2001/05/xmlschema-errata#e2-45 @@ -1300,6 +1301,10 @@ || getSecond() != 0) { invalidFieldValue(HOUR, getHour()); } + // while 0-24 is acceptable in the lexical space, 24 is not valid in value space + // W3C XML Schema Part 2, Section 3.2.7.1 + setHour(0, false); + add(new DurationImpl(true, 0, 0, 1, 0, 0, 0)); } } @@ -1527,12 +1532,12 @@ return normalized; } - /** - * <p>Normalize this instance to UTC.</p> - * - * <p>2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z</p> - * <p>Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).</p> - */ + /** + * <p>Normalize this instance to UTC.</p> + * + * <p>2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z</p> + * <p>Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).</p> + */ private XMLGregorianCalendar normalizeToTimezone(int timezone) { int minutes = timezone; @@ -1675,11 +1680,11 @@ * @return <code>true</code> when <code>compare(this,(XMLGregorianCalendar)obj) == EQUAL.</code>. */ public boolean equals(Object obj) { - - if (obj == null || !(obj instanceof XMLGregorianCalendar)) { - return false; - } - return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL; + + if (obj == null || !(obj instanceof XMLGregorianCalendar)) { + return false; + } + return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL; } /** @@ -1739,7 +1744,7 @@ */ public static XMLGregorianCalendar parse(String lexicalRepresentation) { - return new XMLGregorianCalendarImpl(lexicalRepresentation); + return new XMLGregorianCalendarImpl(lexicalRepresentation); } /** @@ -1906,21 +1911,21 @@ switch(mask) { case 0x3F: - return DatatypeConstants.DATETIME; + return DatatypeConstants.DATETIME; case 0x38: - return DatatypeConstants.DATE; + return DatatypeConstants.DATE; case 0x07: - return DatatypeConstants.TIME; + return DatatypeConstants.TIME; case 0x30: - return DatatypeConstants.GYEARMONTH; + return DatatypeConstants.GYEARMONTH; case 0x18: - return DatatypeConstants.GMONTHDAY; + return DatatypeConstants.GMONTHDAY; case 0x20: - return DatatypeConstants.GYEAR; + return DatatypeConstants.GYEAR; case 0x10: - return DatatypeConstants.GMONTH; + return DatatypeConstants.GMONTH; case 0x08: - return DatatypeConstants.GDAY; + return DatatypeConstants.GDAY; default: throw new IllegalStateException( this.getClass().getName() @@ -1936,12 +1941,12 @@ * @return true if data values are valid. */ public boolean isValid() { - // since setters do not allow for invalid values, - // (except for exceptional case of year field of zero), - // no need to check for anything except for constraints - // between fields. + // since setters do not allow for invalid values, + // (except for exceptional case of year field of zero), + // no need to check for anything except for constraints + // between fields. - //check if days in month is valid. Can be dependent on leap year. + //check if days in month is valid. Can be dependent on leap year. if (getMonth() == DatatypeConstants.FEBRUARY) { // years could not be set int maxDays = 29; @@ -1960,34 +1965,34 @@ } } - // http://www.w3.org/2001/05/xmlschema-errata#e2-45 - if (getHour() == 24) { - if(getMinute() != 0) { - return false; - } else if (getSecond() != 0) { - return false; - } - } + // http://www.w3.org/2001/05/xmlschema-errata#e2-45 + if (getHour() == 24) { + if(getMinute() != 0) { + return false; + } else if (getSecond() != 0) { + return false; + } + } - // XML Schema 1.0 specification defines year value of zero as - // invalid. Allow this class to set year field to zero - // since XML Schema 1.0 errata states that lexical zero will - // be allowed in next version and treated as 1 B.C.E. - if (eon == null) { - // optimize check. - if (year == 0) { - return false; - } - } else { - BigInteger yearField = getEonAndYear(); - if (yearField != null) { - int result = compareField(yearField, BigInteger.ZERO); - if (result == DatatypeConstants.EQUAL) { - return false; - } - } - } - return true; + // XML Schema 1.0 specification defines year value of zero as + // invalid. Allow this class to set year field to zero + // since XML Schema 1.0 errata states that lexical zero will + // be allowed in next version and treated as 1 B.C.E. + if (eon == null) { + // optimize check. + if (year == 0) { + return false; + } + } else { + BigInteger yearField = getEonAndYear(); + if (yearField != null) { + int result = compareField(yearField, BigInteger.ZERO); + if (result == DatatypeConstants.EQUAL) { + return false; + } + } + } + return true; } /** @@ -2256,7 +2261,7 @@ private static int daysInMonth[] = { 0, // XML Schema months start at 1. - 31, 28, 31, 30, 31, 30, + 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private static int maximumDayInMonthFor(BigInteger year, int month) { @@ -2649,9 +2654,9 @@ // of immutable classes, so they do not need to be cloned. return new XMLGregorianCalendarImpl(getEonAndYear(), this.month, this.day, - this.hour, this.minute, this.second, - this.fractionalSecond, - this.timezone); + this.hour, this.minute, this.second, + this.fractionalSecond, + this.timezone); } /** @@ -2783,6 +2788,7 @@ // some tokens are left in the input throw new IllegalArgumentException(value); //,vidx); } + testHour(); } private char peek() throws IllegalArgumentException { @@ -2943,7 +2949,7 @@ if (getFractionalSecond() != null) { // Note: toPlainString() isn't available before Java 1.5 String frac = getFractionalSecond().toString(); - + int pos = frac.indexOf("E-"); if (pos >= 0) { String zeros = frac.substring(pos+2); @@ -3048,3 +3054,4 @@ //PENDING : Implementation of reset method } } +
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/DOMValidatorHelper.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/DOMValidatorHelper.java Wed Sep 28 17:10:18 2011 +0100 @@ -22,7 +22,6 @@ import java.io.IOException; import java.util.Enumeration; -import java.util.Locale; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; @@ -63,7 +62,7 @@ * <p>A validator helper for <code>DOMSource</code>s.</p> * * @author Michael Glavassevich, IBM - * @version $Id: DOMValidatorHelper.java,v 1.6 2008/03/22 02:53:49 joehw Exp $ + * @version $Id: DOMValidatorHelper.java,v 1.8 2010/07/23 02:09:26 joehw Exp $ */ final class DOMValidatorHelper implements ValidatorHelper, EntityState { @@ -208,7 +207,7 @@ } return; } - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), "SourceResultMismatch", new Object [] {source.getClass().getName(), result.getClass().getName()})); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/StAXValidatorHelper.java Wed Sep 28 17:10:18 2011 +0100 @@ -26,7 +26,6 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; import java.io.IOException; -import java.util.Locale; import javax.xml.transform.Result; import javax.xml.transform.Source; @@ -94,7 +93,7 @@ } return; } - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), "SourceResultMismatch", new Object [] {source.getClass().getName(), result.getClass().getName()})); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Wed Sep 28 17:10:18 2011 +0100 @@ -21,7 +21,6 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; import java.lang.ref.SoftReference; -import java.util.Locale; import java.io.IOException; import javax.xml.transform.Result; @@ -46,70 +45,71 @@ /** * <p>A validator helper for <code>StreamSource</code>s.</p> - * + * * @author Michael Glavassevich, IBM * @author <a href="mailto:Sunitha.Reddy@Sun.com">Sunitha Reddy</a> + * @version $Id: StreamValidatorHelper.java,v 1.6 2010/07/23 02:09:26 joehw Exp $ */ final class StreamValidatorHelper implements ValidatorHelper { - + // feature identifiers - + /** Feature identifier: parser settings. */ - private static final String PARSER_SETTINGS = - Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; - + private static final String PARSER_SETTINGS = + Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; + // property identifiers - + /** Property identifier: entity resolver. */ private static final String ENTITY_RESOLVER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_RESOLVER_PROPERTY; - + /** Property identifier: error handler. */ - private static final String ERROR_HANDLER = + private static final String ERROR_HANDLER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_HANDLER_PROPERTY; - + /** Property identifier: error reporter. */ private static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; - + /** Property identifier: XML Schema validator. */ private static final String SCHEMA_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY; - + /** Property identifier: symbol table. */ private static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; - + /** Property identifier: validation manager. */ private static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; - + // // Data // - + /** SoftReference to parser configuration. **/ private SoftReference fConfiguration = new SoftReference(null); - + /** Schema validator. **/ private com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator fSchemaValidator; - + /** Component manager. **/ private XMLSchemaValidatorComponentManager fComponentManager; - + private ValidatorHandlerImpl handler = null; - + public StreamValidatorHelper(XMLSchemaValidatorComponentManager componentManager) { fComponentManager = componentManager; fSchemaValidator = (com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator) fComponentManager.getProperty(SCHEMA_VALIDATOR); } - public void validate(Source source, Result result) + public void validate(Source source, Result result) throws SAXException, IOException { if (result == null || result instanceof StreamResult) { final StreamSource streamSource = (StreamSource) source; TransformerHandler identityTransformerHandler ; - + if( result!=null ) { try { SAXTransformerFactory tf = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); @@ -117,17 +117,17 @@ } catch (TransformerConfigurationException e) { throw new TransformerFactoryConfigurationError(e); } - + handler = new ValidatorHandlerImpl(fComponentManager); handler.setContentHandler(identityTransformerHandler); identityTransformerHandler.setResult(result); } - + XMLInputSource input = new XMLInputSource(streamSource.getPublicId(), streamSource.getSystemId(), null); input.setByteStream(streamSource.getInputStream()); input.setCharacterStream(streamSource.getReader()); - - // Gets the parser configuration. We'll create and initialize a new one, if we + + // Gets the parser configuration. We'll create and initialize a new one, if we // haven't created one before or if the previous one was garbage collected. XMLParserConfiguration config = (XMLParserConfiguration) fConfiguration.get(); if (config == null) { @@ -138,11 +138,11 @@ config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER)); config.setProperty(ERROR_HANDLER, fComponentManager.getProperty(ERROR_HANDLER)); } - + // prepare for parse fComponentManager.reset(); fSchemaValidator.setDocumentHandler(handler); - + try { config.parse(input); } @@ -154,11 +154,11 @@ } return; } - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), - "SourceResultMismatch", + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), + "SourceResultMismatch", new Object [] {source.getClass().getName(), result.getClass().getName()})); } - + private XMLParserConfiguration initialize() { XML11Configuration config = new XML11Configuration(); config.setProperty(ENTITY_RESOLVER, fComponentManager.getProperty(ENTITY_RESOLVER));
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -25,7 +25,6 @@ import java.io.Reader; import java.io.StringReader; import java.util.HashMap; -import java.util.Locale; import javax.xml.XMLConstants; import javax.xml.parsers.FactoryConfigurationError; @@ -48,6 +47,7 @@ import com.sun.org.apache.xerces.internal.util.SAXLocatorWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.util.XMLSymbols; @@ -91,7 +91,7 @@ * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) * @author Michael Glavassevich, IBM * - * @version $Id: ValidatorHandlerImpl.java,v 1.6 2009/07/28 23:48:30 joehw Exp $ + * @version $Id: ValidatorHandlerImpl.java,v 1.9 2010/07/23 02:09:26 joehw Exp $ */ final class ValidatorHandlerImpl extends ValidatorHandler implements DTDHandler, EntityState, PSVIProvider, ValidatorHelper, XMLDocumentHandler { @@ -245,7 +245,7 @@ final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ? "feature-not-recognized" : "feature-not-supported"; throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } } @@ -265,7 +265,7 @@ if (type == XMLConfigurationException.NOT_ALLOWED) { //for now, the identifier can only be (XMLConstants.FEATURE_SECURE_PROCESSING) throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), "jaxp-secureprocessing-feature", null)); } else if (type == XMLConfigurationException.NOT_RECOGNIZED) { key = "feature-not-recognized"; @@ -273,7 +273,7 @@ key = "feature-not-supported"; } throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } } @@ -291,7 +291,7 @@ final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ? "property-not-recognized" : "property-not-supported"; throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } } @@ -309,7 +309,7 @@ final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ? "property-not-recognized" : "property-not-supported"; throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } } @@ -717,7 +717,7 @@ } return; } - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), "SourceResultMismatch", new Object [] {source.getClass().getName(), result.getClass().getName()})); } @@ -806,7 +806,7 @@ * REVISIT: I'm not sure if this code should belong here. */ private final XMLSchemaTypeInfoProvider fTypeInfoProvider = new XMLSchemaTypeInfoProvider(); - private static class XMLSchemaTypeInfoProvider extends TypeInfoProvider { + private class XMLSchemaTypeInfoProvider extends TypeInfoProvider { /** Element augmentations: contains ElementPSVI. **/ private Augmentations fElementAugs; @@ -853,7 +853,7 @@ */ private void checkState(boolean forElementInfo) { if (! (fInStartElement || (fInEndElement && forElementInfo))) { - throw new IllegalStateException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalStateException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), "TypeInfoProviderIllegalState", null)); } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -21,7 +21,6 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; import java.io.IOException; -import java.util.Locale; import javax.xml.XMLConstants; import javax.xml.transform.Result; @@ -51,7 +50,7 @@ * @author <a href="mailto:Kohsuke.Kawaguchi@Sun.com">Kohsuke Kawaguchi</a> * @author Michael Glavassevich, IBM * @author <a href="mailto:Sunitha.Reddy@Sun.com">Sunitha Reddy</a> - * @version $Id: ValidatorImpl.java,v 1.7 2009/07/28 23:48:30 joehw Exp $ + * @version $Id: ValidatorImpl.java,v 1.9 2010/07/23 02:09:26 joehw Exp $ */ final class ValidatorImpl extends Validator implements PSVIProvider { @@ -124,12 +123,12 @@ } // Source parameter cannot be null. else if (source == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), "SourceParameterNull", null)); } // Source parameter must be a SAXSource, DOMSource or StreamSource else { - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fComponentManager.getLocale(), "SourceNotAccepted", new Object [] {source.getClass().getName()})); } } @@ -165,7 +164,7 @@ final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ? "feature-not-recognized" : "feature-not-supported"; throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } } @@ -185,7 +184,7 @@ if (type == XMLConfigurationException.NOT_ALLOWED) { //for now, the identifier can only be (XMLConstants.FEATURE_SECURE_PROCESSING) throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), "jaxp-secureprocessing-feature", null)); } else if (type == XMLConfigurationException.NOT_RECOGNIZED) { key = "feature-not-recognized"; @@ -193,7 +192,7 @@ key = "feature-not-supported"; } throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } fConfigurationChanged = true; @@ -216,7 +215,7 @@ final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ? "property-not-recognized" : "property-not-supported"; throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } } @@ -234,7 +233,7 @@ final String key = e.getType() == XMLConfigurationException.NOT_RECOGNIZED ? "property-not-recognized" : "property-not-supported"; throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fComponentManager.getLocale(), key, new Object [] {identifier})); } fConfigurationChanged = true;
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -23,7 +23,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.Reader; -import java.util.Locale; import javax.xml.XMLConstants; import javax.xml.transform.Source; @@ -61,7 +60,7 @@ * {@link SchemaFactory} for XML Schema. * * @author Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com) - * @version $Id: XMLSchemaFactory.java,v 1.5 2009/07/28 23:48:30 joehw Exp $ + * @version $Id: XMLSchemaFactory.java,v 1.8 2010/07/23 02:23:47 joehw Exp $ */ public final class XMLSchemaFactory extends SchemaFactory { @@ -132,11 +131,11 @@ */ public boolean isSchemaLanguageSupported(String schemaLanguage) { if (schemaLanguage == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "SchemaLanguageNull", null)); } if (schemaLanguage.length() == 0) { - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "SchemaLanguageLengthZero", null)); } // only W3C XML Schema 1.0 is supported @@ -188,7 +187,7 @@ SAXSource saxSource = (SAXSource) source; InputSource inputSource = saxSource.getInputSource(); if (inputSource == null) { - throw new SAXException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new SAXException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "SAXSourceNullInputSource", null)); } xmlInputSources[i] = new SAXInputSource(saxSource.getXMLReader(), inputSource); @@ -200,11 +199,11 @@ xmlInputSources[i] = new DOMInputSource(node, systemID); } else if (source == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "SchemaSourceArrayMemberNull", null)); } else { - throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new IllegalArgumentException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "SchemaFactorySourceUnrecognized", new Object [] {source.getClass().getName()})); } @@ -249,7 +248,7 @@ public boolean getFeature(String name) throws SAXNotRecognizedException, SAXNotSupportedException { if (name == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "FeatureNameNull", null)); } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { @@ -262,12 +261,12 @@ String identifier = e.getIdentifier(); if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "feature-not-recognized", new Object [] {identifier})); } else { throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "feature-not-supported", new Object [] {identifier})); } } @@ -276,7 +275,7 @@ public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException { if (name == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "ProperyNameNull", null)); } if (name.equals(SECURITY_MANAGER)) { @@ -284,7 +283,7 @@ } else if (name.equals(XMLGRAMMAR_POOL)) { throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "property-not-supported", new Object [] {name})); } try { @@ -294,12 +293,12 @@ String identifier = e.getIdentifier(); if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "property-not-recognized", new Object [] {identifier})); } else { throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "property-not-supported", new Object [] {identifier})); } } @@ -308,7 +307,7 @@ public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { if (name == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "FeatureNameNull", null)); } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { @@ -328,12 +327,12 @@ String identifier = e.getIdentifier(); if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "feature-not-recognized", new Object [] {identifier})); } else { throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "feature-not-supported", new Object [] {identifier})); } } @@ -342,7 +341,7 @@ public void setProperty(String name, Object object) throws SAXNotRecognizedException, SAXNotSupportedException { if (name == null) { - throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(Locale.getDefault(), + throw new NullPointerException(JAXPValidationMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "ProperyNameNull", null)); } if (name.equals(SECURITY_MANAGER)) { @@ -352,7 +351,7 @@ } else if (name.equals(XMLGRAMMAR_POOL)) { throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "property-not-supported", new Object [] {name})); } try { @@ -362,12 +361,12 @@ String identifier = e.getIdentifier(); if (e.getType() == XMLConfigurationException.NOT_RECOGNIZED) { throw new SAXNotRecognizedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "property-not-recognized", new Object [] {identifier})); } else { throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(Locale.getDefault(), + SAXMessageFormatter.formatMessage(fXMLSchemaLoader.getLocale(), "property-not-supported", new Object [] {identifier})); } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Wed Sep 28 17:10:18 2011 +0100 @@ -21,6 +21,7 @@ package com.sun.org.apache.xerces.internal.jaxp.validation; import java.util.HashMap; +import java.util.Locale; import javax.xml.XMLConstants; @@ -48,7 +49,7 @@ * <p>An implementation of XMLComponentManager for a schema validator.</p> * * @author Michael Glavassevich, IBM - * @version $Id: XMLSchemaValidatorComponentManager.java,v 1.5 2009/07/28 23:48:30 joehw Exp $ + * @version $Id: XMLSchemaValidatorComponentManager.java,v 1.7 2010/07/23 02:09:26 joehw Exp $ */ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettings implements XMLComponentManager { @@ -112,7 +113,11 @@ /** Property identifier: grammar pool. */ private static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; - + + /** Property identifier: locale. */ + private static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + // // Data // @@ -164,7 +169,10 @@ /** Application's LSResourceResolver. */ private LSResourceResolver fResourceResolver = null; - + + /** Locale chosen by the application. */ + private Locale fLocale = null; + /** Constructs a component manager suitable for Xerces' schema validator. */ public XMLSchemaValidatorComponentManager(XSGrammarPoolContainer grammarContainer) { // setup components @@ -286,6 +294,9 @@ */ public Object getProperty(String propertyId) throws XMLConfigurationException { + if (LOCALE.equals(propertyId)) { + return getLocale(); + } final Object component = fComponents.get(propertyId); if (component != null) { return component; @@ -320,6 +331,11 @@ fComponents.put(propertyId, value); return; } + else if (LOCALE.equals(propertyId)) { + setLocale((Locale) value); + fComponents.put(propertyId, value); + return; + } super.setProperty(propertyId, value); } @@ -373,10 +389,19 @@ setProperty(ENTITY_RESOLVER, new DOMEntityResolverWrapper(resourceResolver)); } - public LSResourceResolver getResourceResolver() { + LSResourceResolver getResourceResolver() { return fResourceResolver; } - + + void setLocale(Locale locale) { + fLocale = locale; + fErrorReporter.setLocale(locale); + } + + Locale getLocale() { + return fLocale; + } + /** Cleans out configuration, restoring it to its initial state. */ void restoreInitialState() { fConfigUpdated = true; @@ -388,7 +413,11 @@ // Remove error resolver and error handler fComponents.put(ENTITY_RESOLVER, null); fComponents.put(ERROR_HANDLER, null); - + + // Set the Locale back to null. + setLocale(null); + fComponents.put(LOCALE, null); + // Restore component defaults. setFeatureDefaults(fEntityManager, fEntityManager.getRecognizedFeatures()); setPropertyDefaults(fEntityManager, fEntityManager.getRecognizedProperties());
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java Wed Sep 28 17:10:18 2011 +0100 @@ -52,11 +52,11 @@ * to DTD-centric validation. Since * the Xerces2 reference implementation document and DTD scanner * implementations are capable of acting as pull parsers, this - * configuration implements the + * configuration implements the * <code>XMLPullParserConfiguration</code> interface. * <p> * In addition to the features and properties recognized by the base - * parser configuration, this class recognizes these additional + * parser configuration, this class recognizes these additional * features and properties: * <ul> * <li>Features @@ -83,9 +83,10 @@ * @author Andy Clark, IBM * @author Neil Graham, IBM * + * @version $Id: DTDConfiguration.java,v 1.6 2010/07/23 02:09:28 joehw Exp $ */ public class DTDConfiguration - extends BasicParserConfiguration + extends BasicParserConfiguration implements XMLPullParserConfiguration { // @@ -101,17 +102,17 @@ /** Feature identifier: warn on duplicate entity definition. */ protected static final String WARN_ON_DUPLICATE_ENTITYDEF = Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE; - + /** Feature identifier: warn on undeclared element definition. */ protected static final String WARN_ON_UNDECLARED_ELEMDEF = Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE; - + /** Feature identifier: allow Java encodings. */ - protected static final String ALLOW_JAVA_ENCODINGS = + protected static final String ALLOW_JAVA_ENCODINGS = Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE; - + /** Feature identifier: continue after fatal error. */ - protected static final String CONTINUE_AFTER_FATAL_ERROR = + protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE; /** Feature identifier: load external DTD. */ @@ -121,40 +122,40 @@ /** Feature identifier: notify built-in refereces. */ protected static final String NOTIFY_BUILTIN_REFS = Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE; - + /** Feature identifier: notify character refereces. */ protected static final String NOTIFY_CHAR_REFS = Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE; - + // property identifiers /** Property identifier: error reporter. */ - protected static final String ERROR_REPORTER = + protected static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; /** Property identifier: entity manager. */ - protected static final String ENTITY_MANAGER = + protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; - + /** Property identifier document scanner: */ - protected static final String DOCUMENT_SCANNER = + protected static final String DOCUMENT_SCANNER = Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY; /** Property identifier: DTD scanner. */ - protected static final String DTD_SCANNER = + protected static final String DTD_SCANNER = Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; /** Property identifier: grammar pool. */ - protected static final String XMLGRAMMAR_POOL = + protected static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; - + /** Property identifier: DTD loader. */ - protected static final String DTD_PROCESSOR = + protected static final String DTD_PROCESSOR = Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_PROCESSOR_PROPERTY; /** Property identifier: DTD validator. */ - protected static final String DTD_VALIDATOR = + protected static final String DTD_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY; /** Property identifier: namespace binder. */ @@ -162,20 +163,23 @@ Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY; /** Property identifier: datatype validator factory. */ - protected static final String DATATYPE_VALIDATOR_FACTORY = + protected static final String DATATYPE_VALIDATOR_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; protected static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; - + /** Property identifier: JAXP schema language / DOM schema-type. */ protected static final String JAXP_SCHEMA_LANGUAGE = - Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE; + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_LANGUAGE; /** Property identifier: JAXP schema source/ DOM schema-location. */ protected static final String JAXP_SCHEMA_SOURCE = - Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; + Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; + /** Property identifier: locale. */ + protected static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; // debugging @@ -226,7 +230,7 @@ /** Locator */ protected XMLLocator fLocator; - /** + /** * True if a parse is in progress. This state is needed because * some features/properties cannot be set while parsing (e.g. * validation and namespaces). @@ -242,8 +246,8 @@ this(null, null, null); } // <init>() - /** - * Constructs a parser configuration using the specified symbol table. + /** + * Constructs a parser configuration using the specified symbol table. * * @param symbolTable The symbol table to use. */ @@ -255,7 +259,7 @@ * Constructs a parser configuration using the specified symbol table and * grammar pool. * <p> - * <strong>REVISIT:</strong> + * <strong>REVISIT:</strong> * Grammar pool will be updated when the new validation engine is * implemented. * @@ -271,7 +275,7 @@ * Constructs a parser configuration using the specified symbol table, * grammar pool, and parent settings. * <p> - * <strong>REVISIT:</strong> + * <strong>REVISIT:</strong> * Grammar pool will be updated when the new validation engine is * implemented. * @@ -292,7 +296,7 @@ CONTINUE_AFTER_FATAL_ERROR, LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl //NOTIFY_BUILTIN_REFS, // from XMLDocumentFragmentScannerImpl - //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl + //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl //WARN_ON_DUPLICATE_ENTITYDEF, // from XMLEntityManager }; addRecognizedFeatures(recognizedFeatures); @@ -309,18 +313,19 @@ // add default recognized properties final String[] recognizedProperties = { - ERROR_REPORTER, - ENTITY_MANAGER, + ERROR_REPORTER, + ENTITY_MANAGER, DOCUMENT_SCANNER, DTD_SCANNER, DTD_PROCESSOR, DTD_VALIDATOR, NAMESPACE_BINDER, - XMLGRAMMAR_POOL, + XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER, JAXP_SCHEMA_SOURCE, - JAXP_SCHEMA_LANGUAGE + JAXP_SCHEMA_LANGUAGE, + LOCALE }; addRecognizedProperties(recognizedProperties); @@ -371,7 +376,7 @@ setProperty(NAMESPACE_BINDER, fNamespaceBinder); addComponent(fNamespaceBinder); } - + fDatatypeValidatorFactory = createDatatypeValidatorFactory(); if (fDatatypeValidatorFactory != null) { setProperty(DATATYPE_VALIDATOR_FACTORY, @@ -404,6 +409,22 @@ // Public methods // + public Object getProperty(String propertyId) + throws XMLConfigurationException { + if (LOCALE.equals(propertyId)) { + return getLocale(); + } + return super.getProperty(propertyId); + } + + public void setProperty(String propertyId, Object value) + throws XMLConfigurationException { + if (LOCALE.equals(propertyId)) { + setLocale((Locale) value); + } + super.setProperty(propertyId, value); + } + /** * Set the locale to use for messages. * @@ -428,7 +449,7 @@ * * @param inputSource The document's input source. * - * @exception XMLConfigurationException Thrown if there is a + * @exception XMLConfigurationException Thrown if there is a * configuration error when initializing the * parser. * @exception IOException Thrown on I/O error. @@ -437,14 +458,14 @@ */ public void setInputSource(XMLInputSource inputSource) throws XMLConfigurationException, IOException { - + // REVISIT: this method used to reset all the components and // construct the pipeline. Now reset() is called // in parse (boolean) just before we parse the document // Should this method still throw exceptions..? fInputSource = inputSource; - + } // setInputSource(XMLInputSource) /** @@ -455,7 +476,7 @@ * * @return True if there is more document to parse. * - * @exception XNIException Any XNI exception, possibly wrapping + * @exception XNIException Any XNI exception, possibly wrapping * another exception. * @exception IOException An IO exception from the parser, possibly * from a byte stream or character stream @@ -472,17 +493,17 @@ reset(); fScanner.setInputSource(fInputSource); fInputSource = null; - } + } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (RuntimeException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -497,17 +518,17 @@ try { return fScanner.scanDocument(complete); - } + } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (RuntimeException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -529,7 +550,7 @@ public void cleanup() { fEntityManager.closeReaders(); } - + // // XMLParserConfiguration methods // @@ -553,12 +574,12 @@ try { setInputSource(source); parse(true); - } + } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -568,7 +589,7 @@ if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (Exception ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -585,9 +606,9 @@ // // Protected methods // - - /** - * Reset all components before parsing. + + /** + * Reset all components before parsing. * * @throws XNIException Thrown if an error occurs during initialization. */ @@ -601,54 +622,54 @@ } // reset() /** Configures the pipeline. */ - protected void configurePipeline() { + protected void configurePipeline() { - // REVISIT: This should be better designed. In other words, we - // need to figure out what is the best way for people to - // re-use *most* of the standard configuration but do - // things common things such as remove a component (e.g. - // the validator), insert a new component (e.g. XInclude), - // etc... -Ac + // REVISIT: This should be better designed. In other words, we + // need to figure out what is the best way for people to + // re-use *most* of the standard configuration but do + // things common things such as remove a component (e.g. + // the validator), insert a new component (e.g. XInclude), + // etc... -Ac - // setup document pipeline - if (fDTDValidator != null) { - fScanner.setDocumentHandler(fDTDValidator); - if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { + // setup document pipeline + if (fDTDValidator != null) { + fScanner.setDocumentHandler(fDTDValidator); + if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { - // filters - fDTDValidator.setDocumentHandler(fNamespaceBinder); - fDTDValidator.setDocumentSource(fScanner); - fNamespaceBinder.setDocumentHandler(fDocumentHandler); - fNamespaceBinder.setDocumentSource(fDTDValidator); - fLastComponent = fNamespaceBinder; - } - else { - fDTDValidator.setDocumentHandler(fDocumentHandler); - fDTDValidator.setDocumentSource(fScanner); - fLastComponent = fDTDValidator; - } - } - else { - if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { - fScanner.setDocumentHandler(fNamespaceBinder); - fNamespaceBinder.setDocumentHandler(fDocumentHandler); - fNamespaceBinder.setDocumentSource(fScanner); - fLastComponent = fNamespaceBinder; - } - else { - fScanner.setDocumentHandler(fDocumentHandler); - fLastComponent = fScanner; - } - } - + // filters + fDTDValidator.setDocumentHandler(fNamespaceBinder); + fDTDValidator.setDocumentSource(fScanner); + fNamespaceBinder.setDocumentHandler(fDocumentHandler); + fNamespaceBinder.setDocumentSource(fDTDValidator); + fLastComponent = fNamespaceBinder; + } + else { + fDTDValidator.setDocumentHandler(fDocumentHandler); + fDTDValidator.setDocumentSource(fScanner); + fLastComponent = fDTDValidator; + } + } + else { + if (fFeatures.get(NAMESPACES) == Boolean.TRUE) { + fScanner.setDocumentHandler(fNamespaceBinder); + fNamespaceBinder.setDocumentHandler(fDocumentHandler); + fNamespaceBinder.setDocumentSource(fScanner); + fLastComponent = fNamespaceBinder; + } + else { + fScanner.setDocumentHandler(fDocumentHandler); + fLastComponent = fScanner; + } + } + configureDTDPipeline(); - } // configurePipeline() - + } // configurePipeline() + protected void configureDTDPipeline (){ - + // setup dtd pipeline if (fDTDScanner != null) { - fProperties.put(DTD_SCANNER, fDTDScanner); + fProperties.put(DTD_SCANNER, fDTDScanner); if (fDTDProcessor != null) { fProperties.put(DTD_PROCESSOR, fDTDProcessor); fDTDScanner.setDTDHandler(fDTDProcessor); @@ -703,14 +724,14 @@ if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); - + // // http://apache.org/xml/features/validation/dynamic // Allows the parser to validate a document only when it // contains a grammar. Validation is turned on/off based // on each document instance, automatically. // - if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && + if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) { return; } @@ -727,7 +748,7 @@ // // http://apache.org/xml/features/validation/default-attribute-values // - if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && + if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) { // REVISIT short type = XMLConfigurationException.NOT_SUPPORTED; @@ -736,14 +757,14 @@ // // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar // - if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && + if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) { return; } // // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd // - if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && + if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { return; } @@ -751,7 +772,7 @@ // // http://apache.org/xml/features/validation/default-attribute-values // - if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && + if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) { short type = XMLConfigurationException.NOT_SUPPORTED; throw new XMLConfigurationException(type, featureId); @@ -789,7 +810,7 @@ if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); - if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && + if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { return; }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java Wed Sep 28 17:10:18 2011 +0100 @@ -49,15 +49,16 @@ * configuration with the set of following parser components: * Document scanner, DTD scanner, namespace binder, document handler. * <p> - * Xerces parser that uses this configuration is <strong>not</strong> <a href="http://www.w3.org/TR/REC-xml#sec-conformance">conformant</a> - * non-validating XML processor, since conformant non-validating processor is required - * to process "all the declarations they read in the internal DTD subset ... must use the information in those declarations to normalize attribute values, + * Xerces parser that uses this configuration is <strong>not</strong> <a href="http://www.w3.org/TR/REC-xml#sec-conformance">conformant</a> + * non-validating XML processor, since conformant non-validating processor is required + * to process "all the declarations they read in the internal DTD subset ... must use the information in those declarations to normalize attribute values, * include the replacement text of internal entities, and supply default attribute values". - * + * * @author Elena Litani, IBM + * @version $Id: NonValidatingConfiguration.java,v 1.6 2010/07/23 02:09:28 joehw Exp $ */ public class NonValidatingConfiguration - extends BasicParserConfiguration + extends BasicParserConfiguration implements XMLPullParserConfiguration { // @@ -73,17 +74,17 @@ /** Feature identifier: warn on duplicate entity definition. */ protected static final String WARN_ON_DUPLICATE_ENTITYDEF = Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE; - + /** Feature identifier: warn on undeclared element definition. */ protected static final String WARN_ON_UNDECLARED_ELEMDEF = Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE; - + /** Feature identifier: allow Java encodings. */ - protected static final String ALLOW_JAVA_ENCODINGS = + protected static final String ALLOW_JAVA_ENCODINGS = Constants.XERCES_FEATURE_PREFIX + Constants.ALLOW_JAVA_ENCODINGS_FEATURE; - + /** Feature identifier: continue after fatal error. */ - protected static final String CONTINUE_AFTER_FATAL_ERROR = + protected static final String CONTINUE_AFTER_FATAL_ERROR = Constants.XERCES_FEATURE_PREFIX + Constants.CONTINUE_AFTER_FATAL_ERROR_FEATURE; /** Feature identifier: load external DTD. */ @@ -93,11 +94,11 @@ /** Feature identifier: notify built-in refereces. */ protected static final String NOTIFY_BUILTIN_REFS = Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_BUILTIN_REFS_FEATURE; - + /** Feature identifier: notify character refereces. */ protected static final String NOTIFY_CHAR_REFS = Constants.XERCES_FEATURE_PREFIX + Constants.NOTIFY_CHAR_REFS_FEATURE; - + /** Feature identifier: expose schema normalized value */ protected static final String NORMALIZE_DATA = @@ -111,27 +112,27 @@ // property identifiers /** Property identifier: error reporter. */ - protected static final String ERROR_REPORTER = + protected static final String ERROR_REPORTER = Constants.XERCES_PROPERTY_PREFIX + Constants.ERROR_REPORTER_PROPERTY; /** Property identifier: entity manager. */ - protected static final String ENTITY_MANAGER = + protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; - + /** Property identifier document scanner: */ - protected static final String DOCUMENT_SCANNER = + protected static final String DOCUMENT_SCANNER = Constants.XERCES_PROPERTY_PREFIX + Constants.DOCUMENT_SCANNER_PROPERTY; /** Property identifier: DTD scanner. */ - protected static final String DTD_SCANNER = + protected static final String DTD_SCANNER = Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_SCANNER_PROPERTY; /** Property identifier: grammar pool. */ - protected static final String XMLGRAMMAR_POOL = + protected static final String XMLGRAMMAR_POOL = Constants.XERCES_PROPERTY_PREFIX + Constants.XMLGRAMMAR_POOL_PROPERTY; - + /** Property identifier: DTD validator. */ - protected static final String DTD_VALIDATOR = + protected static final String DTD_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX + Constants.DTD_VALIDATOR_PROPERTY; /** Property identifier: namespace binder. */ @@ -139,7 +140,7 @@ Constants.XERCES_PROPERTY_PREFIX + Constants.NAMESPACE_BINDER_PROPERTY; /** Property identifier: datatype validator factory. */ - protected static final String DATATYPE_VALIDATOR_FACTORY = + protected static final String DATATYPE_VALIDATOR_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.DATATYPE_VALIDATOR_FACTORY_PROPERTY; protected static final String VALIDATION_MANAGER = @@ -149,6 +150,9 @@ protected static final String SCHEMA_VALIDATOR = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_VALIDATOR_PROPERTY; + /** Property identifier: locale. */ + protected static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; // debugging @@ -194,12 +198,12 @@ /** Default Xerces implementation of scanner*/ private XMLDocumentScannerImpl fNonNSScanner; - - - /** fConfigUpdated is set to true if there has been any change to the configuration settings, - * i.e a feature or a property was changed. - */ - protected boolean fConfigUpdated = false; + + + /** fConfigUpdated is set to true if there has been any change to the configuration settings, + * i.e a feature or a property was changed. + */ + protected boolean fConfigUpdated = false; // state @@ -207,7 +211,7 @@ /** Locator */ protected XMLLocator fLocator; - /** + /** * True if a parse is in progress. This state is needed because * some features/properties cannot be set while parsing (e.g. * validation and namespaces). @@ -223,8 +227,8 @@ this(null, null, null); } // <init>() - /** - * Constructs a parser configuration using the specified symbol table. + /** + * Constructs a parser configuration using the specified symbol table. * * @param symbolTable The symbol table to use. */ @@ -236,7 +240,7 @@ * Constructs a parser configuration using the specified symbol table and * grammar pool. * <p> - * <strong>REVISIT:</strong> + * <strong>REVISIT:</strong> * Grammar pool will be updated when the new validation engine is * implemented. * @@ -252,7 +256,7 @@ * Constructs a parser configuration using the specified symbol table, * grammar pool, and parent settings. * <p> - * <strong>REVISIT:</strong> + * <strong>REVISIT:</strong> * Grammar pool will be updated when the new validation engine is * implemented. * @@ -266,16 +270,16 @@ super(symbolTable, parentSettings); // add default recognized features - final String[] recognizedFeatures = { - PARSER_SETTINGS, - NAMESPACES, + final String[] recognizedFeatures = { + PARSER_SETTINGS, + NAMESPACES, //WARN_ON_DUPLICATE_ATTDEF, // from XMLDTDScannerImpl //WARN_ON_UNDECLARED_ELEMDEF, // from XMLDTDScannerImpl //ALLOW_JAVA_ENCODINGS, // from XMLEntityManager CONTINUE_AFTER_FATAL_ERROR, //LOAD_EXTERNAL_DTD, // from XMLDTDScannerImpl //NOTIFY_BUILTIN_REFS, // from XMLDocumentFragmentScannerImpl - //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl + //NOTIFY_CHAR_REFS, // from XMLDocumentFragmentScannerImpl //WARN_ON_DUPLICATE_ENTITYDEF // from XMLEntityManager }; addRecognizedFeatures(recognizedFeatures); @@ -285,8 +289,8 @@ //setFeature(WARN_ON_UNDECLARED_ELEMDEF, false); // from XMLDTDScannerImpl //setFeature(ALLOW_JAVA_ENCODINGS, false); // from XMLEntityManager fFeatures.put(CONTINUE_AFTER_FATAL_ERROR, Boolean.FALSE); - fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); - fFeatures.put(NAMESPACES, Boolean.TRUE); + fFeatures.put(PARSER_SETTINGS, Boolean.TRUE); + fFeatures.put(NAMESPACES, Boolean.TRUE); //setFeature(LOAD_EXTERNAL_DTD, true); // from XMLDTDScannerImpl //setFeature(NOTIFY_BUILTIN_REFS, false); // from XMLDocumentFragmentScannerImpl //setFeature(NOTIFY_CHAR_REFS, false); // from XMLDocumentFragmentScannerImpl @@ -294,30 +298,31 @@ // add default recognized properties final String[] recognizedProperties = { - ERROR_REPORTER, - ENTITY_MANAGER, + ERROR_REPORTER, + ENTITY_MANAGER, DOCUMENT_SCANNER, DTD_SCANNER, DTD_VALIDATOR, NAMESPACE_BINDER, - XMLGRAMMAR_POOL, + XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, - VALIDATION_MANAGER + VALIDATION_MANAGER, + LOCALE }; addRecognizedProperties(recognizedProperties); - + fGrammarPool = grammarPool; if(fGrammarPool != null){ - fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); + fProperties.put(XMLGRAMMAR_POOL, fGrammarPool); } fEntityManager = createEntityManager(); - fProperties.put(ENTITY_MANAGER, fEntityManager); + fProperties.put(ENTITY_MANAGER, fEntityManager); addComponent(fEntityManager); fErrorReporter = createErrorReporter(); fErrorReporter.setDocumentLocator(fEntityManager.getEntityScanner()); - fProperties.put(ERROR_REPORTER, fErrorReporter); + fProperties.put(ERROR_REPORTER, fErrorReporter); addComponent(fErrorReporter); // this configuration delays creation of the scanner @@ -325,7 +330,7 @@ fDTDScanner = createDTDScanner(); if (fDTDScanner != null) { - fProperties.put(DTD_SCANNER, fDTDScanner); + fProperties.put(DTD_SCANNER, fDTDScanner); if (fDTDScanner instanceof XMLComponent) { addComponent((XMLComponent)fDTDScanner); } @@ -333,13 +338,13 @@ fDatatypeValidatorFactory = createDatatypeValidatorFactory(); if (fDatatypeValidatorFactory != null) { - fProperties.put(DATATYPE_VALIDATOR_FACTORY, + fProperties.put(DATATYPE_VALIDATOR_FACTORY, fDatatypeValidatorFactory); } fValidationManager = createValidationManager(); if (fValidationManager != null) { - fProperties.put(VALIDATION_MANAGER, fValidationManager); + fProperties.put(VALIDATION_MANAGER, fValidationManager); } // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { @@ -347,8 +352,8 @@ fErrorReporter.putMessageFormatter(XMLMessageFormatter.XML_DOMAIN, xmft); fErrorReporter.putMessageFormatter(XMLMessageFormatter.XMLNS_DOMAIN, xmft); } - - fConfigUpdated = false; + + fConfigUpdated = false; // set locale try { @@ -364,17 +369,29 @@ // // Public methods // - public void setFeature(String featureId, boolean state) - throws XMLConfigurationException { - fConfigUpdated = true; - super.setFeature(featureId, state); - } + public void setFeature(String featureId, boolean state) + throws XMLConfigurationException { + fConfigUpdated = true; + super.setFeature(featureId, state); + } + + public Object getProperty(String propertyId) + throws XMLConfigurationException { + if (LOCALE.equals(propertyId)) { + return getLocale(); + } + return super.getProperty(propertyId); + } public void setProperty(String propertyId, Object value) - throws XMLConfigurationException { - fConfigUpdated = true; - super.setProperty(propertyId, value); - } + throws XMLConfigurationException { + fConfigUpdated = true; + if (LOCALE.equals(propertyId)) { + setLocale((Locale) value); + } + super.setProperty(propertyId, value); + } + /** * Set the locale to use for messages. * @@ -387,16 +404,16 @@ super.setLocale(locale); fErrorReporter.setLocale(locale); } // setLocale(Locale) + + public boolean getFeature(String featureId) + throws XMLConfigurationException { + // make this feature special + if (featureId.equals(PARSER_SETTINGS)){ + return fConfigUpdated; + } + return super.getFeature(featureId); - public boolean getFeature(String featureId) - throws XMLConfigurationException { - // make this feature special - if (featureId.equals(PARSER_SETTINGS)){ - return fConfigUpdated; - } - return super.getFeature(featureId); - - } // getFeature(String):boolean + } // getFeature(String):boolean // // XMLPullParserConfiguration methods // @@ -408,7 +425,7 @@ * * @param inputSource The document's input source. * - * @exception XMLConfigurationException Thrown if there is a + * @exception XMLConfigurationException Thrown if there is a * configuration error when initializing the * parser. * @exception IOException Thrown on I/O error. @@ -417,14 +434,14 @@ */ public void setInputSource(XMLInputSource inputSource) throws XMLConfigurationException, IOException { - + // REVISIT: this method used to reset all the components and // construct the pipeline. Now reset() is called // in parse (boolean) just before we parse the document // Should this method still throw exceptions..? fInputSource = inputSource; - + } // setInputSource(XMLInputSource) /** @@ -435,7 +452,7 @@ * * @return True if there is more document to parse. * - * @exception XNIException Any XNI exception, possibly wrapping + * @exception XNIException Any XNI exception, possibly wrapping * another exception. * @exception IOException An IO exception from the parser, possibly * from a byte stream or character stream @@ -452,17 +469,17 @@ reset(); fScanner.setInputSource(fInputSource); fInputSource = null; - } + } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (RuntimeException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -477,17 +494,17 @@ try { return fScanner.scanDocument(complete); - } + } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (RuntimeException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -509,7 +526,7 @@ public void cleanup() { fEntityManager.closeReaders(); } - + // // XMLParserConfiguration methods // @@ -533,12 +550,12 @@ try { setInputSource(source); parse(true); - } + } catch (XNIException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (IOException ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -548,7 +565,7 @@ if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); throw ex; - } + } catch (Exception ex) { if (PRINT_EXCEPTION_STACK_TRACE) ex.printStackTrace(); @@ -565,9 +582,9 @@ // // Protected methods // - - /** - * Reset all components before parsing. + + /** + * Reset all components before parsing. * * @throws XNIException Thrown if an error occurs during initialization. */ @@ -593,7 +610,7 @@ fProperties.put(DOCUMENT_SCANNER, fNamespaceScanner); fNamespaceScanner.setDTDValidator(null); fScanner = fNamespaceScanner; - } + } else { if (fNonNSScanner == null) { fNonNSScanner = new XMLDocumentScannerImpl(); @@ -637,21 +654,21 @@ if (featureId.startsWith(Constants.XERCES_FEATURE_PREFIX)) { final int suffixLength = featureId.length() - Constants.XERCES_FEATURE_PREFIX.length(); - + // // http://apache.org/xml/features/validation/dynamic // Allows the parser to validate a document only when it // contains a grammar. Validation is turned on/off based // on each document instance, automatically. // - if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && + if (suffixLength == Constants.DYNAMIC_VALIDATION_FEATURE.length() && featureId.endsWith(Constants.DYNAMIC_VALIDATION_FEATURE)) { return; } // // http://apache.org/xml/features/validation/default-attribute-values // - if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() && + if (suffixLength == Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE.length() && featureId.endsWith(Constants.DEFAULT_ATTRIBUTE_VALUES_FEATURE)) { // REVISIT short type = XMLConfigurationException.NOT_SUPPORTED; @@ -660,7 +677,7 @@ // // http://apache.org/xml/features/validation/default-attribute-values // - if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && + if (suffixLength == Constants.VALIDATE_CONTENT_MODELS_FEATURE.length() && featureId.endsWith(Constants.VALIDATE_CONTENT_MODELS_FEATURE)) { // REVISIT short type = XMLConfigurationException.NOT_SUPPORTED; @@ -669,14 +686,14 @@ // // http://apache.org/xml/features/validation/nonvalidating/load-dtd-grammar // - if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && + if (suffixLength == Constants.LOAD_DTD_GRAMMAR_FEATURE.length() && featureId.endsWith(Constants.LOAD_DTD_GRAMMAR_FEATURE)) { return; } // // http://apache.org/xml/features/validation/nonvalidating/load-external-dtd // - if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && + if (suffixLength == Constants.LOAD_EXTERNAL_DTD_FEATURE.length() && featureId.endsWith(Constants.LOAD_EXTERNAL_DTD_FEATURE)) { return; } @@ -684,7 +701,7 @@ // // http://apache.org/xml/features/validation/default-attribute-values // - if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && + if (suffixLength == Constants.VALIDATE_DATATYPES_FEATURE.length() && featureId.endsWith(Constants.VALIDATE_DATATYPES_FEATURE)) { short type = XMLConfigurationException.NOT_SUPPORTED; throw new XMLConfigurationException(type, featureId); @@ -721,8 +738,8 @@ if (propertyId.startsWith(Constants.XERCES_PROPERTY_PREFIX)) { final int suffixLength = propertyId.length() - Constants.XERCES_PROPERTY_PREFIX.length(); - - if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && + + if (suffixLength == Constants.DTD_SCANNER_PROPERTY.length() && propertyId.endsWith(Constants.DTD_SCANNER_PROPERTY)) { return; } @@ -731,7 +748,7 @@ if (propertyId.startsWith(Constants.JAXP_PROPERTY_PREFIX)) { final int suffixLength = propertyId.length() - Constants.JAXP_PROPERTY_PREFIX.length(); - if (suffixLength == Constants.SCHEMA_SOURCE.length() && + if (suffixLength == Constants.SCHEMA_SOURCE.length() && propertyId.endsWith(Constants.SCHEMA_SOURCE)) { return; }
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Wed Sep 28 17:10:18 2011 +0100 @@ -73,7 +73,7 @@ * @author Neil Graham, IBM * @author Michael Glavassevich, IBM * - * @version $Id: XML11Configuration.java,v 1.5 2008/08/29 06:17:02 joehw Exp $ + * @version $Id: XML11Configuration.java,v 1.7 2010/07/23 02:09:28 joehw Exp $ */ public class XML11Configuration extends ParserConfigurationSettings implements XMLPullParserConfiguration, XML11Configurable { @@ -255,6 +255,10 @@ protected static final String JAXP_SCHEMA_SOURCE = Constants.JAXP_PROPERTY_PREFIX + Constants.SCHEMA_SOURCE; + /** Property identifier: locale. */ + protected static final String LOCALE = + Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -500,7 +504,10 @@ // validator is constructed dynamically, its recognized // properties might not have been set and it would cause a // not-recognized exception to be thrown. -Ac - SCHEMA_LOCATION, SCHEMA_NONS_LOCATION, }; + SCHEMA_LOCATION, + SCHEMA_NONS_LOCATION, + LOCALE, + }; addRecognizedProperties(recognizedProperties); if (symbolTable == null) { @@ -834,7 +841,7 @@ * Returns the state of a feature. * * @param featureId The feature identifier. - * @return true if the feature is supported + * @return true if the feature is supported * * @throws XMLConfigurationException Thrown for configuration error. * In general, components should @@ -896,7 +903,27 @@ super.setFeature(featureId, state); } // setFeature(String,boolean) - + + /** + * Returns the value of a property. + * + * @param propertyId The property identifier. + * @return the value of the property + * + * @throws XMLConfigurationException Thrown for configuration error. + * In general, components should + * only throw this exception if + * it is <strong>really</strong> + * a critical error. + */ + public Object getProperty(String propertyId) + throws XMLConfigurationException { + if (LOCALE.equals(propertyId)) { + return getLocale(); + } + return super.getProperty(propertyId); + } + /** * setProperty * @@ -906,6 +933,9 @@ public void setProperty(String propertyId, Object value) throws XMLConfigurationException { fConfigUpdated = true; + if (LOCALE.equals(propertyId)) { + setLocale((Locale) value); + } // forward to every XML 1.0 component int count = fComponents.size(); for (int i = 0; i < count; i++) {
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarPreparser.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/parsers/XMLGrammarPreparser.java Wed Sep 28 17:10:18 2011 +0100 @@ -48,6 +48,7 @@ * * @author Neil Graham, IBM * + * @version $Id: XMLGrammarPreparser.java,v 1.6 2010/07/23 02:09:28 joehw Exp $ */ public class XMLGrammarPreparser { @@ -127,9 +128,8 @@ fSymbolTable = symbolTable; fLoaders = new Hashtable(); + fErrorReporter = new XMLErrorReporter(); setLocale(Locale.getDefault()); - fErrorReporter = new XMLErrorReporter(); - fErrorReporter.setLocale(fLocale); fEntityResolver = new XMLEntityManager(); // those are all the basic properties... } // <init>(SymbolTable) @@ -217,6 +217,7 @@ */ public void setLocale(Locale locale) { fLocale = locale; + fErrorReporter.setLocale(locale); } // setLocale(Locale) /** Return the Locale the XMLGrammarLoader is using. */
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/util/XMLAttributesImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -83,7 +83,7 @@ * @author Elena Litani, IBM * @author Michael Glavassevich, IBM * - * @version $Id: XMLAttributesImpl.java,v 1.6 2009/05/13 18:13:21 spericas Exp $ + * @version $Id: XMLAttributesImpl.java,v 1.7 2010/05/07 20:13:09 joehw Exp $ */ public class XMLAttributesImpl implements XMLAttributes, XMLBufferListener { @@ -1020,8 +1020,8 @@ /** * Look up an attribute's value by Namespace name and * Local name. If Namespace is null, ignore namespace - * comparison. If Namespace is "", map it to null as - * required internally by this class. + * comparison. If Namespace is "", treat the name as + * having no Namespace URI. * * <p>See {@link #getValue(int) getValue(int)} for a description * of the possible values.</p> @@ -1032,8 +1032,7 @@ * attribute is not in the list. */ public String getValue(String uri, String localName) { - int index = (uri == null) ? getIndexByLocalName(localName) - : getIndex(uri.length() == 0 ? null : uri, localName); + int index = getIndex(uri, localName); return index != -1 ? getValue(index) : null; } // getValue(String,String):String
--- a/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/xni/QName.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xerces/internal/xni/QName.java Wed Sep 28 17:10:18 2011 +0100 @@ -73,58 +73,63 @@ * * @author Andy Clark, IBM * + * Better performance patch for the equals method by Daniel Petersson: refer to jaxp issue 61; + * == were used to compare strings + * @author Joe Wang, Oracle + * + * @version $Id: QName.java,v 1.6 2010/03/18 19:32:31 joehw Exp $ */ public class QName implements Cloneable { - - + + /** * The qname prefix. For example, the prefix for the qname "a:foo" * is "a". */ public String prefix; - + /** * The qname localpart. For example, the localpart for the qname "a:foo" * is "foo". */ public String localpart; - + /** * The qname rawname. For example, the rawname for the qname "a:foo" * is "a:foo". */ public String rawname; - + /** * The URI to which the qname prefix is bound. This binding must be * performed by a XML Namespaces aware processor. */ public String uri; - + // // Constructors // - + /** Default constructor. */ public QName() { clear(); } // <init>() - + /** Constructs a QName with the specified values. */ public QName(String prefix, String localpart, String rawname, String uri) { setValues(prefix, localpart, rawname, uri); } // <init>(String,String,String,String) - + /** Constructs a copy of the specified QName. */ public QName(QName qname) { setValues(qname); } // <init>(QName) - + // // Public methods // - + /** * Convenience method to set the values of the qname components. * @@ -136,7 +141,7 @@ rawname = qname.rawname; uri = qname.uri; } // setValues(QName) - + /** * Convenience method to set the values of the qname components. * @@ -152,7 +157,7 @@ this.rawname = rawname; this.uri = uri; } // setValues(String,String,String,String) - + /** Clears the values of the qname components. */ public void clear() { prefix = null; @@ -177,7 +182,7 @@ /** Returns the hashcode for this object. */ public int hashCode() { if (uri != null) { - return uri.hashCode() + + return uri.hashCode() + ((localpart != null) ? localpart.hashCode() : 0); } return (rawname != null) ? rawname.hashCode() : 0; @@ -185,13 +190,17 @@ /** Returns true if the two objects are equal. */ public boolean equals(Object object) { - if (object instanceof QName) { + if (object == this) { + return true; + } + + if (object != null && object instanceof QName) { QName qname = (QName)object; if (qname.uri != null) { - return uri == qname.uri && localpart == qname.localpart; + return qname.localpart.equals(localpart) && qname.uri.equals(uri); } else if (uri == null) { - return rawname == qname.rawname; + return rawname.equals(qname.rawname); } // fall through and return not equal }
--- a/sources/jaxp_src/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBaseIterators.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xml/internal/dtm/ref/DTMDefaultBaseIterators.java Wed Sep 28 17:10:18 2011 +0100 @@ -47,7 +47,7 @@ * @param whiteSpaceFilter The white space filter for this DTM, which may * be null. * @param xstringfactory The factory to use for creating XMLStrings. - * @param doIndexing true if the caller considers it worth it to use + * @param doIndexing true if the caller considers it worth it to use * indexing schemes. */ public DTMDefaultBaseIterators(DTMManager mgr, Source source, @@ -56,7 +56,7 @@ XMLStringFactory xstringfactory, boolean doIndexing) { - super(mgr, source, dtmIdentity, whiteSpaceFilter, + super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, doIndexing); } @@ -69,7 +69,7 @@ * @param whiteSpaceFilter The white space filter for this DTM, which may * be null. * @param xstringfactory The factory to use for creating XMLStrings. - * @param doIndexing true if the caller considers it worth it to use + * @param doIndexing true if the caller considers it worth it to use * indexing schemes. * @param blocksize The block size of the DTM. * @param usePrevsib true if we want to build the previous sibling node array. @@ -84,7 +84,7 @@ boolean usePrevsib, boolean newNameTable) { - super(mgr, source, dtmIdentity, whiteSpaceFilter, + super(mgr, source, dtmIdentity, whiteSpaceFilter, xstringfactory, doIndexing, blocksize, usePrevsib, newNameTable); } @@ -116,7 +116,7 @@ // iterator = new FilterIterator(getAxisIterator(axis), // getElementFilter()); // } - // else + // else { switch (axis) { @@ -160,8 +160,8 @@ break; default : throw new DTMException(XMLMessages.createXMLMessage( - XMLErrorResources.ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED, - new Object[]{Axis.getNames(axis)})); + XMLErrorResources.ER_TYPED_ITERATOR_AXIS_NOT_IMPLEMENTED, + new Object[]{Axis.getNames(axis)})); //"Error: typed iterator for axis " //+ Axis.names[axis] + "not implemented"); } @@ -227,8 +227,8 @@ break; default : throw new DTMException(XMLMessages.createXMLMessage( - XMLErrorResources.ER_ITERATOR_AXIS_NOT_IMPLEMENTED, - new Object[]{Axis.getNames(axis)})); + XMLErrorResources.ER_ITERATOR_AXIS_NOT_IMPLEMENTED, + new Object[]{Axis.getNames(axis)})); //"Error: iterator for axis '" + Axis.names[axis] //+ "' not implemented"); } @@ -281,8 +281,8 @@ { _currentNode = _markedNode; } - - } // end of InternalAxisIteratorBase + + } // end of InternalAxisIteratorBase /** * Iterator that returns all immediate children of a given node @@ -578,9 +578,9 @@ return END; } } // end of NamespaceChildrenIterator - + /** - * Iterator that returns the namespace nodes as defined by the XPath data model + * Iterator that returns the namespace nodes as defined by the XPath data model * for a given node. */ public class NamespaceIterator @@ -636,9 +636,9 @@ return returnNode(node); } } // end of NamespaceIterator - + /** - * Iterator that returns the namespace nodes as defined by the XPath data model + * Iterator that returns the namespace nodes as defined by the XPath data model * for a given node, filtered by extended type ID. */ public class TypedNamespaceIterator extends NamespaceIterator @@ -666,7 +666,7 @@ */ public int next() { - int node; + int node; for (node = _currentNode; node != END; @@ -683,9 +683,9 @@ return (_currentNode =END); } } // end of TypedNamespaceIterator - + /** - * Iterator that returns the the root node as defined by the XPath data model + * Iterator that returns the the root node as defined by the XPath data model * for a given node. */ public class RootIterator @@ -738,9 +738,9 @@ return returnNode(_startNode); } } // end of RootIterator - + /** - * Iterator that returns the namespace nodes as defined by the XPath data model + * Iterator that returns the namespace nodes as defined by the XPath data model * for a given node, filtered by extended type ID. */ public class TypedRootIterator extends RootIterator @@ -767,7 +767,7 @@ */ public int next() { - if(_startNode == _currentNode) + if(_startNode == _currentNode) return NULL; int nodeType = _nodeType; @@ -1070,7 +1070,7 @@ final int node = _currentNode; - // singleton iterator, since there can only be one attribute of + // singleton iterator, since there can only be one attribute of // a given type. _currentNode = NULL; @@ -1124,7 +1124,7 @@ } int type = m_expandedNameTable.getType(_exptype(node)); - if(ExpandedNameTable.ATTRIBUTE == type + if(ExpandedNameTable.ATTRIBUTE == type || ExpandedNameTable.NAMESPACE == type ) { _currentNode = node; @@ -1133,7 +1133,7 @@ { // Be careful to handle the Document node properly _currentNode = _parent(node); - if(NULL!=_currentNode) + if(NULL!=_currentNode) _currentNode = _firstch(_currentNode); else _currentNode = node; @@ -1317,22 +1317,22 @@ _startNode = node; _stack[index = 0] = node; - - + + - parent=node; - while ((parent = _parent(parent)) != NULL) - { - if (++index == _stack.length) - { - final int[] stack = new int[index + 4]; - System.arraycopy(_stack, 0, stack, 0, index); - _stack = stack; - } - _stack[index] = parent; + parent=node; + while ((parent = _parent(parent)) != NULL) + { + if (++index == _stack.length) + { + final int[] stack = new int[index + 4]; + System.arraycopy(_stack, 0, stack, 0, index); + _stack = stack; + } + _stack[index] = parent; } if(index>0) - --index; // Pop actual root node (if not start) back off the stack + --index; // Pop actual root node (if not start) back off the stack _currentNode=_stack[index]; // Last parent before root node @@ -1351,23 +1351,23 @@ */ public int next() { - // Bugzilla 8324: We were forgetting to skip Attrs and NS nodes. - // Also recoded the loop controls for clarity and to flatten out - // the tail-recursion. - for(++_currentNode; - _sp>=0; - ++_currentNode) - { - if(_currentNode < _stack[_sp]) - { - if(_type(_currentNode) != ATTRIBUTE_NODE && - _type(_currentNode) != NAMESPACE_NODE) - return returnNode(makeNodeHandle(_currentNode)); - } - else - --_sp; - } - return NULL; + // Bugzilla 8324: We were forgetting to skip Attrs and NS nodes. + // Also recoded the loop controls for clarity and to flatten out + // the tail-recursion. + for(++_currentNode; + _sp>=0; + ++_currentNode) + { + if(_currentNode < _stack[_sp]) + { + if(_type(_currentNode) != ATTRIBUTE_NODE && + _type(_currentNode) != NAMESPACE_NODE) + return returnNode(makeNodeHandle(_currentNode)); + } + else + --_sp; + } + return NULL; } // redefine DTMAxisIteratorBase's reset @@ -1476,7 +1476,7 @@ } _currentNode = node; - + return (node == NULL) ? NULL : returnNode(makeNodeHandle(node)); } } // end of TypedPrecedingIterator @@ -1487,7 +1487,7 @@ public class FollowingIterator extends InternalAxisIteratorBase { DTMAxisTraverser m_traverser; // easier for now - + public FollowingIterator() { m_traverser = getAxisTraverser(Axis.FOLLOWING); @@ -1575,7 +1575,7 @@ _currentNode = m_traverser.next(_startNode, _currentNode); - } + } while (node != DTM.NULL && (getExpandedTypeID(node) != _nodeType && getNodeType(node) != _nodeType)); @@ -1589,16 +1589,16 @@ */ public class AncestorIterator extends InternalAxisIteratorBase { - com.sun.org.apache.xml.internal.utils.NodeVector m_ancestors = + com.sun.org.apache.xml.internal.utils.NodeVector m_ancestors = new com.sun.org.apache.xml.internal.utils.NodeVector(); - + int m_ancestorsPos; int m_markedPos; - + /** The real start node for this axes, since _startNode will be adjusted. */ int m_realStartNode; - + /** * Get start to END should 'close' the iterator, * i.e. subsequent call to next() should return END. @@ -1713,12 +1713,12 @@ { int next = _currentNode; - + int pos = --m_ancestorsPos; _currentNode = (pos >= 0) ? m_ancestors.elementAt(m_ancestorsPos) : DTM.NULL; - + return returnNode(next); } @@ -1898,11 +1898,11 @@ _currentNode = node; return returnNode(makeNodeHandle(node)); // make handle. } - + /** * Reset. * - */ + */ public DTMAxisIterator reset() { @@ -1916,7 +1916,7 @@ return this; } - + } // end of DescendantIterator /** @@ -2092,10 +2092,7 @@ } else if (_isRestartable) { - if (_currentNode == Integer.MIN_VALUE) - { _currentNode = _startNode = node; - } return resetPosition(); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xml/internal/serializer/Encodings.properties Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xml/internal/serializer/Encodings.properties Wed Sep 28 17:10:18 2011 +0100 @@ -1,7 +1,3 @@ -########################################################################### -# reserved comment block -# DO NOT REMOVE OR ALTER! -########################################################################### ########################################################################### # Copyright 2003-2004 The Apache Software Foundation. # @@ -18,7 +14,7 @@ # limitations under the License. ########################################################################## # -# $Id: Encodings.properties,v 1.2.4.1 2005/09/15 08:15:17 suresh_emailid Exp $ +# $Id$ # # <JAVA name encoding>, <PREFERRED name MIME> # Peter Smolik @@ -105,6 +101,8 @@ Cp420 EBCDIC-CP-AR1 0x00FF Cp424 EBCDIC-CP-HE 0x00FF Cp500 EBCDIC-CP-CH 0x00FF +Cp850 850,csPC850Multilingual 0xFFFF +Cp860 860,csIBM860 0xFFFF Cp870 EBCDIC-CP-ROECE,EBCDIC-CP-YU 0x00FF Cp871 EBCDIC-CP-IS 0x00FF Cp918 EBCDIC-CP-AR2 0x00FF
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/axes/NodeSequence.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/axes/NodeSequence.java Wed Sep 28 17:10:18 2011 +0100 @@ -43,39 +43,85 @@ static final long serialVersionUID = 3866261934726581044L; /** The index of the last node in the iteration. */ protected int m_last = -1; - + /** * The index of the next node to be fetched. Useful if this * is a cached iterator, and is being used as random access * NodeList. */ protected int m_next = 0; - + + /** + * A cache of a list of nodes obtained from the iterator so far. + * This list is appended to until the iterator is exhausted and + * the cache is complete. + * <p> + * Multiple NodeSequence objects may share the same cache. + */ + private IteratorCache m_cache; + /** * If this iterator needs to cache nodes that are fetched, they * are stored in the Vector in the generic object. */ - protected NodeVector getVector() - { - return (NodeVector)m_obj; + protected NodeVector getVector() { + NodeVector nv = (m_cache != null) ? m_cache.getVector() : null; + return nv; } - + /** - * Set the vector where nodes will be stored. + * Get the cache (if any) of nodes obtained from + * the iterator so far. Note that the cache keeps + * growing until the iterator is walked to exhaustion, + * at which point the cache is "complete". + */ + private IteratorCache getCache() { + return m_cache; + } + + /** + * Set the vector where nodes will be cached. */ protected void SetVector(NodeVector v) { - m_obj = v; + setObject(v); } - + /** - * If this iterator needs to cache nodes that are fetched, they - * are stored here. + * If the iterator needs to cache nodes as they are fetched, + * then this method returns true. */ public boolean hasCache() { - return (m_obj != null); + final NodeVector nv = getVector(); + return (nv != null); + } + + /** + * If this NodeSequence has a cache, and that cache is + * fully populated then this method returns true, otherwise + * if there is no cache or it is not complete it returns false. + */ + private boolean cacheComplete() { + final boolean complete; + if (m_cache != null) { + complete = m_cache.isComplete(); + } else { + complete = false; + } + return complete; + } + + /** + * If this NodeSequence has a cache, mark that it is complete. + * This method should be called after the iterator is exhausted. + */ + private void markCacheComplete() { + NodeVector nv = getVector(); + if (nv != null) { + m_cache.setCacheComplete(true); + } } @@ -83,7 +129,7 @@ * The functional iterator that fetches nodes. */ protected DTMIterator m_iter; - + /** * Set the functional iterator that fetches nodes. * @param iter The iterator that is to be contained. @@ -92,7 +138,7 @@ { m_iter = iter; } - + /** * Get the functional iterator that fetches nodes. * @return The contained iterator. @@ -101,68 +147,72 @@ { return m_iter; } - + /** * The DTMManager to use if we're using a NodeVector only. * We may well want to do away with this, and store it in the NodeVector. */ protected DTMManager m_dtmMgr; - + // ==== Constructors ==== - + /** * Create a new NodeSequence from a (already cloned) iterator. - * + * * @param iter Cloned (not static) DTMIterator. * @param context The initial context node. * @param xctxt The execution context. * @param shouldCacheNodes True if this sequence can random access. */ - public NodeSequence(DTMIterator iter, int context, XPathContext xctxt, boolean shouldCacheNodes) + private NodeSequence(DTMIterator iter, int context, XPathContext xctxt, boolean shouldCacheNodes) { setIter(iter); setRoot(context, xctxt); setShouldCacheNodes(shouldCacheNodes); } - + /** * Create a new NodeSequence from a (already cloned) iterator. - * + * * @param nodeVector */ public NodeSequence(Object nodeVector) { super(nodeVector); + if (nodeVector instanceof NodeVector) { + SetVector((NodeVector) nodeVector); + } if(null != nodeVector) { - assertion(nodeVector instanceof NodeVector, + assertion(nodeVector instanceof NodeVector, "Must have a NodeVector as the object for NodeSequence!"); if(nodeVector instanceof DTMIterator) { setIter((DTMIterator)nodeVector); m_last = ((DTMIterator)nodeVector).getLength(); } - + } } - + /** - * Construct an empty XNodeSet object. This is used to create a mutable + * Construct an empty XNodeSet object. This is used to create a mutable * nodeset to which random nodes may be added. */ - public NodeSequence(DTMManager dtmMgr) + private NodeSequence(DTMManager dtmMgr) { super(new NodeVector()); m_last = 0; m_dtmMgr = dtmMgr; } - + /** * Create a new NodeSequence in an invalid (null) state. */ public NodeSequence() { + return; } @@ -198,7 +248,7 @@ return m_iter.getRoot(); else { - // NodeSetDTM will call this, and so it's not a good thing to throw + // NodeSetDTM will call this, and so it's not a good thing to throw // an assertion here. // assertion(false, "Can not get the root from a non-iterated NodeSequence!"); return DTM.NULL; @@ -211,7 +261,7 @@ public void setRoot(int nodeHandle, Object environment) { // If root is DTM.NULL, then something's wrong with the context - if (nodeHandle == DTM.NULL) + if (nodeHandle == DTM.NULL) { throw new RuntimeException("Unable to evaluate expression using " + "this context"); @@ -248,7 +298,7 @@ */ public int getWhatToShow() { - return hasCache() ? (DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE) + return hasCache() ? (DTMFilter.SHOW_ALL & ~DTMFilter.SHOW_ENTITY_REFERENCE) : m_iter.getWhatToShow(); } @@ -268,27 +318,29 @@ */ public int nextNode() { - // If the cache is on, and the node has already been found, then + // If the cache is on, and the node has already been found, then // just return from the list. NodeVector vec = getVector(); if (null != vec) - { + { + // There is a cache if(m_next < vec.size()) { + // The node is in the cache, so just return it. int next = vec.elementAt(m_next); m_next++; return next; } - else if((-1 != m_last) || (null == m_iter)) + else if(cacheComplete() || (-1 != m_last) || (null == m_iter)) { m_next++; return DTM.NULL; } } - + if (null == m_iter) return DTM.NULL; - + int next = m_iter.nextNode(); if(DTM.NULL != next) { @@ -311,10 +363,15 @@ } else { + // We have exhausted the iterator, and if there is a cache + // it must have all nodes in it by now, so let the cache + // know that it is complete. + markCacheComplete(); + m_last = m_next; m_next++; } - + return next; } @@ -352,7 +409,7 @@ } /** - * Calling this with a value of false will cause the nodeset + * Calling this with a value of false will cause the nodeset * to be cached. * @see DTMIterator#allowDetachToRelease(boolean) */ @@ -362,7 +419,7 @@ { setShouldCacheNodes(true); } - + if(null != m_iter) m_iter.allowDetachToRelease(allowRelease); super.allowDetachToRelease(allowRelease); @@ -382,7 +439,7 @@ else return DTM.NULL; } - + if(null != m_iter) { return m_iter.getCurrentNode(); @@ -439,7 +496,7 @@ public void runTo(int index) { int n; - + if (-1 == index) { int pos = m_next; @@ -459,10 +516,10 @@ while ((m_next >= index) && DTM.NULL != (n = previousNode())); } else - { + { while ((m_next < index) && DTM.NULL != (n = nextNode())); } - + } /** @@ -492,6 +549,40 @@ NodeVector vec = getVector(); if(null != vec) { + int oldNode = vec.elementAt(index); + if (oldNode != node && m_cache.useCount() > 1) { + /* If we are going to set the node at the given index + * to a different value, and the cache is shared + * (has a use count greater than 1) + * then make a copy of the cache and use it + * so we don't overwrite the value for other + * users of the cache. + */ + IteratorCache newCache = new IteratorCache(); + final NodeVector nv; + try { + nv = (NodeVector) vec.clone(); + } catch (CloneNotSupportedException e) { + // This should never happen + e.printStackTrace(); + RuntimeException rte = new RuntimeException(e.getMessage()); + throw rte; + } + newCache.setVector(nv); + newCache.setCacheComplete(true); + m_cache = newCache; + vec = nv; + + // Keep our superclass informed of the current NodeVector + super.setObject(nv); + + /* When we get to here the new cache has + * a use count of 1 and when setting a + * bunch of values on the same NodeSequence, + * such as when sorting, we will keep setting + * values in that same copy which has a use count of 1. + */ + } vec.setElementAt(node, index); m_last = vec.size(); } @@ -504,16 +595,26 @@ */ public int getLength() { - if(hasCache()) + IteratorCache cache = getCache(); + + if(cache != null) { + // Nodes from the iterator are cached + if (cache.isComplete()) { + // All of the nodes from the iterator are cached + // so just return the number of nodes in the cache + NodeVector nv = cache.getVector(); + return nv.size(); + } + // If this NodeSequence wraps a mutable nodeset, then // m_last will not reflect the size of the nodeset if // it has been mutated... if (m_iter instanceof NodeSetDTM) { return m_iter.getLength(); - } - + } + if(-1 == m_last) { int pos = m_next; @@ -536,11 +637,20 @@ { NodeSequence seq = (NodeSequence)super.clone(); seq.m_next = 0; + if (m_cache != null) { + // In making this clone of an iterator we are making + // another NodeSequence object it has a reference + // to the same IteratorCache object as the original + // so we need to remember that more than one + // NodeSequence object shares the cache. + m_cache.increaseUseCount(); + } + return seq; } - + /** - * Get a clone of this iterator, but don't reset the iteration in the + * Get a clone of this iterator, but don't reset the iteration in the * process, so that it may be used from the current position. * Note: Not a deep clone. * @@ -552,6 +662,15 @@ { NodeSequence clone = (NodeSequence) super.clone(); if (null != m_iter) clone.m_iter = (DTMIterator) m_iter.clone(); + if (m_cache != null) { + // In making this clone of an iterator we are making + // another NodeSequence object it has a reference + // to the same IteratorCache object as the original + // so we need to remember that more than one + // NodeSequence object shares the cache. + m_cache.increaseUseCount(); + } + return clone; } @@ -593,19 +712,19 @@ } /** - * @see com.sun.org.apache.xpath.internal.Expression#fixupVariables(Vector, int) + * @see org.apache.xpath.Expression#fixupVariables(Vector, int) */ public void fixupVariables(Vector vars, int globalsSize) { super.fixupVariables(vars, globalsSize); - } - + } + /** * Add the node into a vector of nodes where it should occur in * document order. * @param node The node to be added. * @return insertIndex. - * @throws RuntimeException thrown if this NodeSetDTM is not of + * @throws RuntimeException thrown if this NodeSetDTM is not of * a mutable type. */ protected int addNodeInDocOrder(int node) @@ -613,11 +732,11 @@ assertion(hasCache(), "addNodeInDocOrder must be done on a mutable sequence!"); int insertIndex = -1; - + NodeVector vec = getVector(); - // This needs to do a binary search, but a binary search - // is somewhat tough because the sequence test involves + // This needs to do a binary search, but a binary search + // is somewhat tough because the sequence test involves // two nodes. int size = vec.size(), i; @@ -649,5 +768,195 @@ // checkDups(); return insertIndex; } // end addNodeInDocOrder(Vector v, Object obj) + + /** + * It used to be that many locations in the code simply + * did an assignment to this.m_obj directly, rather than + * calling the setObject(Object) method. The problem is + * that our super-class would be updated on what the + * cache associated with this NodeSequence, but + * we wouldn't know ourselves. + * <p> + * All setting of m_obj is done through setObject() now, + * and this method over-rides the super-class method. + * So now we are in the loop have an opportunity + * to update some caching information. + * + */ + protected void setObject(Object obj) { + if (obj instanceof NodeVector) { + // Keep our superclass informed of the current NodeVector + // ... if we don't the smoketest fails (don't know why). + super.setObject(obj); + + // A copy of the code of what SetVector() would do. + NodeVector v = (NodeVector)obj; + if (m_cache != null) { + m_cache.setVector(v); + } else if (v!=null) { + m_cache = new IteratorCache(); + m_cache.setVector(v); + } + } else if (obj instanceof IteratorCache) { + IteratorCache cache = (IteratorCache) obj; + m_cache = cache; + m_cache.increaseUseCount(); + + // Keep our superclass informed of the current NodeVector + super.setObject(cache.getVector()); + } else { + super.setObject(obj); + } + + } + + /** + * Each NodeSequence object has an iterator which is "walked". + * As an iterator is walked one obtains nodes from it. + * As those nodes are obtained they may be cached, making + * the next walking of a copy or clone of the iterator faster. + * This field (m_cache) is a reference to such a cache, + * which is populated as the iterator is walked. + * <p> + * Note that multiple NodeSequence objects may hold a + * reference to the same cache, and also + * (and this is important) the same iterator. + * The iterator and its cache may be shared among + * many NodeSequence objects. + * <p> + * If one of the NodeSequence objects walks ahead + * of the others it fills in the cache. + * As the others NodeSequence objects catch up they + * get their values from + * the cache rather than the iterator itself, so + * the iterator is only ever walked once and everyone + * benefits from the cache. + * <p> + * At some point the cache may be + * complete due to walking to the end of one of + * the copies of the iterator, and the cache is + * then marked as "complete". + * and the cache will have no more nodes added to it. + * <p> + * Its use-count is the number of NodeSequence objects that use it. + */ + private final static class IteratorCache { + /** + * A list of nodes already obtained from the iterator. + * As the iterator is walked the nodes obtained from + * it are appended to this list. + * <p> + * Both an iterator and its corresponding cache can + * be shared by multiple NodeSequence objects. + * <p> + * For example, consider three NodeSequence objects + * ns1, ns2 and ns3 doing such sharing, and the + * nodes to be obtaind from the iterator being + * the sequence { 33, 11, 44, 22, 55 }. + * <p> + * If ns3.nextNode() is called 3 times the the + * underlying iterator will have walked through + * 33, 11, 55 and these three nodes will have been put + * in the cache. + * <p> + * If ns2.nextNode() is called 2 times it will return + * 33 and 11 from the cache, leaving the iterator alone. + * <p> + * If ns1.nextNode() is called 6 times it will return + * 33 and 11 from the cache, then get 44, 22, 55 from + * the iterator, and appending 44, 22, 55 to the cache. + * On the sixth call it is found that the iterator is + * exhausted and the cache is marked complete. + * <p> + * Should ns2 or ns3 have nextNode() called they will + * know that the cache is complete, and they will + * obtain all subsequent nodes from the cache. + * <p> + * Note that the underlying iterator, though shared + * is only ever walked once. + */ + private NodeVector m_vec2; + + /** + * true if the associated iterator is exhausted and + * all nodes obtained from it are in the cache. + */ + private boolean m_isComplete2; + + private int m_useCount2; + + IteratorCache() { + m_vec2 = null; + m_isComplete2 = false; + m_useCount2 = 1; + return; + } + + /** + * Returns count of how many NodeSequence objects share this + * IteratorCache object. + */ + private int useCount() { + return m_useCount2; + } + + /** + * This method is called when yet another + * NodeSequence object uses, or shares + * this same cache. + * + */ + private void increaseUseCount() { + if (m_vec2 != null) + m_useCount2++; + + } + + /** + * Sets the NodeVector that holds the + * growing list of nodes as they are appended + * to the cached list. + */ + private void setVector(NodeVector nv) { + m_vec2 = nv; + m_useCount2 = 1; + } + + /** + * Get the cached list of nodes obtained from + * the iterator so far. + */ + private NodeVector getVector() { + return m_vec2; + } + + /** + * Call this method with 'true' if the + * iterator is exhausted and the cached list + * is complete, or no longer growing. + */ + private void setCacheComplete(boolean b) { + m_isComplete2 = b; + + } + + /** + * Returns true if no cache is complete + * and immutable. + */ + private boolean isComplete() { + return m_isComplete2; + } + } + + /** + * Get the cached list of nodes appended with + * values obtained from the iterator as + * a NodeSequence is walked when its + * nextNode() method is called. + */ + protected IteratorCache getIteratorCache() { + return m_cache; + } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XBoolean.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XBoolean.java Wed Sep 28 17:10:18 2011 +0100 @@ -71,7 +71,7 @@ super(); m_val = b.booleanValue(); - m_obj = b; + setObject(b); } @@ -135,7 +135,7 @@ public Object object() { if(null == m_obj) - m_obj = new Boolean(m_val); + setObject(new Boolean(m_val)); return m_obj; }
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XNodeSet.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XNodeSet.java Wed Sep 28 17:10:18 2011 +0100 @@ -38,7 +38,7 @@ * @xsl.usage general */ public class XNodeSet extends NodeSequence -{ +{ static final long serialVersionUID = 1916026368035639667L; /** * Default constructor for derived objects. @@ -54,20 +54,25 @@ */ public XNodeSet(DTMIterator val) { - super(); - if(val instanceof XNodeSet) - { - setIter(((XNodeSet)val).m_iter); - m_dtmMgr = ((XNodeSet)val).m_dtmMgr; - m_last = ((XNodeSet)val).m_last; - if(!((XNodeSet)val).hasCache()) - ((XNodeSet)val).setShouldCacheNodes(true); - m_obj = ((XNodeSet)val).m_obj; - } - else - setIter(val); + super(); + if(val instanceof XNodeSet) + { + final XNodeSet nodeSet = (XNodeSet) val; + setIter(nodeSet.m_iter); + m_dtmMgr = nodeSet.m_dtmMgr; + m_last = nodeSet.m_last; + // First make sure the DTMIterator val has a cache, + // so if it doesn't have one, make one. + if(!nodeSet.hasCache()) + nodeSet.setShouldCacheNodes(true); + + // Get the cache from val and use it ourselves (we share it). + setObject(nodeSet.getIteratorCache()); + } + else + setIter(val); } - + /** * Construct a XNodeSet object. * @@ -75,21 +80,21 @@ */ public XNodeSet(XNodeSet val) { - super(); + super(); setIter(val.m_iter); m_dtmMgr = val.m_dtmMgr; m_last = val.m_last; if(!val.hasCache()) - val.setShouldCacheNodes(true); - m_obj = val.m_obj; + val.setShouldCacheNodes(true); + setObject(val.m_obj); } /** - * Construct an empty XNodeSet object. This is used to create a mutable + * Construct an empty XNodeSet object. This is used to create a mutable * nodeset to which random nodes may be added. */ - public XNodeSet(DTMManager dtmMgr) + public XNodeSet(DTMManager dtmMgr) { this(DTM.NULL,dtmMgr); } @@ -111,7 +116,7 @@ m_last = 1; } else - m_last = 0; + m_last = 0; } /** @@ -151,7 +156,7 @@ /** * Cast result object to a number. * - * @return numeric value of the string conversion from the + * @return numeric value of the string conversion from the * next node in the NodeSetDTM, or NAN if no node was found */ public double num() @@ -160,12 +165,12 @@ int node = item(0); return (node != DTM.NULL) ? getNumberFromNode(node) : Double.NaN; } - + /** - * Cast result object to a number, but allow side effects, such as the + * Cast result object to a number, but allow side effects, such as the * incrementing of an iterator. * - * @return numeric value of the string conversion from the + * @return numeric value of the string conversion from the * next node in the NodeSetDTM, or NAN if no node was found */ public double numWithSideEffects() @@ -185,9 +190,9 @@ { return (item(0) != DTM.NULL); } - + /** - * Cast result object to a boolean, but allow side effects, such as the + * Cast result object to a boolean, but allow side effects, such as the * incrementing of an iterator. * * @return True if there is a next node in the nodeset @@ -197,7 +202,7 @@ return (nextNode() != DTM.NULL); } - + /** * Get the string conversion from a single node. * @@ -218,7 +223,7 @@ return com.sun.org.apache.xpath.internal.objects.XString.EMPTYSTRING; } } - + /** * Directly call the * characters method on the passed ContentHandler for the @@ -234,25 +239,25 @@ throws org.xml.sax.SAXException { int node = item(0); - + if(node != DTM.NULL) { m_dtmMgr.getDTM(node).dispatchCharactersEvents(node, ch, false); } - + } - + /** * Cast result object to an XMLString. * - * @return The document fragment node data or the empty string. + * @return The document fragment node data or the empty string. */ public XMLString xstr() { int node = item(0); return (node != DTM.NULL) ? getStringFromNode(node) : XString.EMPTYSTRING; } - + /** * Cast result object to a string. * @@ -263,7 +268,7 @@ XString xstring = (XString)xstr(); xstring.appendToFsb(fsb); } - + /** * Cast result object to a string. @@ -274,9 +279,9 @@ public String str() { int node = item(0); - return (node != DTM.NULL) ? getStringFromNode(node).toString() : ""; + return (node != DTM.NULL) ? getStringFromNode(node).toString() : ""; } - + /** * Return a java object that's closest to the representation * that should be handed to an extension. @@ -286,9 +291,9 @@ public Object object() { if(null == m_obj) - return this; + return this; else - return m_obj; + return m_obj; } // %REVIEW% @@ -296,7 +301,7 @@ // /** // * Cast result object to a result tree fragment. // * -// * @param support The XPath context to use for the conversion +// * @param support The XPath context to use for the conversion // * // * @return the nodeset as a result tree fragment. // */ @@ -305,7 +310,7 @@ // DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // DocumentBuilder db = dbf.newDocumentBuilder(); // Document myDoc = db.newDocument(); -// +// // DocumentFragment docFrag = myDoc.createDocumentFragment(); // // DTMIterator nl = iter(); @@ -330,7 +335,7 @@ { return new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeIterator(iter()); } - + /** * Cast result object to a nodelist. * @@ -343,14 +348,14 @@ com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList nodelist = new com.sun.org.apache.xml.internal.dtm.ref.DTMNodeList(this); // Creating a DTMNodeList has the side-effect that it will create a clone // XNodeSet with cache and run m_iter to the end. You cannot get any node - // from m_iter after this call. As a fix, we call SetVector() on the clone's + // from m_iter after this call. As a fix, we call SetVector() on the clone's // cache. See Bugzilla 14406. XNodeSet clone = (XNodeSet)nodelist.getDTMIterator(); SetVector(clone.getVector()); return nodelist; } - + // /** // * Return a java object that's closest to the representation // * that should be handed to an extension. @@ -369,11 +374,11 @@ { return this; } - + public void release(DTMIterator iter) { } - + /** * Cast result object to a nodelist. * @@ -383,17 +388,17 @@ { try { - if(hasCache()) - return cloneWithReset(); - else - return this; // don't bother to clone... won't do any good! + if(hasCache()) + return cloneWithReset(); + else + return this; // don't bother to clone... won't do any good! } catch (CloneNotSupportedException cnse) { throw new RuntimeException(cnse.getMessage()); } } - + /** * Get a fresh copy of the object. For use with variables. * @@ -403,10 +408,10 @@ { try { - if(hasCache()) - return (XObject)cloneWithReset(); - else - return this; // don't bother to clone... won't do any good! + if(hasCache()) + return (XObject)cloneWithReset(); + else + return this; // don't bother to clone... won't do any good! } catch (CloneNotSupportedException cnse) { @@ -430,7 +435,7 @@ else { mnl = new NodeSetDTM(iter()); - m_obj = mnl; + setObject(mnl); setCurrentPos(0); } @@ -462,7 +467,7 @@ * @param obj2 Object to compare this nodeset to * @param comparator Comparator to use * - * @return See the comments below for each object type comparison + * @return See the comments below for each object type comparison * * @throws javax.xml.transform.TransformerException */ @@ -477,16 +482,16 @@ { // %OPT% This should be XMLString based instead of string based... - // From http://www.w3.org/TR/xpath: - // If both objects to be compared are node-sets, then the comparison - // will be true if and only if there is a node in the first node-set - // and a node in the second node-set such that the result of performing + // From http://www.w3.org/TR/xpath: + // If both objects to be compared are node-sets, then the comparison + // will be true if and only if there is a node in the first node-set + // and a node in the second node-set such that the result of performing // the comparison on the string-values of the two nodes is true. // Note this little gem from the draft: - // NOTE: If $x is bound to a node-set, then $x="foo" - // does not mean the same as not($x!="foo"): the former - // is true if and only if some node in $x has the string-value - // foo; the latter is true if and only if all nodes in $x have + // NOTE: If $x is bound to a node-set, then $x="foo" + // does not mean the same as not($x!="foo"): the former + // is true if and only if some node in $x has the string-value + // foo; the latter is true if and only if all nodes in $x have // the string-value foo. DTMIterator list1 = iterRaw(); DTMIterator list2 = ((XNodeSet) obj2).iterRaw(); @@ -539,11 +544,11 @@ else if (XObject.CLASS_BOOLEAN == type) { - // From http://www.w3.org/TR/xpath: - // If one object to be compared is a node-set and the other is a boolean, - // then the comparison will be true if and only if the result of - // performing the comparison on the boolean and on the result of - // converting the node-set to a boolean using the boolean function + // From http://www.w3.org/TR/xpath: + // If one object to be compared is a node-set and the other is a boolean, + // then the comparison will be true if and only if the result of + // performing the comparison on the boolean and on the result of + // converting the node-set to a boolean using the boolean function // is true. double num1 = bool() ? 1.0 : 0.0; double num2 = obj2.num(); @@ -553,13 +558,13 @@ else if (XObject.CLASS_NUMBER == type) { - // From http://www.w3.org/TR/xpath: - // If one object to be compared is a node-set and the other is a number, - // then the comparison will be true if and only if there is a - // node in the node-set such that the result of performing the - // comparison on the number to be compared and on the result of - // converting the string-value of that node to a number using - // the number function is true. + // From http://www.w3.org/TR/xpath: + // If one object to be compared is a node-set and the other is a number, + // then the comparison will be true if and only if there is a + // node in the node-set such that the result of performing the + // comparison on the number to be compared and on the result of + // converting the string-value of that node to a number using + // the number function is true. DTMIterator list1 = iterRaw(); double num2 = obj2.num(); int node; @@ -599,12 +604,12 @@ else if (XObject.CLASS_STRING == type) { - // From http://www.w3.org/TR/xpath: - // If one object to be compared is a node-set and the other is a - // string, then the comparison will be true if and only if there - // is a node in the node-set such that the result of performing - // the comparison on the string-value of the node and the other - // string is true. + // From http://www.w3.org/TR/xpath: + // If one object to be compared is a node-set and the other is a + // string, then the comparison will be true if and only if there + // is a node in the node-set such that the result of performing + // the comparison on the string-value of the node and the other + // string is true. XMLString s2 = obj2.xstr(); DTMIterator list1 = iterRaw(); int node; @@ -634,7 +639,7 @@ * * @param obj2 object to compare this nodeset to * - * @return see this.compare(...) + * @return see this.compare(...) * * @throws javax.xml.transform.TransformerException */ @@ -648,7 +653,7 @@ * * @param obj2 object to compare this nodeset to * - * @return see this.compare(...) + * @return see this.compare(...) * * @throws javax.xml.transform.TransformerException */ @@ -662,7 +667,7 @@ * * @param obj2 object to compare this nodeset to * - * @return see this.compare(...) + * @return see this.compare(...) * * @throws javax.xml.transform.TransformerException */ @@ -676,7 +681,7 @@ * * @param obj2 object to compare this nodeset to * - * @return see this.compare(...) + * @return see this.compare(...) * * @throws javax.xml.transform.TransformerException */ @@ -691,7 +696,7 @@ * * @param obj2 object to compare this nodeset to * - * @return see this.compare(...) + * @return see this.compare(...) * * @throws javax.xml.transform.TransformerException */ @@ -712,7 +717,7 @@ * * @param obj2 object to compare this nodeset to * - * @return see this.compare(...) + * @return see this.compare(...) * * @throws javax.xml.transform.TransformerException */ @@ -733,7 +738,7 @@ * * * @param s1 First string to compare - * @param s2 Second String to compare + * @param s2 Second String to compare * * @return Whether the strings are equal or not */ @@ -762,7 +767,7 @@ * * * @param s1 First string to compare - * @param s2 Second String to compare + * @param s2 Second String to compare * * @return True if s1 is less than s2 */
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XNodeSetForDOM.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XNodeSetForDOM.java Wed Sep 28 17:10:18 2011 +0100 @@ -31,7 +31,7 @@ import org.w3c.dom.traversal.NodeIterator; /** - * This class overrides the XNodeSet#object() method to provide the original + * This class overrides the XNodeSet#object() method to provide the original * Node object, NodeList object, or NodeIterator. */ public class XNodeSetForDOM extends XNodeSet @@ -44,10 +44,10 @@ m_dtmMgr = dtmMgr; m_origObj = node; int dtmHandle = dtmMgr.getDTMHandleFromNode(node); - m_obj = new NodeSetDTM(dtmMgr); + setObject(new NodeSetDTM(dtmMgr)); ((NodeSetDTM) m_obj).addNode(dtmHandle); } - + /** * Construct a XNodeSet object. * @@ -55,11 +55,11 @@ */ public XNodeSetForDOM(XNodeSet val) { - super(val); - if(val instanceof XNodeSetForDOM) - m_origObj = ((XNodeSetForDOM)val).m_origObj; + super(val); + if(val instanceof XNodeSetForDOM) + m_origObj = ((XNodeSetForDOM)val).m_origObj; } - + public XNodeSetForDOM(NodeList nodeList, XPathContext xctxt) { m_dtmMgr = xctxt.getDTMManager(); @@ -71,7 +71,7 @@ // m_obj=new com.sun.org.apache.xpath.internal.NodeSetDTM(nodeList, xctxt); com.sun.org.apache.xpath.internal.NodeSetDTM nsdtm=new com.sun.org.apache.xpath.internal.NodeSetDTM(nodeList, xctxt); m_last=nsdtm.getLength(); - m_obj = nsdtm; + setObject(nsdtm); } public XNodeSetForDOM(NodeIterator nodeIter, XPathContext xctxt) @@ -85,9 +85,9 @@ // m_obj = new com.sun.org.apache.xpath.internal.NodeSetDTM(nodeIter, xctxt); com.sun.org.apache.xpath.internal.NodeSetDTM nsdtm=new com.sun.org.apache.xpath.internal.NodeSetDTM(nodeIter, xctxt); m_last=nsdtm.getLength(); - m_obj = nsdtm; + setObject(nsdtm); } - + /** * Return the original DOM object that the user passed in. For use primarily * by the extension mechanism. @@ -98,7 +98,7 @@ { return m_origObj; } - + /** * Cast result object to a nodelist. Always issues an error. * @@ -108,10 +108,10 @@ */ public NodeIterator nodeset() throws javax.xml.transform.TransformerException { - return (m_origObj instanceof NodeIterator) - ? (NodeIterator)m_origObj : super.nodeset(); + return (m_origObj instanceof NodeIterator) + ? (NodeIterator)m_origObj : super.nodeset(); } - + /** * Cast result object to a nodelist. Always issues an error. * @@ -121,8 +121,8 @@ */ public NodeList nodelist() throws javax.xml.transform.TransformerException { - return (m_origObj instanceof NodeList) - ? (NodeList)m_origObj : super.nodelist(); + return (m_origObj instanceof NodeList) + ? (NodeList)m_origObj : super.nodelist(); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XNumber.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XNumber.java Wed Sep 28 17:10:18 2011 +0100 @@ -50,7 +50,7 @@ m_val = d; } - + /** * Construct a XNodeSet object. * @@ -62,13 +62,13 @@ super(); m_val = num.doubleValue(); - m_obj = num; + setObject(num); } /** * Tell that this is a CLASS_NUMBER. * - * @return node type CLASS_NUMBER + * @return node type CLASS_NUMBER */ public int getType() { @@ -79,7 +79,7 @@ * Given a request type, return the equivalent string. * For diagnostic purposes. * - * @return type string "#NUMBER" + * @return type string "#NUMBER" */ public String getTypeString() { @@ -95,7 +95,7 @@ { return m_val; } - + /** * Evaluate expression to a number. * @@ -103,7 +103,7 @@ * * @throws javax.xml.transform.TransformerException */ - public double num(XPathContext xctxt) + public double num(XPathContext xctxt) throws javax.xml.transform.TransformerException { @@ -238,7 +238,7 @@ // len = s.length(); // } // -// // Account for exponent by adding zeros as needed +// // Account for exponent by adding zeros as needed // // and moving the decimal place // // if (exp == 0) @@ -337,7 +337,7 @@ // Eliminate trailing 0's - bugzilla 14241 while (s.charAt(e-1) == '0') e--; - + if (exp > 0) return sign + s.substring(0, 1) + s.substring(2, 2 + exp) + "." + s.substring(2 + exp, e); @@ -379,7 +379,7 @@ public Object object() { if(null == m_obj) - m_obj = new Double(m_val); + setObject(new Double(m_val)); return m_obj; } @@ -388,37 +388,37 @@ * * @param obj2 Object to compare this to * - * @return true if the two objects are equal + * @return true if the two objects are equal * * @throws javax.xml.transform.TransformerException */ public boolean equals(XObject obj2) { - // In order to handle the 'all' semantics of - // nodeset comparisons, we always call the + // In order to handle the 'all' semantics of + // nodeset comparisons, we always call the // nodeset function. int t = obj2.getType(); try { - if (t == XObject.CLASS_NODESET) - return obj2.equals(this); - else if(t == XObject.CLASS_BOOLEAN) - return obj2.bool() == bool(); - else - return m_val == obj2.num(); + if (t == XObject.CLASS_NODESET) + return obj2.equals(this); + else if(t == XObject.CLASS_BOOLEAN) + return obj2.bool() == bool(); + else + return m_val == obj2.num(); } catch(javax.xml.transform.TransformerException te) { throw new com.sun.org.apache.xml.internal.utils.WrappedRuntimeException(te); } } - + /** - * Tell if this expression returns a stable number that will not change during - * iterations within the expression. This is used to determine if a proximity + * Tell if this expression returns a stable number that will not change during + * iterations within the expression. This is used to determine if a proximity * position predicate can indicate that no more searching has to occur. - * + * * * @return true if the expression represents a stable number. */ @@ -426,13 +426,13 @@ { return true; } - + /** * @see com.sun.org.apache.xpath.internal.XPathVisitable#callVisitors(ExpressionOwner, XPathVisitor) */ public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) { - visitor.visitNumberLiteral(owner, this); + visitor.visitNumberLiteral(owner, this); }
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XObject.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XObject.java Wed Sep 28 17:10:18 2011 +0100 @@ -70,7 +70,11 @@ */ public XObject(Object obj) { - m_obj = obj; + setObject(obj); + } + + protected void setObject(Object obj) { + m_obj = obj; } /** @@ -121,7 +125,7 @@ allowDetachToRelease(true); detach(); - m_obj = null; + setObject(null); } } @@ -735,23 +739,23 @@ */ public void callVisitors(ExpressionOwner owner, XPathVisitor visitor) { - assertion(false, "callVisitors should not be called for this object!!!"); + assertion(false, "callVisitors should not be called for this object!!!"); } /** * @see Expression#deepEquals(Expression) */ public boolean deepEquals(Expression expr) { - if(!isSameClass(expr)) - return false; + if(!isSameClass(expr)) + return false; - // If equals at the expression level calls deepEquals, I think we're - // still safe from infinite recursion since this object overrides - // equals. I hope. - if(!this.equals((XObject)expr)) - return false; + // If equals at the expression level calls deepEquals, I think we're + // still safe from infinite recursion since this object overrides + // equals. I hope. + if(!this.equals((XObject)expr)) + return false; - return true; + return true; } }
--- a/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XRTreeFrag.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/org/apache/xpath/internal/objects/XRTreeFrag.java Wed Sep 28 17:10:18 2011 +0100 @@ -53,19 +53,19 @@ { super(null); exprSetParent(parent); - initDTM(root, xctxt); + initDTM(root, xctxt); } - + /** * Create an XRTreeFrag Object. * */ public XRTreeFrag(int root, XPathContext xctxt) { - super(null); - initDTM(root, xctxt); + super(null); + initDTM(root, xctxt); } - + private final void initDTM(int root, XPathContext xctxt){ m_dtmRoot = root; final DTM dtm = xctxt.getDTM(root); @@ -73,7 +73,7 @@ m_DTMXRTreeFrag = xctxt.getDTMXRTreeFrag(xctxt.getDTMIdentity(dtm)); } } - + /** * Return a java object that's closest to the representation * that should be handed to an extension. @@ -87,7 +87,7 @@ else return super.object(); } - + /** * Create an XRTreeFrag Object. * @@ -96,11 +96,11 @@ { super(expr); } - + /** * Specify if it's OK for detach to release the iterator for reuse. - * - * @param allowRelease true if it is OK for detach to release this iterator + * + * @param allowRelease true if it is OK for detach to release this iterator * for pooling. */ public void allowDetachToRelease(boolean allowRelease) @@ -114,20 +114,20 @@ * in the INVALID state. After <code>detach</code> has been invoked, * calls to <code>nextNode</code> or <code>previousNode</code> will * raise a runtime exception. - * + * * In general, detach should only be called once on the object. */ public void detach(){ if(m_allowRelease){ - m_DTMXRTreeFrag.destruct(); - m_obj = null; + m_DTMXRTreeFrag.destruct(); + setObject(null); } } - + /** * Tell what kind of class this is. * - * @return type CLASS_RTREEFRAG + * @return type CLASS_RTREEFRAG */ public int getType() { @@ -169,22 +169,22 @@ { return true; } - + private XMLString m_xmlStr = null; - + /** * Cast result object to an XMLString. * - * @return The document fragment node data or the empty string. + * @return The document fragment node data or the empty string. */ public XMLString xstr() { if(null == m_xmlStr) m_xmlStr = m_DTMXRTreeFrag.getDTM().getStringValue(m_dtmRoot); - + return m_xmlStr; } - + /** * Cast result object to a string. * @@ -200,7 +200,7 @@ /** * Cast result object to a string. * - * @return The document fragment node data or the empty string. + * @return The document fragment node data or the empty string. */ public String str() { @@ -222,7 +222,7 @@ /** * Cast result object to a DTMIterator. * dml - modified to return an RTFIterator for - * benefit of EXSLT object-type function in + * benefit of EXSLT object-type function in * {@link com.sun.org.apache.xalan.internal.lib.ExsltCommon}. * @return The document fragment as a DTMIterator */ @@ -261,9 +261,9 @@ { if (XObject.CLASS_NODESET == obj2.getType()) { - - // In order to handle the 'all' semantics of - // nodeset comparisons, we always call the + + // In order to handle the 'all' semantics of + // nodeset comparisons, we always call the // nodeset function. return obj2.equals(this); } @@ -285,7 +285,7 @@ } else if (XObject.CLASS_RTREEFRAG == obj2.getType()) { - + // Probably not so good. Think about this. return xstr().equals(obj2.xstr()); }
--- a/sources/jaxp_src/src/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/com/sun/xml/internal/stream/writers/XMLDOMWriterImpl.java Wed Sep 28 17:10:18 2011 +0100 @@ -58,8 +58,8 @@ */ public class XMLDOMWriterImpl implements XMLStreamWriter { - - + + private Document ownerDoc = null; private Node currentNode = null; private Node node = null; @@ -74,7 +74,7 @@ * @param result DOMResult object @javax.xml.transform.dom.DOMResult */ public XMLDOMWriterImpl(DOMResult result) { - + node = result.getNode(); if( node.getNodeType() == Node.DOCUMENT_NODE){ ownerDoc = (Document)node; @@ -88,7 +88,7 @@ needContextPop = new boolean[resizeValue]; namespaceContext = new NamespaceSupport(); } - + private void getDLThreeMethods(){ try{ mXmlVersion = ownerDoc.getClass().getMethod("setXmlVersion",new Class[] {String.class}); @@ -100,8 +100,8 @@ mXmlVersion = null; } } - - + + /** * This method has no effect when called. * @throws javax.xml.stream.XMLStreamException {@inheritDoc} @@ -109,7 +109,7 @@ public void close() throws XMLStreamException { //no-op } - + /** * This method has no effect when called. * @throws javax.xml.stream.XMLStreamException {@inheritDoc} @@ -117,7 +117,7 @@ public void flush() throws XMLStreamException { //no-op } - + /** * {@inheritDoc} * @return {@inheritDoc} @@ -125,7 +125,7 @@ public javax.xml.namespace.NamespaceContext getNamespaceContext() { return null; } - + /** * {@inheritDoc} * @param namespaceURI {@inheritDoc} @@ -139,7 +139,7 @@ } return prefix; } - + /** * Is not supported in this implementation. * @param str {@inheritDoc} @@ -149,7 +149,7 @@ public Object getProperty(String str) throws IllegalArgumentException { throw new UnsupportedOperationException(); } - + /** * Is not supported in this version of the implementation. * @param uri {@inheritDoc} @@ -161,7 +161,7 @@ needContextPop[depth] = true; } } - + /** * {@inheritDoc} * @param namespaceContext {@inheritDoc} @@ -170,7 +170,7 @@ public void setNamespaceContext(javax.xml.namespace.NamespaceContext namespaceContext) throws XMLStreamException { throw new UnsupportedOperationException(); } - + /** * Is not supported in this version of the implementation. * @param prefix {@inheritDoc} @@ -186,7 +186,7 @@ needContextPop[depth] = true; } } - + /** * Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node. * @param localName {@inheritDoc} @@ -194,7 +194,7 @@ * @throws javax.xml.stream.XMLStreamException {@inheritDoc} */ public void writeAttribute(String localName, String value) throws XMLStreamException { - + if(currentNode.getNodeType() == Node.ELEMENT_NODE){ Attr attr = ownerDoc.createAttribute(localName); attr.setValue(value); @@ -205,7 +205,7 @@ "and does not allow attributes to be set "); } } - + /** * Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node. * @param namespaceURI {@inheritDoc} @@ -225,12 +225,12 @@ if(namespaceContext != null){ prefix = namespaceContext.getPrefix(namespaceURI); } - + if(prefix == null){ throw new XMLStreamException("Namespace URI "+namespaceURI + "is not bound to any prefix" ); } - + String qualifiedName = null; if(prefix.equals("")){ qualifiedName = localName; @@ -246,7 +246,7 @@ "and does not allow attributes to be set "); } } - + /** * Creates a DOM Atrribute @see org.w3c.dom.Node and associates it with the current DOM element @see org.w3c.dom.Node. * @param prefix {@inheritDoc} @@ -270,7 +270,7 @@ if(prefix.equals("")){ qualifiedName = localName; }else{ - + qualifiedName = getQName(prefix,localName); } Attr attr = ownerDoc.createAttributeNS(namespaceURI, qualifiedName); @@ -281,9 +281,9 @@ throw new IllegalStateException("Current DOM Node type is "+ currentNode.getNodeType() + "and does not allow attributes to be set "); } - + } - + /** * Creates a CDATA object @see org.w3c.dom.CDATASection. * @param data {@inheritDoc} @@ -293,11 +293,11 @@ if(data == null){ throw new XMLStreamException("CDATA cannot be null"); } - + CDATASection cdata = ownerDoc.createCDATASection(data); getNode().appendChild(cdata); } - + /** * Creates a character object @see org.w3c.dom.Text and appends it to the current * element in the DOM tree. @@ -308,7 +308,7 @@ Text text = ownerDoc.createTextNode(charData); currentNode.appendChild(text); } - + /** * Creates a character object @see org.w3c.dom.Text and appends it to the current * element in the DOM tree. @@ -318,11 +318,11 @@ * @throws javax.xml.stream.XMLStreamException {@inheritDoc} */ public void writeCharacters(char[] values, int param, int param2) throws XMLStreamException { - + Text text = ownerDoc.createTextNode(new String(values,param,param2)); currentNode.appendChild(text); } - + /** * Creates a Comment object @see org.w3c.dom.Comment and appends it to the current * element in the DOM tree. @@ -333,7 +333,7 @@ Comment comment = ownerDoc.createComment(str); getNode().appendChild(comment); } - + /** * This method is not supported in this implementation. * @param str {@inheritDoc} @@ -342,7 +342,7 @@ public void writeDTD(String str) throws XMLStreamException { throw new UnsupportedOperationException(); } - + /** * Creates a DOM attribute and adds it to the current element in the DOM tree. * @param namespaceURI {@inheritDoc} @@ -358,7 +358,7 @@ "and does not allow attributes to be set "); } } - + /** * creates a DOM Element and appends it to the current element in the tree. * @param localName {@inheritDoc} @@ -373,9 +373,9 @@ ownerDoc.appendChild(element); } } - + } - + /** * creates a DOM Element and appends it to the current element in the tree. * @param namespaceURI {@inheritDoc} @@ -392,7 +392,7 @@ if(localName == null){ throw new XMLStreamException("Local name cannot be null"); } - + if(namespaceContext != null){ prefix = namespaceContext.getPrefix(namespaceURI); } @@ -403,9 +403,9 @@ if("".equals(prefix)){ qualifiedName = localName; }else{ - + qualifiedName = getQName(prefix,localName); - + } Element element = ownerDoc.createElementNS(namespaceURI, qualifiedName); if(currentNode!=null){ @@ -416,7 +416,7 @@ //currentNode = element; } } - + /** * creates a DOM Element and appends it to the current element in the tree. * @param prefix {@inheritDoc} @@ -447,10 +447,10 @@ }else{ ownerDoc.appendChild(el); } - + } } - + /** * Will reset current Node pointer maintained by the implementation. * @throws javax.xml.stream.XMLStreamException {@inheritDoc} @@ -467,7 +467,7 @@ } depth =0; } - + /** * Internal current Node pointer will point to the parent of the current Node. * @throws javax.xml.stream.XMLStreamException {@inheritDoc} @@ -485,7 +485,7 @@ } depth--; } - + /** * Is not supported in this implementation. * @param name {@inheritDoc} @@ -495,7 +495,7 @@ EntityReference er = ownerDoc.createEntityReference(name); currentNode.appendChild(er); } - + /** * creates a namespace attribute and will associate it with the current element in * the DOM tree. @@ -514,7 +514,7 @@ } String qname = null; - + if (prefix.equals("")) { qname = XMLConstants.XMLNS_ATTRIBUTE; } else { @@ -523,7 +523,7 @@ ((Element)currentNode).setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI,qname, namespaceURI); } - + /** * is not supported in this release. * @param target {@inheritDoc} @@ -536,7 +536,7 @@ ProcessingInstruction pi = ownerDoc.createProcessingInstruction(target, ""); currentNode.appendChild(pi); } - + /** * is not supported in this release. * @param target {@inheritDoc} @@ -550,7 +550,7 @@ ProcessingInstruction pi = ownerDoc.createProcessingInstruction(target, data); currentNode.appendChild(pi); } - + /** * will set version on the Document object when the DOM Node passed to this implementation * supports DOM Level3 API's. @@ -567,7 +567,7 @@ throw new XMLStreamException(ite); } } - + /** * will set version on the Document object when the DOM Node passed to this implementation * supports DOM Level3 API's. @@ -585,7 +585,7 @@ throw new XMLStreamException(ite); } } - + /** * will set version on the Document object when the DOM Node passed to this implementation * supports DOM Level3 API's. @@ -605,7 +605,7 @@ } //TODO: What to do with encoding.-Venu } - + /** * creates a DOM Element and appends it to the current element in the tree. * @param localName {@inheritDoc} @@ -624,9 +624,9 @@ if(needContextPop[depth]){ namespaceContext.pushContext(); } - depth++; + incDepth(); } - + /** * creates a DOM Element and appends it to the current element in the tree. * @param namespaceURI {@inheritDoc} @@ -637,14 +637,14 @@ if(ownerDoc != null){ String qualifiedName = null; String prefix = null; - + if(namespaceURI == null ){ throw new XMLStreamException("NamespaceURI cannot be null"); } if(localName == null){ throw new XMLStreamException("Local name cannot be null"); } - + if(namespaceContext != null){ prefix = namespaceContext.getPrefix(namespaceURI); } @@ -657,9 +657,9 @@ }else{ qualifiedName = getQName(prefix,localName); } - + Element element = ownerDoc.createElementNS(namespaceURI, qualifiedName); - + if(currentNode!=null){ currentNode.appendChild(element); }else{ @@ -670,9 +670,9 @@ if(needContextPop[depth]){ namespaceContext.pushContext(); } - depth++; + incDepth(); } - + /** * creates a DOM Element and appends it to the current element in the tree. * @param prefix {@inheritDoc} @@ -681,7 +681,7 @@ * @throws javax.xml.stream.XMLStreamException {@inheritDoc} */ public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { - + if(ownerDoc != null){ String qname = null; if(namespaceURI == null ){ @@ -693,15 +693,15 @@ if(prefix == null){ throw new XMLStreamException("Prefix cannot be null"); } - + if(prefix.equals("")){ qname = localName; }else{ qname = getQName(prefix,localName); } - + Element el = ownerDoc.createElementNS(namespaceURI,qname); - + if(currentNode!=null){ currentNode.appendChild(el); }else{ @@ -711,11 +711,11 @@ if(needContextPop[depth]){ namespaceContext.pushContext(); } - depth++; - + incDepth(); + } } - + private String getQName(String prefix , String localName){ stringBuffer.setLength(0); stringBuffer.append(prefix); @@ -723,7 +723,7 @@ stringBuffer.append(localName); return stringBuffer.toString(); } - + private Node getNode(){ if(currentNode == null){ return ownerDoc; @@ -731,4 +731,12 @@ return currentNode; } } + private void incDepth() { + depth++; + if (depth == needContextPop.length) { + boolean[] array = new boolean[depth + resizeValue]; + System.arraycopy(needContextPop, 0, array, 0, depth); + needContextPop = array; + } + } }
--- a/sources/jaxp_src/src/javax/xml/XMLConstants.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/XMLConstants.java Wed Sep 28 17:10:18 2011 +0100 @@ -29,6 +29,7 @@ * <p>Utility class to contain basic XML values as constants.</p> * * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> + * @version $Revision: 1.8 $, $Date: 2010/05/25 16:19:45 $ * @see <a href="http://www.w3.org/TR/xml11/">Extensible Markup Language (XML) 1.1</a> * @see <a href="http://www.w3.org/TR/REC-xml">Extensible Markup Language (XML) 1.0 (Second Edition)</a> * @see <a href="http://www.w3.org/XML/xml-V10-2e-errata">XML 1.0 Second Edition Specification Errata</a> @@ -44,8 +45,8 @@ /** * <p>Private constructor to prevent instantiation.</p> */ - private XMLConstants() { - } + private XMLConstants() { + } /** * <p>Namespace URI to use to represent that there is no Namespace.</p> @@ -104,7 +105,7 @@ * href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames"> * Namespaces in XML, 3. Qualified Names</a> * @see <a - * href="http://www.w3.org/XML/xml-names-19990114-errata/"> + * href="http://www.w3.org/XML/xml-names-19990114-errata"> * Namespaces in XML Errata</a> */ public static final String XMLNS_ATTRIBUTE_NS_URI = @@ -123,12 +124,12 @@ * Namespaces in XML, 3. Qualified Names</a> */ public static final String XMLNS_ATTRIBUTE = "xmlns"; - + /** * <p>W3C XML Schema Namespace URI.</p> - * + * * <p>Defined to be "<code>http://www.w3.org/2001/XMLSchema</code>". - * + * * @see <a href= * "http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions"> * XML Schema Part 1: @@ -139,9 +140,9 @@ /** * <p>W3C XML Schema Instance Namespace URI.</p> - * + * * <p>Defined to be "<code>http://www.w3.org/2001/XMLSchema-instance</code>".</p> - * + * * @see <a href= * "http://www.w3.org/TR/xmlschema-1/#Instance_Document_Constructions"> * XML Schema Part 1: @@ -150,44 +151,44 @@ public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI = "http://www.w3.org/2001/XMLSchema-instance"; - /** - * <p>W3C XPath Datatype Namespace URI.</p> - * - * <p>Defined to be "<code>http://www.w3.org/2003/11/xpath-datatypes</code>".</p> - * - * @see <a href="http://www.w3.org/TR/xpath-datamodel">XQuery 1.0 and XPath 2.0 Data Model</a> - */ - public static final String W3C_XPATH_DATATYPE_NS_URI = "http://www.w3.org/2003/11/xpath-datatypes"; + /** + * <p>W3C XPath Datatype Namespace URI.</p> + * + * <p>Defined to be "<code>http://www.w3.org/2003/11/xpath-datatypes</code>".</p> + * + * @see <a href="http://www.w3.org/TR/xpath-datamodel">XQuery 1.0 and XPath 2.0 Data Model</a> + */ + public static final String W3C_XPATH_DATATYPE_NS_URI = "http://www.w3.org/2003/11/xpath-datatypes"; /** * <p>XML Document Type Declaration Namespace URI as an arbitrary value.</p> - * + * * <p>Since not formally defined by any existing standard, arbitrarily define to be "<code>http://www.w3.org/TR/REC-xml</code>". */ public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml"; - /** - * <p>RELAX NG Namespace URI.</p> - * - * <p>Defined to be "<code>http://relaxng.org/ns/structure/1.0</code>".</p> - * - * @see <a href="http://relaxng.org/spec-20011203.html">RELAX NG Specification</a> - */ - public static final String RELAXNG_NS_URI = "http://relaxng.org/ns/structure/1.0"; - - /** - * <p>Feature for secure processing.</p> - * - * <ul> - * <li> - * <code>true</code> instructs the implementation to process XML securely. - * This may set limits on XML constructs to avoid conditions such as denial of service attacks. - * </li> - * <li> - * <code>false</code> instructs the implementation to process XML acording the letter of the XML specifications - * ingoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks. - * </li> - * </ul> - */ - public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing"; + /** + * <p>RELAX NG Namespace URI.</p> + * + * <p>Defined to be "<code>http://relaxng.org/ns/structure/1.0</code>".</p> + * + * @see <a href="http://relaxng.org/spec-20011203.html">RELAX NG Specification</a> + */ + public static final String RELAXNG_NS_URI = "http://relaxng.org/ns/structure/1.0"; + + /** + * <p>Feature for secure processing.</p> + * + * <ul> + * <li> + * <code>true</code> instructs the implementation to process XML securely. + * This may set limits on XML constructs to avoid conditions such as denial of service attacks. + * </li> + * <li> + * <code>false</code> instructs the implementation to process XML acording the letter of the XML specifications + * ingoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks. + * </li> + * </ul> + */ + public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing"; }
--- a/sources/jaxp_src/src/javax/xml/datatype/DatatypeFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/datatype/DatatypeFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -33,7 +33,7 @@ /** * <p>Factory that creates new <code>javax.xml.datatype</code> <code>Object</code>s that map XML to/from Java <code>Object</code>s.</p> - * + * * <p><a name="DatatypeFactory.newInstance"/>{@link #newInstance()} is used to create a new <code>DatatypeFactory</code>. * The following implementation resolution mechanisms are used in the following order:</p> * <ol> @@ -56,37 +56,38 @@ * {@link #DATATYPEFACTORY_IMPLEMENTATION_CLASS}. * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. * </li> - * </ol> - * + * </ol> + * * @author <a href="mailto:Joseph.Fialli@Sun.COM">Joseph Fialli</a> * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> * + * @version $Revision: 1.13 $, $Date: 2010/03/11 23:10:53 $ * @since 1.5 */ public abstract class DatatypeFactory { - - /** - * <p>Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.</p> - * - * <p>Default value is <code>javax.xml.datatype.DatatypeFactory</code>.</p> - */ - public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory"; + + /** + * <p>Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.</p> + * + * <p>Default value is <code>javax.xml.datatype.DatatypeFactory</code>.</p> + */ + public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory"; - /** - * <p>Default implementation class name as defined in - * <em>JSR 206: Java(TM) API for XML Processing (JAXP) 1.3</em>.</p> - * - * <p>Implementers should specify the name of an appropriate class - * to be instantiated if no other implementation resolution mechanism - * succeeds.</p> - * - * <p>Users should not refer to this field; it is intended only to - * document a factory implementation detail. - * </p> - */ - public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = new String("com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl"); - + /** + * <p>Default implementation class name as defined in + * <em>JSR 206: Java(TM) API for XML Processing (JAXP) 1.3</em>.</p> + * + * <p>Implementers should specify the name of an appropriate class + * to be instantiated if no other implementation resolution mechanism + * succeeds.</p> + * + * <p>Users should not refer to this field; it is intended only to + * document a factory implementation detail. + * </p> + */ + public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = new String("com.sun.org.apache.xerces.internal.jaxp.datatype.DatatypeFactoryImpl"); + /** * http://www.w3.org/TR/xpath-datamodel/#xdtschema defines two regexps * to constrain the value space of dayTimeDuration ([^YM]*[DT].*) @@ -100,69 +101,69 @@ private static final Pattern XDTSCHEMA_DTD = Pattern.compile("[^YM]*[DT].*"); - /** - * <p>Protected constructor to prevent instaniation outside of package.</p> - * - * <p>Use {@link #newInstance()} to create a <code>DatatypeFactory</code>.</p> - */ - protected DatatypeFactory() { - } - - /** - * <p>Obtain a new instance of a <code>DatatypeFactory</code>.</p> - * + /** + * <p>Protected constructor to prevent instaniation outside of package.</p> + * + * <p>Use {@link #newInstance()} to create a <code>DatatypeFactory</code>.</p> + */ + protected DatatypeFactory() { + } + + /** + * <p>Obtain a new instance of a <code>DatatypeFactory</code>.</p> + * * <p>The implementation resolution mechanisms are <a href="#DatatypeFactory.newInstance">defined</a> in this * <code>Class</code>'s documentation.</p> - * - * @return New instance of a <code>DatatypeFactory</code> - * - * @throws DatatypeConfigurationException If the implementation is not - * available or cannot be instantiated. + * + * @return New instance of a <code>DatatypeFactory</code> + * + * @throws DatatypeConfigurationException If the implementation is not + * available or cannot be instantiated. * * @see #newInstance(String factoryClassName, ClassLoader classLoader) - */ - public static DatatypeFactory newInstance() - throws DatatypeConfigurationException { - - try { - return (DatatypeFactory) FactoryFinder.find( - /* The default property name according to the JAXP spec */ - DATATYPEFACTORY_PROPERTY, - /* The fallback implementation class name */ - DATATYPEFACTORY_IMPLEMENTATION_CLASS); - } catch (FactoryFinder.ConfigurationError e) { - throw new DatatypeConfigurationException(e.getMessage(), e.getException()); - } - } - + */ + public static DatatypeFactory newInstance() + throws DatatypeConfigurationException { + + try { + return (DatatypeFactory) FactoryFinder.find( + /* The default property name according to the JAXP spec */ + DATATYPEFACTORY_PROPERTY, + /* The fallback implementation class name */ + DATATYPEFACTORY_IMPLEMENTATION_CLASS); + } catch (FactoryFinder.ConfigurationError e) { + throw new DatatypeConfigurationException(e.getMessage(), e.getException()); + } + } + /** * <p>Obtain a new instance of a <code>DatatypeFactory</code> from class name. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider * should be loaded.</p> * - * <p>Once an application has obtained a reference to a <code>DatatypeFactory</code> + * <p>Once an application has obtained a reference to a <code>DatatypeFactory</code> * it can use the factory to configure and obtain datatype instances.</P> - * - * + * + * * <h2>Tip for Trouble-shooting</h2> * <p>Setting the <code>jaxp.debug</code> system property will cause * this method to print a lot of debug messages * to <code>System.err</code> about what it is doing and where it is looking at.</p> - * + * * <p> If you have problems try:</p> * <pre> * java -Djaxp.debug=1 YourProgram .... * </pre> - * + * * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.datatype.DatatypeFactory</code>. * - * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> + * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> * current <code>Thread</code>'s context classLoader is used to load the factory class. * * @return New instance of a <code>DatatypeFactory</code> * - * @throws DatatypeConfigurationException if <code>factoryClassName</code> is <code>null</code>, or + * @throws DatatypeConfigurationException if <code>factoryClassName</code> is <code>null</code>, or * the factory class cannot be loaded, instantiated. * * @see #newInstance() @@ -171,55 +172,55 @@ */ public static DatatypeFactory newInstance(String factoryClassName, ClassLoader classLoader) throws DatatypeConfigurationException { - try { + try { return (DatatypeFactory) FactoryFinder.newInstance(factoryClassName, classLoader, false); } catch (FactoryFinder.ConfigurationError e) { throw new DatatypeConfigurationException(e.getMessage(), e.getException()); - } + } } - - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS", - * as defined in XML Schema 1.0 section 3.2.6.1.</p> - * - * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> - * <blockquote> - * duration represents a duration of time. - * The value space of duration is a six-dimensional space where the coordinates designate the - * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. - * These components are ordered in their significance by their order of appearance i.e. as - * year, month, day, hour, minute, and second. - * </blockquote> + + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as its string representation, "PnYnMnDTnHnMnS", + * as defined in XML Schema 1.0 section 3.2.6.1.</p> + * + * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> + * <blockquote> + * duration represents a duration of time. + * The value space of duration is a six-dimensional space where the coordinates designate the + * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. + * These components are ordered in their significance by their order of appearance i.e. as + * year, month, day, hour, minute, and second. + * </blockquote> * <p>All six values are set and availabe from the created {@link Duration}</p> - * + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * - * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>. - * - * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>. - * - * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>. - * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>. - */ - public abstract Duration newDuration(final String lexicalRepresentation); - - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as milliseconds.</p> - * - * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> - * <blockquote> - * duration represents a duration of time. - * The value space of duration is a six-dimensional space where the coordinates designate the - * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. - * These components are ordered in their significance by their order of appearance i.e. as - * year, month, day, hour, minute, and second. - * </blockquote> + * + * @param lexicalRepresentation <code>String</code> representation of a <code>Duration</code>. + * + * @return New <code>Duration</code> created from parsing the <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code>. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException if <code>lexicalRepresentation</code> is <code>null</code>. + */ + public abstract Duration newDuration(final String lexicalRepresentation); + + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as milliseconds.</p> + * + * <p>XML Schema Part 2: Datatypes, 3.2.6 duration, defines <code>duration</code> as:</p> + * <blockquote> + * duration represents a duration of time. + * The value space of duration is a six-dimensional space where the coordinates designate the + * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. + * These components are ordered in their significance by their order of appearance i.e. as + * year, month, day, hour, minute, and second. + * </blockquote> * <p>All six values are set by computing their values from the specified milliseconds * and are availabe using the <code>get</code> methods of the created {@link Duration}. * The values conform to and are defined by:</p> @@ -230,63 +231,63 @@ * </li> * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> * </ul> - * - * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., - * {@link java.util.Calendar#YEAR} = 1970, - * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, - * {@link java.util.Calendar#DATE} = 1, etc. - * This is important as there are variations in the Gregorian Calendar, - * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p> - * - * @param durationInMilliSeconds Duration in milliseconds to create. - * - * @return New <code>Duration</code> representing <code>durationInMilliSeconds</code>. - */ - public abstract Duration newDuration(final long durationInMilliSeconds); - - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> - * + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.</p> + * + * @param durationInMilliSeconds Duration in milliseconds to create. + * + * @return New <code>Duration</code> representing <code>durationInMilliSeconds</code>. + */ + public abstract Duration newDuration(final long durationInMilliSeconds); + + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * + * * <p>A <code>null</code> value indicates that field is not set.</p> - * - * @param isPositive Set to <code>false</code> to create a negative duration. When the length - * of the duration is zero, this parameter will be ignored. - * @param years of this <code>Duration</code> - * @param months of this <code>Duration</code> - * @param days of this <code>Duration</code> - * @param hours of this <code>Duration</code> - * @param minutes of this <code>Duration</code> - * @param seconds of this <code>Duration</code> - * - * @return New <code>Duration</code> created from the specified values. - * - * @throws IllegalArgumentException If the values are not a valid representation of a - * <code>Duration</code>: if all the fields (years, months, ...) are null or - * if any of the fields is negative. - * @throws UnsupportedOperationException If implementation cannot support requested values. - */ - public abstract Duration newDuration( - final boolean isPositive, - final BigInteger years, - final BigInteger months, - final BigInteger days, - final BigInteger hours, - final BigInteger minutes, - final BigDecimal seconds); + * + * @param isPositive Set to <code>false</code> to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param years of this <code>Duration</code> + * @param months of this <code>Duration</code> + * @param days of this <code>Duration</code> + * @param hours of this <code>Duration</code> + * @param minutes of this <code>Duration</code> + * @param seconds of this <code>Duration</code> + * + * @return New <code>Duration</code> created from the specified values. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if all the fields (years, months, ...) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public abstract Duration newDuration( + final boolean isPositive, + final BigInteger years, + final BigInteger months, + final BigInteger days, + final BigInteger hours, + final BigInteger minutes, + final BigDecimal seconds); - /** - * <p>Obtain a new instance of a <code>Duration</code> - * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> - * + /** + * <p>Obtain a new instance of a <code>Duration</code> + * specifying the <code>Duration</code> as isPositive, years, months, days, hours, minutes, seconds.</p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * + * * @param isPositive Set to <code>false</code> to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. * @param years of this <code>Duration</code> @@ -295,112 +296,112 @@ * @param hours of this <code>Duration</code> * @param minutes of this <code>Duration</code> * @param seconds of this <code>Duration</code> - * - * @return New <code>Duration</code> created from the specified values. - * - * @throws IllegalArgumentException If the values are not a valid representation of a - * <code>Duration</code>: if any of the fields is negative. - * - * @see #newDuration( - * boolean isPositive, - * BigInteger years, - * BigInteger months, - * BigInteger days, - * BigInteger hours, - * BigInteger minutes, - * BigDecimal seconds) - */ - public Duration newDuration( - final boolean isPositive, - final int years, - final int months, - final int days, - final int hours, - final int minutes, - final int seconds) { - - // years may not be set - BigInteger realYears = (years != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) years) : null; - - // months may not be set - BigInteger realMonths = (months != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) months) : null; + * + * @return New <code>Duration</code> created from the specified values. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if any of the fields is negative. + * + * @see #newDuration( + * boolean isPositive, + * BigInteger years, + * BigInteger months, + * BigInteger days, + * BigInteger hours, + * BigInteger minutes, + * BigDecimal seconds) + */ + public Duration newDuration( + final boolean isPositive, + final int years, + final int months, + final int days, + final int hours, + final int minutes, + final int seconds) { + + // years may not be set + BigInteger realYears = (years != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) years) : null; + + // months may not be set + BigInteger realMonths = (months != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) months) : null; - // days may not be set - BigInteger realDays = (days != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) days) : null; + // days may not be set + BigInteger realDays = (days != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) days) : null; - // hours may not be set - BigInteger realHours = (hours != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) hours) : null; + // hours may not be set + BigInteger realHours = (hours != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) hours) : null; - // minutes may not be set - BigInteger realMinutes = (minutes != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) minutes) : null; - - // seconds may not be set - BigDecimal realSeconds = (seconds != DatatypeConstants.FIELD_UNDEFINED) ? BigDecimal.valueOf((long) seconds) : null; + // minutes may not be set + BigInteger realMinutes = (minutes != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) minutes) : null; + + // seconds may not be set + BigDecimal realSeconds = (seconds != DatatypeConstants.FIELD_UNDEFINED) ? BigDecimal.valueOf((long) seconds) : null; - return newDuration( - isPositive, - realYears, - realMonths, - realDays, - realHours, - realMinutes, - realSeconds - ); - } - - /** - * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation, - * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> - * - * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> - * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> - * + return newDuration( + isPositive, + realYears, + realMonths, + realDays, + realHours, + realMinutes, + realSeconds + ); + } + + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> by parsing its <code>String</code> representation, + * "<em>PnDTnHnMnS</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * * <p>All four values are set and availabe from the created {@link Duration}</p> - * + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * - * @param lexicalRepresentation Lexical representation of a duration. - * - * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. - * - * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of days and time. - * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. - */ - public Duration newDurationDayTime(final String lexicalRepresentation) { - // lexicalRepresentation must be non-null - if (lexicalRepresentation == null) { - throw new NullPointerException( + * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of days and time. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + public Duration newDurationDayTime(final String lexicalRepresentation) { + // lexicalRepresentation must be non-null + if (lexicalRepresentation == null) { + throw new NullPointerException( "Trying to create an xdt:dayTimeDuration with an invalid" + " lexical representation of \"null\""); - } + } - // test lexicalRepresentation against spec regex - Matcher matcher = XDTSCHEMA_DTD.matcher(lexicalRepresentation); - if (!matcher.matches()) { - throw new IllegalArgumentException( + // test lexicalRepresentation against spec regex + Matcher matcher = XDTSCHEMA_DTD.matcher(lexicalRepresentation); + if (!matcher.matches()) { + throw new IllegalArgumentException( "Trying to create an xdt:dayTimeDuration with an invalid" + " lexical representation of \"" + lexicalRepresentation + "\", data model requires years and months only."); - } + } - return newDuration(lexicalRepresentation); - } + return newDuration(lexicalRepresentation); + } - /** - * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in - * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> - * - * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> - * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> - * + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified milliseconds as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * * <p>All four values are set by computing their values from the specified milliseconds * and are availabe using the <code>get</code> methods of the created {@link Duration}. * The values conform to and are defined by:</p> @@ -411,144 +412,144 @@ * </li> * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> * </ul> - * - * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., - * {@link java.util.Calendar#YEAR} = 1970, - * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, - * {@link java.util.Calendar#DATE} = 1, etc. - * This is important as there are variations in the Gregorian Calendar, - * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getDays()} can be influenced.</p> - * + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getDays()} can be influenced.</p> + * * <p>Any remaining milliseconds after determining the day, hour, minute and second are discarded.</p> - * - * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. - * - * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>. - * - * @see <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a> - */ - public Duration newDurationDayTime(final long durationInMilliseconds) { - - return newDuration(durationInMilliseconds); - } - - /** - * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified - * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in - * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> - * - * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> - * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> - * + * + * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. + * + * @return New <code>Duration</code> created with the specified <code>durationInMilliseconds</code>. + * + * @see <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a> + */ + public Duration newDurationDayTime(final long durationInMilliseconds) { + + return newDuration(durationInMilliseconds); + } + + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified + * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * + * * <p>A <code>null</code> value indicates that field is not set.</p> - * + * * @param isPositive Set to <code>false</code> to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param day Day of <code>Duration</code>. - * @param hour Hour of <code>Duration</code>. - * @param minute Minute of <code>Duration</code>. - * @param second Second of <code>Duration</code>. - * - * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> - * and <code>second</code>. - * - * @throws IllegalArgumentException If the values are not a valid representation of a - * <code>Duration</code>: if all the fields (day, hour, ...) are null or - * if any of the fields is negative. - * @throws UnsupportedOperationException If implementation cannot support requested values. - */ - public Duration newDurationDayTime( - final boolean isPositive, - final BigInteger day, - final BigInteger hour, - final BigInteger minute, - final BigInteger second) { - - return newDuration( - isPositive, - null, // years - null, // months - day, - hour, - minute, - (second != null)? new BigDecimal(second):null - ); - } - - /** - * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified - * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in - * <a href="http://www.w3.org/TR/xpath-datamodel#dt-dayTimeDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> - * - * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> - * whose lexical representation contains only day, hour, minute, and second components. - * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> - * + * @param day Day of <code>Duration</code>. + * @param hour Hour of <code>Duration</code>. + * @param minute Minute of <code>Duration</code>. + * @param second Second of <code>Duration</code>. + * + * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> + * and <code>second</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if all the fields (day, hour, ...) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public Duration newDurationDayTime( + final boolean isPositive, + final BigInteger day, + final BigInteger hour, + final BigInteger minute, + final BigInteger second) { + + return newDuration( + isPositive, + null, // years + null, // months + day, + hour, + minute, + (second != null)? new BigDecimal(second):null + ); + } + + /** + * <p>Create a <code>Duration</code> of type <code>xdt:dayTimeDuration</code> using the specified + * <code>day</code>, <code>hour</code>, <code>minute</code> and <code>second</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#dayTimeDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration</a>.</p> + * + * <p>The datatype <code>xdt:dayTimeDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace <code>http://www.w3.org/2003/11/xpath-datatypes</code>.</p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * + * * @param isPositive Set to <code>false</code> to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param day Day of <code>Duration</code>. - * @param hour Hour of <code>Duration</code>. - * @param minute Minute of <code>Duration</code>. - * @param second Second of <code>Duration</code>. - * - * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> - * and <code>second</code>. - * - * @throws IllegalArgumentException If the values are not a valid representation of a - * <code>Duration</code>: if any of the fields (day, hour, ...) is negative. - */ - public Duration newDurationDayTime( - final boolean isPositive, - final int day, - final int hour, - final int minute, - final int second) { + * @param day Day of <code>Duration</code>. + * @param hour Hour of <code>Duration</code>. + * @param minute Minute of <code>Duration</code>. + * @param second Second of <code>Duration</code>. + * + * @return New <code>Duration</code> created with the specified <code>day</code>, <code>hour</code>, <code>minute</code> + * and <code>second</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if any of the fields (day, hour, ...) is negative. + */ + public Duration newDurationDayTime( + final boolean isPositive, + final int day, + final int hour, + final int minute, + final int second) { + + return newDurationDayTime( + isPositive, + BigInteger.valueOf((long) day), + BigInteger.valueOf((long) hour), + BigInteger.valueOf((long) minute), + BigInteger.valueOf((long) second) + ); + } - return newDurationDayTime( - isPositive, - BigInteger.valueOf((long) day), - BigInteger.valueOf((long) hour), - BigInteger.valueOf((long) minute), - BigInteger.valueOf((long) second) - ); - } - - /** - * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation, - * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> - * - * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> - * whose lexical representation contains only year and month components. - * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> - * + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> by parsing its <code>String</code> representation, + * "<em>PnYnM</em>", <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> + * * <p>Both values are set and availabe from the created {@link Duration}</p> - * + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * - * @param lexicalRepresentation Lexical representation of a duration. - * - * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. - * - * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of years and months. - * @throws UnsupportedOperationException If implementation cannot support requested values. - * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. - */ + * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @return New <code>Duration</code> created using the specified <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If <code>lexicalRepresentation</code> is not a valid representation of a <code>Duration</code> expressed only in terms of years and months. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ public Duration newDurationYearMonth( final String lexicalRepresentation) { @@ -568,18 +569,18 @@ + "\", data model requires days and times only."); } - return newDuration(lexicalRepresentation); + return newDuration(lexicalRepresentation); } - /** - * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in - * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> - * - * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> - * whose lexical representation contains only year and month components. - * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> - * + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified milliseconds as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * + * <p>The datatype <code>xdt:yearMonthDuration</code> is a subtype of <code>xs:duration</code> + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.</p> + * * <p>Both values are set by computing their values from the specified milliseconds * and are availabe using the <code>get</code> methods of the created {@link Duration}. * The values conform to and are defined by:</p> @@ -590,21 +591,21 @@ * </li> * <li>{@link XMLGregorianCalendar} Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation</li> * </ul> - * - * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., - * {@link java.util.Calendar#YEAR} = 1970, - * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, - * {@link java.util.Calendar#DATE} = 1, etc. - * This is important as there are variations in the Gregorian Calendar, - * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} - * so the result of {@link Duration#getMonths()} can be influenced.</p> - * + * + * <p>The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} can be influenced.</p> + * * <p>Any remaining milliseconds after determining the year and month are discarded.</p> - * - * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. - * - * @return New <code>Duration</code> created using the specified <code>durationInMilliseconds</code>. - */ + * + * @param durationInMilliseconds Milliseconds of <code>Duration</code> to create. + * + * @return New <code>Duration</code> created using the specified <code>durationInMilliseconds</code>. + */ public Duration newDurationYearMonth( final long durationInMilliseconds) { @@ -623,95 +624,95 @@ return newDurationYearMonth(isPositive, years, months); } - /** - * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified - * <code>year</code> and <code>month</code> as defined in - * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthyDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> - * + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified + * <code>year</code> and <code>month</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * * <p>The XML Schema specification states that values can be of an arbitrary size. * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits * if implementation capacities are exceeded.</p> - * + * * <p>A <code>null</code> value indicates that field is not set.</p> - * + * * @param isPositive Set to <code>false</code> to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param year Year of <code>Duration</code>. - * @param month Month of <code>Duration</code>. - * - * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. - * - * @throws IllegalArgumentException If the values are not a valid representation of a - * <code>Duration</code>: if all of the fields (year, month) are null or - * if any of the fields is negative. - * @throws UnsupportedOperationException If implementation cannot support requested values. - */ - public Duration newDurationYearMonth( - final boolean isPositive, - final BigInteger year, - final BigInteger month) { + * @param year Year of <code>Duration</code>. + * @param month Month of <code>Duration</code>. + * + * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if all of the fields (year, month) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public Duration newDurationYearMonth( + final boolean isPositive, + final BigInteger year, + final BigInteger month) { + + return newDuration( + isPositive, + year, + month, + null, // days + null, // hours + null, // minutes + null // seconds + ); + } - return newDuration( - isPositive, - year, - month, - null, // days - null, // hours - null, // minutes - null // seconds - ); - } - - /** - * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified - * <code>year</code> and <code>month</code> as defined in - * <a href="http://www.w3.org/TR/xpath-datamodel#dt-yearMonthyDuration"> - * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> - * + /** + * <p>Create a <code>Duration</code> of type <code>xdt:yearMonthDuration</code> using the specified + * <code>year</code> and <code>month</code> as defined in + * <a href="http://www.w3.org/TR/xpath-datamodel#yearMonthDuration"> + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration</a>.</p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * + * * @param isPositive Set to <code>false</code> to create a negative duration. When the length * of the duration is zero, this parameter will be ignored. - * @param year Year of <code>Duration</code>. - * @param month Month of <code>Duration</code>. - * - * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. - * - * @throws IllegalArgumentException If the values are not a valid representation of a - * <code>Duration</code>: if any of the fields (year, month) is negative. - */ - public Duration newDurationYearMonth( - final boolean isPositive, - final int year, - final int month) { + * @param year Year of <code>Duration</code>. + * @param month Month of <code>Duration</code>. + * + * @return New <code>Duration</code> created using the specified <code>year</code> and <code>month</code>. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * <code>Duration</code>: if any of the fields (year, month) is negative. + */ + public Duration newDurationYearMonth( + final boolean isPositive, + final int year, + final int month) { + + return newDurationYearMonth( + isPositive, + BigInteger.valueOf((long) year), + BigInteger.valueOf((long) month)); + } - return newDurationYearMonth( - isPositive, - BigInteger.valueOf((long) year), - BigInteger.valueOf((long) month)); - } - - /** - * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p> - * + /** + * <p>Create a new instance of an <code>XMLGregorianCalendar</code>.</p> + * * <p>All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.</p> - * + * * @return New <code>XMLGregorianCalendar</code> with all date/time datatype fields set to * {@link DatatypeConstants#FIELD_UNDEFINED} or null. - */ - public abstract XMLGregorianCalendar newXMLGregorianCalendar(); - - /** - * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p> - * - * <p>Parsing the lexical string representation is defined in + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar(); + + /** + * <p>Create a new XMLGregorianCalendar by parsing the String as a lexical representation.</p> + * + * <p>Parsing the lexical string representation is defined in * <a href="http://www.w3.org/TR/xmlschema-2/#dateTime-order">XML Schema 1.0 Part 2, Section 3.2.[7-14].1, * <em>Lexical Representation</em>.</a></p> - * + * * <p>The string representation may not have any leading and trailing whitespaces.</p> - * + * * <p>The parsing is done field by field so that * the following holds for any lexically correct String x:</p> * <pre> @@ -720,344 +721,344 @@ * <p>Except for the noted lexical/canonical representation mismatches * listed in <a href="http://www.w3.org/2001/05/xmlschema-errata#e2-45"> * XML Schema 1.0 errata, Section 3.2.7.2</a>.</p> - * - * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. - * - * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>. - * - * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>. - * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. - */ - public abstract XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation); + * + * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. + * + * @return <code>XMLGregorianCalendar</code> created from the <code>lexicalRepresentation</code>. + * + * @throws IllegalArgumentException If the <code>lexicalRepresentation</code> is not a valid <code>XMLGregorianCalendar</code>. + * @throws NullPointerException If <code>lexicalRepresentation</code> is <code>null</code>. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation); + + /** + * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p> + * + * <table border="2" rules="all" cellpadding="2"> + * <thead> + * <tr> + * <th align="center" colspan="2"> + * Field by Field Conversion from + * {@link GregorianCalendar} to an {@link XMLGregorianCalendar} + * </th> + * </tr> + * <tr> + * <th><code>java.util.GregorianCalendar</code> field</th> + * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> + * </tr> + * </thead> + * <tbody> + * <tr> + * <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td> + * <td>{@link XMLGregorianCalendar#setYear(int year)}</td> + * </tr> + * <tr> + * <td><code>MONTH + 1</code></td> + * <td>{@link XMLGregorianCalendar#setMonth(int month)}</td> + * </tr> + * <tr> + * <td><code>DAY_OF_MONTH</code></td> + * <td>{@link XMLGregorianCalendar#setDay(int day)}</td> + * </tr> + * <tr> + * <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td> + * <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td> + * </tr> + * <tr> + * <td> + * <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> + * <em>(in minutes)</em> + * </td> + * <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup> + * </td> + * </tr> + * </tbody> + * </table> + * <p><em>*</em>conversion loss of information. It is not possible to represent + * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the + * XML Schema 1.0 date/time datatype representation.</p> + * + * <p>To compute the return value's <code>TimeZone</code> field, + * <ul> + * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>, + * create a <code>java.util.TimeZone</code> with a custom timezone id + * using the <code>this.getTimezone()</code>.</li> + * <li>else use the <code>GregorianCalendar</code> default timezone value + * for the host is defined as specified by + * <code>java.util.TimeZone.getDefault()</code>.</li></p> + * + * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> + * + * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code> + * + * @throws NullPointerException If <code>cal</code> is <code>null</code>. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal); - /** - * <p>Create an <code>XMLGregorianCalendar</code> from a {@link GregorianCalendar}.</p> - * - * <table border="2" rules="all" cellpadding="2"> - * <thead> - * <tr> - * <th align="center" colspan="2"> - * Field by Field Conversion from - * {@link GregorianCalendar} to an {@link XMLGregorianCalendar} - * </th> - * </tr> - * <tr> - * <th><code>java.util.GregorianCalendar</code> field</th> - * <th><code>javax.xml.datatype.XMLGregorianCalendar</code> field</th> - * </tr> - * </thead> - * <tbody> - * <tr> - * <td><code>ERA == GregorianCalendar.BC ? -YEAR : YEAR</code></td> - * <td>{@link XMLGregorianCalendar#setYear(int year)}</td> - * </tr> - * <tr> - * <td><code>MONTH + 1</code></td> - * <td>{@link XMLGregorianCalendar#setMonth(int month)}</td> - * </tr> - * <tr> - * <td><code>DAY_OF_MONTH</code></td> - * <td>{@link XMLGregorianCalendar#setDay(int day)}</td> - * </tr> - * <tr> - * <td><code>HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND</code></td> - * <td>{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}</td> - * </tr> - * <tr> - * <td> - * <code>(ZONE_OFFSET + DST_OFFSET) / (60*1000)</code><br/> - * <em>(in minutes)</em> - * </td> - * <td>{@link XMLGregorianCalendar#setTimezone(int offset)}<sup><em>*</em></sup> - * </td> - * </tr> - * </tbody> - * </table> - * <p><em>*</em>conversion loss of information. It is not possible to represent - * a <code>java.util.GregorianCalendar</code> daylight savings timezone id in the - * XML Schema 1.0 date/time datatype representation.</p> - * - * <p>To compute the return value's <code>TimeZone</code> field, - * <ul> - * <li>when <code>this.getTimezone() != FIELD_UNDEFINED</code>, - * create a <code>java.util.TimeZone</code> with a custom timezone id - * using the <code>this.getTimezone()</code>.</li> - * <li>else use the <code>GregorianCalendar</code> default timezone value - * for the host is defined as specified by - * <code>java.util.TimeZone.getDefault()</code>.</li></p> - * - * @param cal <code>java.util.GregorianCalendar</code> used to create <code>XMLGregorianCalendar</code> - * - * @return <code>XMLGregorianCalendar</code> created from <code>java.util.GregorianCalendar</code> - * - * @throws NullPointerException If <code>cal</code> is <code>null</code>. - */ - public abstract XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal); - - /** - * <p>Constructor allowing for complete value spaces allowed by - * W3C XML Schema 1.0 recommendation for xsd:dateTime and related - * builtin datatypes. Note that <code>year</code> parameter supports - * arbitrarily large numbers and fractionalSecond has infinite - * precision.</p> - * + /** + * <p>Constructor allowing for complete value spaces allowed by + * W3C XML Schema 1.0 recommendation for xsd:dateTime and related + * builtin datatypes. Note that <code>year</code> parameter supports + * arbitrarily large numbers and fractionalSecond has infinite + * precision.</p> + * * <p>A <code>null</code> value indicates that field is not set.</p> - * - * @param year of <code>XMLGregorianCalendar</code> to be created. - * @param month of <code>XMLGregorianCalendar</code> to be created. - * @param day of <code>XMLGregorianCalendar</code> to be created. - * @param hour of <code>XMLGregorianCalendar</code> to be created. - * @param minute of <code>XMLGregorianCalendar</code> to be created. - * @param second of <code>XMLGregorianCalendar</code> to be created. - * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created. - * @param timezone of <code>XMLGregorianCalendar</code> to be created. - * - * @return <code>XMLGregorianCalendar</code> created from specified values. - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - */ - public abstract XMLGregorianCalendar newXMLGregorianCalendar( - final BigInteger year, - final int month, - final int day, - final int hour, - final int minute, - final int second, - final BigDecimal fractionalSecond, - final int timezone); - - /** - * <p>Constructor of value spaces that a - * <code>java.util.GregorianCalendar</code> instance would need to convert to an - * <code>XMLGregorianCalendar</code> instance.</p> - * - * <p><code>XMLGregorianCalendar eon</code> and - * <code>fractionalSecond</code> are set to <code>null</code></p> - * + * + * @param year of <code>XMLGregorianCalendar</code> to be created. + * @param month of <code>XMLGregorianCalendar</code> to be created. + * @param day of <code>XMLGregorianCalendar</code> to be created. + * @param hour of <code>XMLGregorianCalendar</code> to be created. + * @param minute of <code>XMLGregorianCalendar</code> to be created. + * @param second of <code>XMLGregorianCalendar</code> to be created. + * @param fractionalSecond of <code>XMLGregorianCalendar</code> to be created. + * @param timezone of <code>XMLGregorianCalendar</code> to be created. + * + * @return <code>XMLGregorianCalendar</code> created from specified values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar( + final BigInteger year, + final int month, + final int day, + final int hour, + final int minute, + final int second, + final BigDecimal fractionalSecond, + final int timezone); + + /** + * <p>Constructor of value spaces that a + * <code>java.util.GregorianCalendar</code> instance would need to convert to an + * <code>XMLGregorianCalendar</code> instance.</p> + * + * <p><code>XMLGregorianCalendar eon</code> and + * <code>fractionalSecond</code> are set to <code>null</code></p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * - * @param year of <code>XMLGregorianCalendar</code> to be created. - * @param month of <code>XMLGregorianCalendar</code> to be created. - * @param day of <code>XMLGregorianCalendar</code> to be created. - * @param hour of <code>XMLGregorianCalendar</code> to be created. - * @param minute of <code>XMLGregorianCalendar</code> to be created. - * @param second of <code>XMLGregorianCalendar</code> to be created. - * @param millisecond of <code>XMLGregorianCalendar</code> to be created. - * @param timezone of <code>XMLGregorianCalendar</code> to be created. - * - * @return <code>XMLGregorianCalendar</code> created from specified values. - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - */ - public XMLGregorianCalendar newXMLGregorianCalendar( - final int year, - final int month, - final int day, - final int hour, - final int minute, - final int second, - final int millisecond, - final int timezone) { - - // year may be undefined - BigInteger realYear = (year != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) year) : null; + * + * @param year of <code>XMLGregorianCalendar</code> to be created. + * @param month of <code>XMLGregorianCalendar</code> to be created. + * @param day of <code>XMLGregorianCalendar</code> to be created. + * @param hour of <code>XMLGregorianCalendar</code> to be created. + * @param minute of <code>XMLGregorianCalendar</code> to be created. + * @param second of <code>XMLGregorianCalendar</code> to be created. + * @param millisecond of <code>XMLGregorianCalendar</code> to be created. + * @param timezone of <code>XMLGregorianCalendar</code> to be created. + * + * @return <code>XMLGregorianCalendar</code> created from specified values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendar( + final int year, + final int month, + final int day, + final int hour, + final int minute, + final int second, + final int millisecond, + final int timezone) { + + // year may be undefined + BigInteger realYear = (year != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) year) : null; + + // millisecond may be undefined + // millisecond must be >= 0 millisecond <= 1000 + BigDecimal realMillisecond = null; // undefined value + if (millisecond != DatatypeConstants.FIELD_UNDEFINED) { + if (millisecond < 0 || millisecond > 1000) { + throw new IllegalArgumentException( + "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(" + + "int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)" + + "with invalid millisecond: " + millisecond + ); + } + + realMillisecond = BigDecimal.valueOf((long) millisecond).movePointLeft(3); + } + + return newXMLGregorianCalendar( + realYear, + month, + day, + hour, + minute, + second, + realMillisecond, + timezone + ); + } - // millisecond may be undefined - // millisecond must be >= 0 millisecond <= 1000 - BigDecimal realMillisecond = null; // undefined value - if (millisecond != DatatypeConstants.FIELD_UNDEFINED) { - if (millisecond < 0 || millisecond > 1000) { - throw new IllegalArgumentException( - "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(" - + "int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)" - + "with invalid millisecond: " + millisecond - ); - } - - realMillisecond = BigDecimal.valueOf((long) millisecond).movePointLeft(3); - } - - return newXMLGregorianCalendar( - realYear, - month, - day, - hour, - minute, - second, - realMillisecond, - timezone - ); - } - - /** - * <p>Create a Java representation of XML Schema builtin datatype <code>date</code> or <code>g*</code>.</p> - * - * <p>For example, an instance of <code>gYear</code> can be created invoking this factory - * with <code>month</code> and <code>day</code> parameters set to - * {@link DatatypeConstants#FIELD_UNDEFINED}.</p> - * + /** + * <p>Create a Java representation of XML Schema builtin datatype <code>date</code> or <code>g*</code>.</p> + * + * <p>For example, an instance of <code>gYear</code> can be created invoking this factory + * with <code>month</code> and <code>day</code> parameters set to + * {@link DatatypeConstants#FIELD_UNDEFINED}.</p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * - * @param year of <code>XMLGregorianCalendar</code> to be created. - * @param month of <code>XMLGregorianCalendar</code> to be created. - * @param day of <code>XMLGregorianCalendar</code> to be created. - * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. - * - * @return <code>XMLGregorianCalendar</code> created from parameter values. - * - * @see DatatypeConstants#FIELD_UNDEFINED - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - */ - public XMLGregorianCalendar newXMLGregorianCalendarDate( - final int year, - final int month, - final int day, - final int timezone) { - - return newXMLGregorianCalendar( - year, - month, - day, - DatatypeConstants.FIELD_UNDEFINED, // hour - DatatypeConstants.FIELD_UNDEFINED, // minute - DatatypeConstants.FIELD_UNDEFINED, // second - DatatypeConstants.FIELD_UNDEFINED, // millisecond - timezone); - } - - /** - * <p>Create a Java instance of XML Schema builtin datatype <code>time</code>.</p> - * + * + * @param year of <code>XMLGregorianCalendar</code> to be created. + * @param month of <code>XMLGregorianCalendar</code> to be created. + * @param day of <code>XMLGregorianCalendar</code> to be created. + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return <code>XMLGregorianCalendar</code> created from parameter values. + * + * @see DatatypeConstants#FIELD_UNDEFINED + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendarDate( + final int year, + final int month, + final int day, + final int timezone) { + + return newXMLGregorianCalendar( + year, + month, + day, + DatatypeConstants.FIELD_UNDEFINED, // hour + DatatypeConstants.FIELD_UNDEFINED, // minute + DatatypeConstants.FIELD_UNDEFINED, // second + DatatypeConstants.FIELD_UNDEFINED, // millisecond + timezone); + } + + /** + * <p>Create a Java instance of XML Schema builtin datatype <code>time</code>.</p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * - * @param hours number of hours - * @param minutes number of minutes - * @param seconds number of seconds - * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. - * - * @return <code>XMLGregorianCalendar</code> created from parameter values. - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - * - * @see DatatypeConstants#FIELD_UNDEFINED - */ - public XMLGregorianCalendar newXMLGregorianCalendarTime( - final int hours, - final int minutes, - final int seconds, - final int timezone) { - - return newXMLGregorianCalendar( - DatatypeConstants.FIELD_UNDEFINED, // Year - DatatypeConstants.FIELD_UNDEFINED, // Month - DatatypeConstants.FIELD_UNDEFINED, // Day - hours, - minutes, - seconds, - DatatypeConstants.FIELD_UNDEFINED, //Millisecond - timezone); - } - - /** - * <p>Create a Java instance of XML Schema builtin datatype time.</p> - * + * + * @param hours number of hours + * @param minutes number of minutes + * @param seconds number of seconds + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return <code>XMLGregorianCalendar</code> created from parameter values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + * + * @see DatatypeConstants#FIELD_UNDEFINED + */ + public XMLGregorianCalendar newXMLGregorianCalendarTime( + final int hours, + final int minutes, + final int seconds, + final int timezone) { + + return newXMLGregorianCalendar( + DatatypeConstants.FIELD_UNDEFINED, // Year + DatatypeConstants.FIELD_UNDEFINED, // Month + DatatypeConstants.FIELD_UNDEFINED, // Day + hours, + minutes, + seconds, + DatatypeConstants.FIELD_UNDEFINED, //Millisecond + timezone); + } + + /** + * <p>Create a Java instance of XML Schema builtin datatype time.</p> + * * <p>A <code>null</code> value indicates that field is not set.</p> * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * - * @param hours number of hours - * @param minutes number of minutes - * @param seconds number of seconds - * @param fractionalSecond value of <code>null</code> indicates that this optional field is not set. - * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. - * - * @return <code>XMLGregorianCalendar</code> created from parameter values. - * - * @see DatatypeConstants#FIELD_UNDEFINED - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - */ - public XMLGregorianCalendar newXMLGregorianCalendarTime( - final int hours, - final int minutes, - final int seconds, - final BigDecimal fractionalSecond, - final int timezone) { + * + * @param hours number of hours + * @param minutes number of minutes + * @param seconds number of seconds + * @param fractionalSecond value of <code>null</code> indicates that this optional field is not set. + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return <code>XMLGregorianCalendar</code> created from parameter values. + * + * @see DatatypeConstants#FIELD_UNDEFINED + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendarTime( + final int hours, + final int minutes, + final int seconds, + final BigDecimal fractionalSecond, + final int timezone) { + + return newXMLGregorianCalendar( + null, // year + DatatypeConstants.FIELD_UNDEFINED, // month + DatatypeConstants.FIELD_UNDEFINED, // day + hours, + minutes, + seconds, + fractionalSecond, + timezone); + } - return newXMLGregorianCalendar( - null, // year - DatatypeConstants.FIELD_UNDEFINED, // month - DatatypeConstants.FIELD_UNDEFINED, // day - hours, - minutes, - seconds, - fractionalSecond, - timezone); - } - - /** - * <p>Create a Java instance of XML Schema builtin datatype time.</p> - * + /** + * <p>Create a Java instance of XML Schema builtin datatype time.</p> + * * <p>A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.</p> - * - * @param hours number of hours - * @param minutes number of minutes - * @param seconds number of seconds - * @param milliseconds number of milliseconds - * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. - * - * @return <code>XMLGregorianCalendar</code> created from parameter values. - * - * @see DatatypeConstants#FIELD_UNDEFINED - * - * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field - * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} - * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance - * as determined by {@link XMLGregorianCalendar#isValid()}. - */ - public XMLGregorianCalendar newXMLGregorianCalendarTime( - final int hours, - final int minutes, - final int seconds, - final int milliseconds, - final int timezone) { - - // millisecond may be undefined - // millisecond must be >= 0 millisecond <= 1000 - BigDecimal realMilliseconds = null; // undefined value - if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) { - if (milliseconds < 0 || milliseconds > 1000) { - throw new IllegalArgumentException( - "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendarTime(" - + "int hours, int minutes, int seconds, int milliseconds, int timezone)" - + "with invalid milliseconds: " + milliseconds - ); - } - - realMilliseconds = BigDecimal.valueOf((long) milliseconds).movePointLeft(3); - } - - return newXMLGregorianCalendarTime( - hours, - minutes, - seconds, - realMilliseconds, - timezone - ); - } + * + * @param hours number of hours + * @param minutes number of minutes + * @param seconds number of seconds + * @param milliseconds number of milliseconds + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return <code>XMLGregorianCalendar</code> created from parameter values. + * + * @see DatatypeConstants#FIELD_UNDEFINED + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid <code>XMLGregorianCalendar</code> instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendarTime( + final int hours, + final int minutes, + final int seconds, + final int milliseconds, + final int timezone) { + + // millisecond may be undefined + // millisecond must be >= 0 millisecond <= 1000 + BigDecimal realMilliseconds = null; // undefined value + if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) { + if (milliseconds < 0 || milliseconds > 1000) { + throw new IllegalArgumentException( + "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendarTime(" + + "int hours, int minutes, int seconds, int milliseconds, int timezone)" + + "with invalid milliseconds: " + milliseconds + ); + } + + realMilliseconds = BigDecimal.valueOf((long) milliseconds).movePointLeft(3); + } + + return newXMLGregorianCalendarTime( + hours, + minutes, + seconds, + realMilliseconds, + timezone + ); + } }
--- a/sources/jaxp_src/src/javax/xml/datatype/FactoryFinder.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/datatype/FactoryFinder.java Wed Sep 28 17:10:18 2011 +0100 @@ -37,30 +37,30 @@ /** * <p>Implements pluggable Datatypes.</p> - * + * * <p>This class is duplicated for each JAXP subpackage so keep it in * sync. It is package private for secure class loading.</p> * * @author Santiago.PericasGeertsen@sun.com */ class FactoryFinder { - + /** * Internal debug flag. */ private static boolean debug = false; - + /** * Cache for properties in java.home/lib/jaxp.properties */ static Properties cacheProps = new Properties(); - + /** - * Flag indicating if properties from java.home/lib/jaxp.properties + * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ static boolean firstTime = true; - + /** * Security support class use to check access control before * getting certain system resources. @@ -75,29 +75,29 @@ String val = ss.getSystemProperty("jaxp.debug"); // Allow simply setting the prop to turn on debug debug = val != null && !"false".equals(val); - } + } catch (SecurityException se) { debug = false; } } - + private static void dPrint(String msg) { if (debug) { System.err.println("JAXP: " + msg); } } - + /** * Attempt to load a class using the class loader supplied. If that fails * and fall back is enabled, the current (i.e. bootstrap) class loader is - * tried. - * + * tried. + * * If the class loader supplied is <code>null</code>, first try using the * context class loader followed by the current (i.e. bootstrap) class - * loader. + * loader. */ static private Class getProviderClass(String className, ClassLoader cl, - boolean doFallback) throws ClassNotFoundException + boolean doFallback) throws ClassNotFoundException { try { if (cl == null) { @@ -108,7 +108,7 @@ else { return cl.loadClass(className); } - } + } else { return cl.loadClass(className); } @@ -117,15 +117,15 @@ if (doFallback) { // Use current class loader - should always be bootstrap CL return Class.forName(className, true, FactoryFinder.class.getClassLoader()); - } + } else { throw e1; } - } + } } - + /** - * Create an instance of a class. Delegates to method + * Create an instance of a class. Delegates to method * <code>getProviderClass()</code> in order to load the class. * * @param className Name of the concrete class corresponding to the @@ -136,30 +136,30 @@ * * @param doFallback True if the current ClassLoader should be tried as * a fallback if the class is not found using cl - */ + */ static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError { try { - Class providerClass = getProviderClass(className, cl, doFallback); + Class providerClass = getProviderClass(className, cl, doFallback); Object instance = providerClass.newInstance(); if (debug) { // Extra check to avoid computing cl strings dPrint("created new instance of " + providerClass + " using ClassLoader: " + cl); } return instance; - } + } catch (ClassNotFoundException x) { throw new ConfigurationError( "Provider " + className + " not found", x); - } + } catch (Exception x) { throw new ConfigurationError( "Provider " + className + " could not be instantiated: " + x, x); } } - + /** * Finds the implementation Class object in the specified order. Main * entry point. @@ -174,17 +174,17 @@ */ static Object find(String factoryId, String fallbackClassName) throws ConfigurationError - { + { dPrint("find factoryId =" + factoryId); - + // Use the system property first try { String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { + if (systemProp != null) { dPrint("found system property, value=" + systemProp); return newInstance(systemProp, null, true); } - } + } catch (SecurityException se) { if (debug) se.printStackTrace(); } @@ -206,13 +206,13 @@ } } } - factoryClassName = cacheProps.getProperty(factoryId); + factoryClassName = cacheProps.getProperty(factoryId); if (factoryClassName != null) { dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); return newInstance(factoryClassName, null, true); } - } + } catch (Exception ex) { if (debug) ex.printStackTrace(); } @@ -230,26 +230,26 @@ dPrint("loaded from fallback value: " + fallbackClassName); return newInstance(fallbackClassName, null, true); } - + /* * Try to find provider using Jar Service Provider Mechanism * * @return instance of provider class if found or null */ private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError + throws ConfigurationError { String serviceId = "META-INF/services/" + factoryId; InputStream is = null; - + // First try the Context ClassLoader ClassLoader cl = ss.getContextClassLoader(); if (cl != null) { is = ss.getResourceAsStream(cl, serviceId); - + // If no provider found then try the current ClassLoader if (is == null) { - cl = FactoryFinder.class.getClassLoader(); + cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); } } else { @@ -257,24 +257,24 @@ cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); } - + if (is == null) { // No provider found return null; } - + if (debug) { // Extra check to avoid computing cl strings dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); } - + BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); - } + } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is)); } - + String factoryClassName = null; try { // XXX Does not handle all possible input as specified by the @@ -285,24 +285,24 @@ // No provider found return null; } - + if (factoryClassName != null && !"".equals(factoryClassName)) { dPrint("found in resource, value=" + factoryClassName); - + // Note: here we do not want to fall back to the current // ClassLoader because we want to avoid the case where the // resource file was found using one ClassLoader and the // provider class was instantiated using a different one. return newInstance(factoryClassName, cl, false); } - + // No provider found return null; } - + static class ConfigurationError extends Error { private Exception exception; - + /** * Construct a new instance with the specified detail string and * exception. @@ -311,10 +311,17 @@ super(msg); this.exception = x; } - + Exception getException() { return exception; } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } } - + }
--- a/sources/jaxp_src/src/javax/xml/namespace/QName.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/namespace/QName.java Wed Sep 28 17:10:18 2011 +0100 @@ -62,6 +62,7 @@ * <p><code>QName</code> is immutable.</p> * * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> + * @version $Revision: 1.8 $, $Date: 2010/03/18 03:06:17 $ * @see <a href="http://www.w3.org/TR/xmlschema-2/#QName"> * XML Schema Part2: Datatypes specification</a> * @see <a href="http://www.w3.org/TR/REC-xml-names/#ns-qualnames"> @@ -355,14 +356,18 @@ * equal to this <code>QName</code> else <code>false</code> */ public final boolean equals(Object objectToTest) { + if (objectToTest == this) { + return true; + } + if (objectToTest == null || !(objectToTest instanceof QName)) { return false; } QName qName = (QName) objectToTest; - return namespaceURI.equals(qName.namespaceURI) - && localPart.equals(qName.localPart); + return localPart.equals(qName.localPart) + && namespaceURI.equals(qName.namespaceURI); } /**
--- a/sources/jaxp_src/src/javax/xml/parsers/DocumentBuilderFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/parsers/DocumentBuilderFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -34,11 +34,12 @@ * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> * + * @version $Revision: 1.9 $, $Date: 2010/05/25 16:19:44 $ */ public abstract class DocumentBuilderFactory { - + /** The default property name according to the JAXP spec */ private static final String DEFAULT_PROPERTY_NAME = "javax.xml.parsers.DocumentBuilderFactory"; @@ -48,9 +49,9 @@ private boolean expandEntityRef = true; private boolean ignoreComments = false; private boolean coalescing = false; - + private boolean canonicalState = false; - + /** * <p>Protected constructor to prevent instantiation. * Use {@link #newInstance()}.</p> @@ -76,7 +77,7 @@ * </code> format and contains the fully qualified name of the * implementation class with the key being the system property defined * above. - * + * * The jaxp.properties file is read only once by the JAXP implementation * and it's values are then cached for future use. If the file does not exist * when the first attempt is made to read from it, no further attempts are @@ -98,18 +99,18 @@ * Once an application has obtained a reference to a * <code>DocumentBuilderFactory</code> it can use the factory to * configure and obtain parser instances. - * - * + * + * * <h2>Tip for Trouble-shooting</h2> * <p>Setting the <code>jaxp.debug</code> system property will cause * this method to print a lot of debug messages * to <code>System.err</code> about what it is doing and where it is looking at.</p> - * + * * <p> If you have problems loading {@link DocumentBuilder}s, try:</p> * <pre> * java -Djaxp.debug=1 YourProgram .... * </pre> - * + * * @return New instance of a <code>DocumentBuilderFactory</code> * * @throws FactoryConfigurationError if the implementation is not @@ -135,29 +136,29 @@ * It gives more control to the application as it can specify which provider * should be loaded.</p> * - * <p>Once an application has obtained a reference to a <code>DocumentBuilderFactory</code> + * <p>Once an application has obtained a reference to a <code>DocumentBuilderFactory</code> * it can use the factory to configure and obtain parser instances.</p> - * - * + * + * * <h2>Tip for Trouble-shooting</h2> * <p>Setting the <code>jaxp.debug</code> system property will cause * this method to print a lot of debug messages * to <code>System.err</code> about what it is doing and where it is looking at.</p> - * + * * <p> If you have problems try:</p> * <pre> * java -Djaxp.debug=1 YourProgram .... * </pre> - * + * * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.parsers.DocumentBuilderFactory</code>. * - * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> + * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> * current <code>Thread</code>'s context classLoader is used to load the factory class. * * @return New instance of a <code>DocumentBuilderFactory</code> * - * @throws FactoryConfigurationError if <code>factoryClassName</code> is <code>null</code>, or - * the factory class cannot be loaded, instantiated. + * @throws FactoryConfigurationError if <code>factoryClassName</code> is <code>null</code>, or + * the factory class cannot be loaded, instantiated. * * @see #newInstance() * @@ -170,7 +171,7 @@ } catch (FactoryFinder.ConfigurationError e) { throw new FactoryConfigurationError(e.getException(), e.getMessage()); - } + } } /** @@ -182,11 +183,11 @@ * @throws ParserConfigurationException if a DocumentBuilder * cannot be created which satisfies the configuration requested. */ - + public abstract DocumentBuilder newDocumentBuilder() throws ParserConfigurationException; - - + + /** * Specifies that the parser produced by this code will * provide support for XML namespaces. By default the value of this is set @@ -195,7 +196,7 @@ * @param awareness true if the parser produced will provide support * for XML namespaces; false otherwise. */ - + public void setNamespaceAware(boolean awareness) { this.namespaceAware = awareness; } @@ -204,7 +205,7 @@ * Specifies that the parser produced by this code will * validate documents as they are parsed. By default the value of this * is set to <code>false</code>. - * + * * <p> * Note that "the validation" here means * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating @@ -212,7 +213,7 @@ * In other words, it essentially just controls the DTD validation. * (except the legacy two properties defined in JAXP 1.2.) * </p> - * + * * <p> * To use modern schema languages such as W3C XML Schema or * RELAX NG instead of DTD, you can configure your parser to be @@ -220,11 +221,11 @@ * method <code>false</code>, then use the {@link #setSchema(Schema)} * method to associate a schema to a parser. * </p> - * + * * @param validating true if the parser produced will validate documents * as they are parsed; false otherwise. */ - + public void setValidating(boolean validating) { this.validating = validating; } @@ -256,7 +257,7 @@ * @param expandEntityRef true if the parser produced will expand entity * reference nodes; false otherwise. */ - + public void setExpandEntityReferences(boolean expandEntityRef) { this.expandEntityRef = expandEntityRef; } @@ -265,10 +266,10 @@ * <p>Specifies that the parser produced by this code will * ignore comments. By default the value of this is set to <code>false * </code>.</p> - * + * * @param ignoreComments <code>boolean</code> value to ignore comments during processing */ - + public void setIgnoringComments(boolean ignoreComments) { this.ignoreComments = ignoreComments; } @@ -283,7 +284,7 @@ * to Text nodes and append it to the adjacent (if any) * text node; false otherwise. */ - + public void setCoalescing(boolean coalescing) { this.coalescing = coalescing; } @@ -295,7 +296,7 @@ * @return true if the factory is configured to produce parsers which * are namespace aware; false otherwise. */ - + public boolean isNamespaceAware() { return namespaceAware; } @@ -307,7 +308,7 @@ * @return true if the factory is configured to produce parsers * which validate the XML content during parse; false otherwise. */ - + public boolean isValidating() { return validating; } @@ -320,7 +321,7 @@ * which ignore ignorable whitespace in element content; * false otherwise. */ - + public boolean isIgnoringElementContentWhitespace() { return whitespace; } @@ -332,7 +333,7 @@ * @return true if the factory is configured to produce parsers * which expand entity reference nodes; false otherwise. */ - + public boolean isExpandEntityReferences() { return expandEntityRef; } @@ -344,7 +345,7 @@ * @return true if the factory is configured to produce parsers * which ignores comments; false otherwise. */ - + public boolean isIgnoringComments() { return ignoreComments; } @@ -358,7 +359,7 @@ * which converts CDATA nodes to Text nodes and appends it to * the adjacent (if any) Text node; false otherwise. */ - + public boolean isCoalescing() { return coalescing; } @@ -389,67 +390,67 @@ */ public abstract Object getAttribute(String name) throws IllegalArgumentException; + + /** + * <p>Set a feature for this <code>DocumentBuilderFactory</code> and <code>DocumentBuilder</code>s created by this factory.</p> + * + * <p> + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * A {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the + * <code>DocumentBuilder</code>s it creates cannot support the feature. + * It is possible for a <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state. + * </p> + * + * <p> + * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is:</p> + * <ul> + * <li> + * <code>true</code>: the implementation will limit XML processing to conform to implementation limits. + * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. + * If XML processing is limited for security reasons, it will be reported via a call to the registered + * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. + * See {@link DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}. + * </li> + * <li> + * <code>false</code>: the implementation will processing XML according to the XML specifications without + * regard to possible implementation limits. + * </li> + * </ul> + * + * @param name Feature name. + * @param value Is feature state <code>true</code> or <code>false</code>. + * + * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> or the <code>DocumentBuilder</code>s + * it creates cannot support this feature. + * @throws NullPointerException If the <code>name</code> parameter is null. + */ + public abstract void setFeature(String name, boolean value) + throws ParserConfigurationException; - /** - * <p>Set a feature for this <code>DocumentBuilderFactory</code> and <code>DocumentBuilder</code>s created by this factory.</p> - * - * <p> - * Feature names are fully qualified {@link java.net.URI}s. - * Implementations may define their own features. - * A {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the - * <code>DocumentBuilder</code>s it creates cannot support the feature. - * It is possible for a <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state. - * </p> - * - * <p> - * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. - * When the feature is:</p> - * <ul> - * <li> - * <code>true</code>: the implementation will limit XML processing to conform to implementation limits. - * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. - * If XML processing is limited for security reasons, it will be reported via a call to the registered - * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. - * See {@link DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}. - * </li> - * <li> - * <code>false</code>: the implementation will processing XML according to the XML specifications without - * regard to possible implementation limits. - * </li> - * </ul> - * - * @param name Feature name. - * @param value Is feature state <code>true</code> or <code>false</code>. - * - * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> or the <code>DocumentBuilder</code>s - * it creates cannot support this feature. - * @throws NullPointerException If the <code>name</code> parameter is null. - */ - public abstract void setFeature(String name, boolean value) - throws ParserConfigurationException; - - /** - * <p>Get the state of the named feature.</p> - * - * <p> - * Feature names are fully qualified {@link java.net.URI}s. - * Implementations may define their own features. - * An {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the - * <code>DocumentBuilder</code>s it creates cannot support the feature. - * It is possible for an <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state. - * </p> - * - * @param name Feature name. - * - * @return State of the named feature. - * - * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> - * or the <code>DocumentBuilder</code>s it creates cannot support this feature. - */ - public abstract boolean getFeature(String name) - throws ParserConfigurationException; - - + /** + * <p>Get the state of the named feature.</p> + * + * <p> + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * An {@link ParserConfigurationException} is thrown if this <code>DocumentBuilderFactory</code> or the + * <code>DocumentBuilder</code>s it creates cannot support the feature. + * It is possible for an <code>DocumentBuilderFactory</code> to expose a feature value but be unable to change its state. + * </p> + * + * @param name Feature name. + * + * @return State of the named feature. + * + * @throws ParserConfigurationException if this <code>DocumentBuilderFactory</code> + * or the <code>DocumentBuilder</code>s it creates cannot support this feature. + */ + public abstract boolean getFeature(String name) + throws ParserConfigurationException; + + /** <p>Get current state of canonicalization.</p> * * @return current state canonicalization control @@ -459,8 +460,8 @@ return canonicalState; } */ - - + + /** * Gets the {@link Schema} object specified through * the {@link #setSchema(Schema schema)} method. @@ -486,7 +487,7 @@ ); } - + /* <p>Set canonicalization control to <code>true</code> or * </code>false</code>.</p> * @@ -497,16 +498,16 @@ canonicalState = state; } */ - + /** * <p>Set the {@link Schema} to be used by parsers created * from this factory. - * + * * <p> * When a {@link Schema} is non-null, a parser will use a validator * created from it to validate documents before it passes information * down to the application. - * + * * <p>When errors are found by the validator, the parser is responsible * to report them to the user-specified {@link org.xml.sax.ErrorHandler} * (or if the error handler is not set, ignore them or throw them), just @@ -515,20 +516,20 @@ * is set, it must receive those errors, and if not, they must be * treated according to the implementation specific * default error handling rules. - * + * * <p> * A validator may modify the outcome of a parse (for example by * adding default values that were missing in documents), and a parser * is responsible to make sure that the application will receive - * modified DOM trees. - * + * modified DOM trees. + * * <p> - * Initialy, null is set as the {@link Schema}. - * + * Initialy, null is set as the {@link Schema}. + * * <p> * This processing will take effect even if * the {@link #isValidating()} method returns <code>false</code>. - * + * * <p>It is an error to use * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code> * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code> @@ -536,7 +537,7 @@ * Such configuration will cause a {@link ParserConfigurationException} * exception when the {@link #newDocumentBuilder()} is invoked.</p> * - * + * * <h4>Note for implmentors</h4> * * <p> @@ -563,18 +564,18 @@ + "\"" ); } - + - + /** * <p>Set state of XInclude processing.</p> - * + * * <p>If XInclude markup is found in the document instance, should it be * processed as specified in <a href="http://www.w3.org/TR/xinclude/"> * XML Inclusions (XInclude) Version 1.0</a>.</p> - * + * * <p>XInclude processing defaults to <code>false</code>.</p> - * + * * @param state Set XInclude processing to <code>true</code> or * <code>false</code> * @@ -584,18 +585,16 @@ * @since 1.5 */ public void setXIncludeAware(final boolean state) { - throw new UnsupportedOperationException( - "This parser does not support specification \"" - + this.getClass().getPackage().getSpecificationTitle() - + "\" version \"" - + this.getClass().getPackage().getSpecificationVersion() - + "\"" - ); + if (state) { + throw new UnsupportedOperationException(" setXIncludeAware " + + "is not supported on this JAXP" + + " implementation or earlier: " + this.getClass()); + } } /** * <p>Get state of XInclude processing.</p> - * + * * @return current state of XInclude processing * * @throws UnsupportedOperationException When implementation does not
--- a/sources/jaxp_src/src/javax/xml/parsers/FactoryConfigurationError.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/parsers/FactoryConfigurationError.java Wed Sep 28 17:10:18 2011 +0100 @@ -32,6 +32,7 @@ * or instantiated. * * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> + * @version $Revision: 1.5 $, $Date: 2010/02/03 07:34:04 $ */ public class FactoryConfigurationError extends Error { @@ -57,7 +58,7 @@ * * @param msg The error message for the exception. */ - + public FactoryConfigurationError(String msg) { super(msg); this.exception = null; @@ -71,7 +72,7 @@ * @param e The exception to be encapsulated in a * FactoryConfigurationError. */ - + public FactoryConfigurationError(Exception e) { super(e.toString()); this.exception = e; @@ -85,7 +86,7 @@ * FactoryConfigurationError * @param msg The detail message. */ - + public FactoryConfigurationError(Exception e, String msg) { super(msg); this.exception = e; @@ -95,31 +96,39 @@ /** * Return the message (if any) for this error . If there is no * message for the exception and there is an encapsulated - * exception then the message of that exception, if it exists will be + * exception then the message of that exception, if it exists will be * returned. Else the name of the encapsulated exception will be * returned. * * @return The error message. */ - + public String getMessage () { String message = super.getMessage (); - + if (message == null && exception != null) { return exception.getMessage(); } return message; } - + /** * Return the actual exception (if any) that caused this exception to * be raised. * * @return The encapsulated exception, or null if there is none. */ - + public Exception getException () { return exception; } + + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } }
--- a/sources/jaxp_src/src/javax/xml/parsers/FactoryFinder.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/parsers/FactoryFinder.java Wed Sep 28 17:10:18 2011 +0100 @@ -37,30 +37,30 @@ /** * <p>Implements pluggable Datatypes.</p> - * + * * <p>This class is duplicated for each JAXP subpackage so keep it in * sync. It is package private for secure class loading.</p> * * @author Santiago.PericasGeertsen@sun.com */ class FactoryFinder { - + /** * Internal debug flag. */ private static boolean debug = false; - + /** * Cache for properties in java.home/lib/jaxp.properties */ static Properties cacheProps = new Properties(); - + /** - * Flag indicating if properties from java.home/lib/jaxp.properties + * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ static boolean firstTime = true; - + /** * Security support class use to check access control before * getting certain system resources. @@ -75,29 +75,29 @@ String val = ss.getSystemProperty("jaxp.debug"); // Allow simply setting the prop to turn on debug debug = val != null && !"false".equals(val); - } + } catch (SecurityException se) { debug = false; } } - + private static void dPrint(String msg) { if (debug) { System.err.println("JAXP: " + msg); } } - + /** * Attempt to load a class using the class loader supplied. If that fails * and fall back is enabled, the current (i.e. bootstrap) class loader is - * tried. - * + * tried. + * * If the class loader supplied is <code>null</code>, first try using the * context class loader followed by the current (i.e. bootstrap) class - * loader. + * loader. */ static private Class getProviderClass(String className, ClassLoader cl, - boolean doFallback) throws ClassNotFoundException + boolean doFallback) throws ClassNotFoundException { try { if (cl == null) { @@ -108,7 +108,7 @@ else { return cl.loadClass(className); } - } + } else { return cl.loadClass(className); } @@ -117,15 +117,15 @@ if (doFallback) { // Use current class loader - should always be bootstrap CL return Class.forName(className, true, FactoryFinder.class.getClassLoader()); - } + } else { throw e1; } - } + } } - + /** - * Create an instance of a class. Delegates to method + * Create an instance of a class. Delegates to method * <code>getProviderClass()</code> in order to load the class. * * @param className Name of the concrete class corresponding to the @@ -136,30 +136,30 @@ * * @param doFallback True if the current ClassLoader should be tried as * a fallback if the class is not found using cl - */ + */ static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError { try { - Class providerClass = getProviderClass(className, cl, doFallback); + Class providerClass = getProviderClass(className, cl, doFallback); Object instance = providerClass.newInstance(); if (debug) { // Extra check to avoid computing cl strings dPrint("created new instance of " + providerClass + " using ClassLoader: " + cl); } return instance; - } + } catch (ClassNotFoundException x) { throw new ConfigurationError( "Provider " + className + " not found", x); - } + } catch (Exception x) { throw new ConfigurationError( "Provider " + className + " could not be instantiated: " + x, x); } } - + /** * Finds the implementation Class object in the specified order. Main * entry point. @@ -174,17 +174,17 @@ */ static Object find(String factoryId, String fallbackClassName) throws ConfigurationError - { + { dPrint("find factoryId =" + factoryId); - + // Use the system property first try { String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { + if (systemProp != null) { dPrint("found system property, value=" + systemProp); return newInstance(systemProp, null, true); } - } + } catch (SecurityException se) { if (debug) se.printStackTrace(); } @@ -206,13 +206,13 @@ } } } - factoryClassName = cacheProps.getProperty(factoryId); + factoryClassName = cacheProps.getProperty(factoryId); if (factoryClassName != null) { dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); return newInstance(factoryClassName, null, true); } - } + } catch (Exception ex) { if (debug) ex.printStackTrace(); } @@ -230,26 +230,26 @@ dPrint("loaded from fallback value: " + fallbackClassName); return newInstance(fallbackClassName, null, true); } - + /* * Try to find provider using Jar Service Provider Mechanism * * @return instance of provider class if found or null */ private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError + throws ConfigurationError { String serviceId = "META-INF/services/" + factoryId; InputStream is = null; - + // First try the Context ClassLoader ClassLoader cl = ss.getContextClassLoader(); if (cl != null) { is = ss.getResourceAsStream(cl, serviceId); - + // If no provider found then try the current ClassLoader if (is == null) { - cl = FactoryFinder.class.getClassLoader(); + cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); } } else { @@ -257,24 +257,24 @@ cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); } - + if (is == null) { // No provider found return null; } - + if (debug) { // Extra check to avoid computing cl strings dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); } - + BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); - } + } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is)); } - + String factoryClassName = null; try { // XXX Does not handle all possible input as specified by the @@ -285,24 +285,24 @@ // No provider found return null; } - + if (factoryClassName != null && !"".equals(factoryClassName)) { dPrint("found in resource, value=" + factoryClassName); - + // Note: here we do not want to fall back to the current // ClassLoader because we want to avoid the case where the // resource file was found using one ClassLoader and the // provider class was instantiated using a different one. return newInstance(factoryClassName, cl, false); } - + // No provider found return null; } - + static class ConfigurationError extends Error { private Exception exception; - + /** * Construct a new instance with the specified detail string and * exception. @@ -311,10 +311,17 @@ super(msg); this.exception = x; } - + Exception getException() { return exception; } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } } - + }
--- a/sources/jaxp_src/src/javax/xml/parsers/SAXParserFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/parsers/SAXParserFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -38,6 +38,7 @@ * @author <a href="mailto:Jeff.Suttor@Sun.com">Jeff Suttor</a> * @author <a href="mailto:Neeraj.Bajaj@sun.com">Neeraj Bajaj</a> * + * @version $Revision: 1.9 $, $Date: 2010/05/25 16:19:44 $ * */ public abstract class SAXParserFactory { @@ -48,17 +49,17 @@ * <p>Should Parsers be validating?</p> */ private boolean validating = false; - + /** * <p>Should Parsers be namespace aware?</p> */ private boolean namespaceAware = false; - + /** * <p>Protected constructor to force use of {@link #newInstance()}.</p> */ protected SAXParserFactory () { - + } /** @@ -78,7 +79,7 @@ * </code> format and contains the fully qualified name of the * implementation class with the key being the system property defined * above. - * + * * The jaxp.properties file is read only once by the JAXP implementation * and it's values are then cached for future use. If the file does not exist * when the first attempt is made to read from it, no further attempts are @@ -100,20 +101,20 @@ * Once an application has obtained a reference to a * <code>SAXParserFactory</code> it can use the factory to * configure and obtain parser instances. - * - * - * + * + * + * * <h2>Tip for Trouble-shooting</h2> * <p>Setting the <code>jaxp.debug</code> system property will cause * this method to print a lot of debug messages * to <code>System.err</code> about what it is doing and where it is looking at.</p> - * + * * <p> If you have problems loading {@link DocumentBuilder}s, try:</p> * <pre> * java -Djaxp.debug=1 YourProgram .... * </pre> - * - * + * + * * @return A new instance of a SAXParserFactory. * * @throws FactoryConfigurationError if the implementation is @@ -137,31 +138,31 @@ * <p>Obtain a new instance of a <code>SAXParserFactory</code> from class name. * This function is useful when there are multiple providers in the classpath. * It gives more control to the application as it can specify which provider - * should be loaded.</p> + * should be loaded.</p> * - * <p>Once an application has obtained a reference to a <code>SAXParserFactory</code> + * <p>Once an application has obtained a reference to a <code>SAXParserFactory</code> * it can use the factory to configure and obtain parser instances.</p> - * - * + * + * * <h2>Tip for Trouble-shooting</h2> * <p>Setting the <code>jaxp.debug</code> system property will cause * this method to print a lot of debug messages * to <code>System.err</code> about what it is doing and where it is looking at.</p> - * + * * <p> If you have problems, try:</p> * <pre> * java -Djaxp.debug=1 YourProgram .... * </pre> - * + * * @param factoryClassName fully qualified factory class name that provides implementation of <code>javax.xml.parsers.SAXParserFactory</code>. * - * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> + * @param classLoader <code>ClassLoader</code> used to load the factory class. If <code>null</code> * current <code>Thread</code>'s context classLoader is used to load the factory class. * * @return New instance of a <code>SAXParserFactory</code> * - * @throws FactoryConfigurationError if <code>factoryClassName</code> is <code>null</code>, or - * the factory class cannot be loaded, instantiated. + * @throws FactoryConfigurationError if <code>factoryClassName</code> is <code>null</code>, or + * the factory class cannot be loaded, instantiated. * * @see #newInstance() * @@ -174,9 +175,9 @@ } catch (FactoryFinder.ConfigurationError e) { throw new FactoryConfigurationError(e.getException(), e.getMessage()); - } + } } - + /** * <p>Creates a new instance of a SAXParser using the currently * configured factory parameters.</p> @@ -187,11 +188,11 @@ * be created which satisfies the requested configuration. * @throws SAXException for SAX errors. */ - + public abstract SAXParser newSAXParser() throws ParserConfigurationException, SAXException; - + /** * Specifies that the parser produced by this code will * provide support for XML namespaces. By default the value of this is set @@ -200,7 +201,7 @@ * @param awareness true if the parser produced by this code will * provide support for XML namespaces; false otherwise. */ - + public void setNamespaceAware(boolean awareness) { this.namespaceAware = awareness; } @@ -209,7 +210,7 @@ * Specifies that the parser produced by this code will * validate documents as they are parsed. By default the value of this is * set to <code>false</code>. - * + * * <p> * Note that "the validation" here means * <a href="http://www.w3.org/TR/REC-xml#proc-types">a validating @@ -217,7 +218,7 @@ * In other words, it essentially just controls the DTD validation. * (except the legacy two properties defined in JAXP 1.2.) * </p> - * + * * <p> * To use modern schema languages such as W3C XML Schema or * RELAX NG instead of DTD, you can configure your parser to be @@ -229,7 +230,7 @@ * @param validating true if the parser produced by this code will * validate documents as they are parsed; false otherwise. */ - + public void setValidating(boolean validating) { this.validating = validating; } @@ -241,7 +242,7 @@ * @return true if the factory is configured to produce * parsers which are namespace aware; false otherwise. */ - + public boolean isNamespaceAware() { return namespaceAware; } @@ -253,7 +254,7 @@ * @return true if the factory is configured to produce parsers which validate * the XML content during parse; false otherwise. */ - + public boolean isValidating() { return validating; } @@ -265,25 +266,25 @@ * A list of the core features and properties can be found at * <a href="http://www.saxproject.org/">http://www.saxproject.org/</a></p> * - * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. - * When the feature is</p> - * <ul> - * <li> - * <code>true</code>: the implementation will limit XML processing to conform to implementation limits. - * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. - * If XML processing is limited for security reasons, it will be reported via a call to the registered - * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. - * See {@link SAXParser} <code>parse</code> methods for handler specification. - * </li> - * <li> - * When the feature is <code>false</code>, the implementation will processing XML according to the XML specifications without - * regard to possible implementation limits. - * </li> - * </ul> - * + * <p>All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is</p> + * <ul> + * <li> + * <code>true</code>: the implementation will limit XML processing to conform to implementation limits. + * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. + * If XML processing is limited for security reasons, it will be reported via a call to the registered + * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. + * See {@link SAXParser} <code>parse</code> methods for handler specification. + * </li> + * <li> + * When the feature is <code>false</code>, the implementation will processing XML according to the XML specifications without + * regard to possible implementation limits. + * </li> + * </ul> + * * @param name The name of the feature to be set. * @param value The value of the feature to be set. - * + * * @throws ParserConfigurationException if a parser cannot * be created which satisfies the requested configuration. * @throws SAXNotRecognizedException When the underlying XMLReader does @@ -305,7 +306,7 @@ * implementation of org.xml.sax.XMLReader.</p> * * @param name The name of the property to be retrieved. - * + * * @return Value of the requested property. * * @throws ParserConfigurationException if a parser cannot be created which satisfies the requested configuration. @@ -319,7 +320,7 @@ SAXNotSupportedException; - + /* <p>Get current state of canonicalization.</p> * * @return current state canonicalization control @@ -329,21 +330,21 @@ return canonicalState; } */ - + /** * Gets the {@link Schema} object specified through * the {@link #setSchema(Schema schema)} method. - * - * + * + * * @throws UnsupportedOperationException When implementation does not * override this method - * + * * @return * the {@link Schema} object that was last set through * the {@link #setSchema(Schema)} method, or null * if the method was not invoked since a {@link SAXParserFactory} * is created. - * + * * @since 1.5 */ public Schema getSchema() { @@ -355,7 +356,7 @@ + "\"" ); } - + /** <p>Set canonicalization control to <code>true</code> or * </code>false</code>.</p> * @@ -366,39 +367,39 @@ canonicalState = state; } */ - + /** * <p>Set the {@link Schema} to be used by parsers created * from this factory.</p> - * + * * <p>When a {@link Schema} is non-null, a parser will use a validator * created from it to validate documents before it passes information * down to the application.</p> - * + * * <p>When warnings/errors/fatal errors are found by the validator, the parser must - * handle them as if those errors were found by the parser itself. + * handle them as if those errors were found by the parser itself. * In other words, if the user-specified {@link org.xml.sax.ErrorHandler} * is set, it must receive those errors, and if not, they must be * treated according to the implementation specific * default error handling rules. - * + * * <p>A validator may modify the SAX event stream (for example by * adding default values that were missing in documents), and a parser * is responsible to make sure that the application will receive - * those modified event stream.</p> - * - * <p>Initialy, <code>null</code> is set as the {@link Schema}.</p> - * + * those modified event stream.</p> + * + * <p>Initialy, <code>null</code> is set as the {@link Schema}.</p> + * * <p>This processing will take effect even if * the {@link #isValidating()} method returns <code>false</code>. - * + * * <p>It is an error to use * the <code>http://java.sun.com/xml/jaxp/properties/schemaSource</code> * property and/or the <code>http://java.sun.com/xml/jaxp/properties/schemaLanguage</code> * property in conjunction with a non-null {@link Schema} object. * Such configuration will cause a {@link SAXException} * exception when those properties are set on a {@link SAXParser}.</p> - * + * * <h4>Note for implmentors</h4> * <p> * A parser must be able to work with any {@link Schema} @@ -406,12 +407,12 @@ * to use implementation-specific custom mechanisms * as long as they yield the result described in the specification. * </p> - * + * * @param schema <code>Schema</code> to use, <code>null</code> to remove a schema. - * + * * @throws UnsupportedOperationException When implementation does not * override this method - * + * * @since 1.5 */ public void setSchema(Schema schema) { @@ -426,39 +427,37 @@ /** * <p>Set state of XInclude processing.</p> - * + * * <p>If XInclude markup is found in the document instance, should it be * processed as specified in <a href="http://www.w3.org/TR/xinclude/"> * XML Inclusions (XInclude) Version 1.0</a>.</p> - * + * * <p>XInclude processing defaults to <code>false</code>.</p> - * + * * @param state Set XInclude processing to <code>true</code> or * <code>false</code> - * + * * @throws UnsupportedOperationException When implementation does not * override this method - * + * * @since 1.5 */ public void setXIncludeAware(final boolean state) { - throw new UnsupportedOperationException( - "This parser does not support specification \"" - + this.getClass().getPackage().getSpecificationTitle() - + "\" version \"" - + this.getClass().getPackage().getSpecificationVersion() - + "\"" - ); + if (state) { + throw new UnsupportedOperationException(" setXIncludeAware " + + "is not supported on this JAXP" + + " implementation or earlier: " + this.getClass()); + } } /** * <p>Get state of XInclude processing.</p> - * + * * @return current state of XInclude processing - * + * * @throws UnsupportedOperationException When implementation does not * override this method - * + * * @since 1.5 */ public boolean isXIncludeAware() { @@ -471,3 +470,4 @@ ); } } +
--- a/sources/jaxp_src/src/javax/xml/stream/FactoryConfigurationError.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/stream/FactoryConfigurationError.java Wed Sep 28 17:10:18 2011 +0100 @@ -94,7 +94,13 @@ public Exception getException() { return nested; } - + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return nested; + } /** * Report the message associated with this error
--- a/sources/jaxp_src/src/javax/xml/stream/FactoryFinder.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/stream/FactoryFinder.java Wed Sep 28 17:10:18 2011 +0100 @@ -160,8 +160,8 @@ } /** - * Finds the implementation Class object in the specified order. Main - * entry point. + * Finds the implementation Class object in the specified order. + * * @return Class object of factory, never null * * @param factoryId Name of the factory to find, same as @@ -174,6 +174,28 @@ static Object find(String factoryId, String fallbackClassName) throws ConfigurationError { + return find(factoryId, null, fallbackClassName); + } + + /** + * Finds the implementation Class object in the specified order. Main + * entry point. + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * + * @param cl ClassLoader to be used to load the class, null means to use + * the bootstrap ClassLoader + * + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * Package private so this code can be shared. + */ + static Object find(String factoryId, ClassLoader cl, String fallbackClassName) + throws ConfigurationError + { dPrint("find factoryId =" + factoryId); // Use the system property first @@ -238,7 +260,7 @@ } dPrint("loaded from fallback value: " + fallbackClassName); - return newInstance(fallbackClassName, null, true); + return newInstance(fallbackClassName, cl, true); } /* @@ -325,6 +347,13 @@ Exception getException() { return exception; } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } } }
--- a/sources/jaxp_src/src/javax/xml/stream/XMLInputFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/stream/XMLInputFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -139,6 +139,8 @@ public static final String ALLOCATOR= "javax.xml.stream.allocator"; + static final String DEFAULIMPL = "com.sun.xml.internal.stream.XMLInputFactoryImpl"; + protected XMLInputFactory(){} /** @@ -150,7 +152,7 @@ { return (XMLInputFactory) FactoryFinder.find( "javax.xml.stream.XMLInputFactory", - "com.sun.xml.internal.stream.XMLInputFactoryImpl"); + DEFAULIMPL); } /** @@ -183,7 +185,7 @@ { return (XMLInputFactory) FactoryFinder.find( "javax.xml.stream.XMLInputFactory", - "com.sun.xml.internal.stream.XMLInputFactoryImpl"); + DEFAULIMPL); } /** @@ -206,7 +208,7 @@ throws FactoryConfigurationError { try { //do not fallback if given classloader can't find the class, throw exception - return (XMLInputFactory) FactoryFinder.newInstance(factoryId, classLoader, false); + return (XMLInputFactory) FactoryFinder.find(factoryId, classLoader, null); } catch (FactoryFinder.ConfigurationError e) { throw new FactoryConfigurationError(e.getException(), e.getMessage()); @@ -233,7 +235,7 @@ throws FactoryConfigurationError { try { //do not fallback if given classloader can't find the class, throw exception - return (XMLInputFactory) FactoryFinder.newInstance(factoryId, classLoader, false); + return (XMLInputFactory) FactoryFinder.find(factoryId, classLoader, null); } catch (FactoryFinder.ConfigurationError e) { throw new FactoryConfigurationError(e.getException(), e.getMessage());
--- a/sources/jaxp_src/src/javax/xml/stream/XMLOutputFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/stream/XMLOutputFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -115,6 +115,8 @@ public static final String IS_REPAIRING_NAMESPACES= "javax.xml.stream.isRepairingNamespaces"; + static final String DEFAULIMPL = "com.sun.xml.internal.stream.XMLOutputFactoryImpl"; + protected XMLOutputFactory(){} /** @@ -125,7 +127,7 @@ throws FactoryConfigurationError { return (XMLOutputFactory) FactoryFinder.find("javax.xml.stream.XMLOutputFactory", - "com.sun.xml.internal.stream.XMLOutputFactoryImpl"); + DEFAULIMPL); } /** @@ -157,7 +159,7 @@ throws FactoryConfigurationError { return (XMLOutputFactory) FactoryFinder.find("javax.xml.stream.XMLOutputFactory", - "com.sun.xml.internal.stream.XMLOutputFactoryImpl"); + DEFAULIMPL); } /** @@ -179,7 +181,7 @@ throws FactoryConfigurationError { try { //do not fallback if given classloader can't find the class, throw exception - return (XMLInputFactory) FactoryFinder.newInstance(factoryId, classLoader, false); + return (XMLInputFactory) FactoryFinder.find(factoryId, classLoader, null); } catch (FactoryFinder.ConfigurationError e) { throw new FactoryConfigurationError(e.getException(), e.getMessage()); @@ -208,7 +210,7 @@ throws FactoryConfigurationError { try { //do not fallback if given classloader can't find the class, throw exception - return (XMLOutputFactory) FactoryFinder.newInstance(factoryId, classLoader, false); + return (XMLOutputFactory) FactoryFinder.find(factoryId, classLoader, null); } catch (FactoryFinder.ConfigurationError e) { throw new FactoryConfigurationError(e.getException(), e.getMessage());
--- a/sources/jaxp_src/src/javax/xml/transform/FactoryFinder.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/transform/FactoryFinder.java Wed Sep 28 17:10:18 2011 +0100 @@ -37,30 +37,30 @@ /** * <p>Implements pluggable Datatypes.</p> - * + * * <p>This class is duplicated for each JAXP subpackage so keep it in * sync. It is package private for secure class loading.</p> * * @author Santiago.PericasGeertsen@sun.com */ class FactoryFinder { - + /** * Internal debug flag. */ private static boolean debug = false; - + /** * Cache for properties in java.home/lib/jaxp.properties */ static Properties cacheProps = new Properties(); - + /** - * Flag indicating if properties from java.home/lib/jaxp.properties + * Flag indicating if properties from java.home/lib/jaxp.properties * have been cached. */ static boolean firstTime = true; - + /** * Security support class use to check access control before * getting certain system resources. @@ -75,29 +75,29 @@ String val = ss.getSystemProperty("jaxp.debug"); // Allow simply setting the prop to turn on debug debug = val != null && !"false".equals(val); - } + } catch (SecurityException se) { debug = false; } } - + private static void dPrint(String msg) { if (debug) { System.err.println("JAXP: " + msg); } } - + /** * Attempt to load a class using the class loader supplied. If that fails * and fall back is enabled, the current (i.e. bootstrap) class loader is - * tried. - * + * tried. + * * If the class loader supplied is <code>null</code>, first try using the * context class loader followed by the current (i.e. bootstrap) class - * loader. + * loader. */ static private Class getProviderClass(String className, ClassLoader cl, - boolean doFallback) throws ClassNotFoundException + boolean doFallback) throws ClassNotFoundException { try { if (cl == null) { @@ -108,7 +108,7 @@ else { return cl.loadClass(className); } - } + } else { return cl.loadClass(className); } @@ -117,15 +117,15 @@ if (doFallback) { // Use current class loader - should always be bootstrap CL return Class.forName(className, true, FactoryFinder.class.getClassLoader()); - } + } else { throw e1; } - } + } } - + /** - * Create an instance of a class. Delegates to method + * Create an instance of a class. Delegates to method * <code>getProviderClass()</code> in order to load the class. * * @param className Name of the concrete class corresponding to the @@ -136,30 +136,30 @@ * * @param doFallback True if the current ClassLoader should be tried as * a fallback if the class is not found using cl - */ + */ static Object newInstance(String className, ClassLoader cl, boolean doFallback) throws ConfigurationError { try { - Class providerClass = getProviderClass(className, cl, doFallback); + Class providerClass = getProviderClass(className, cl, doFallback); Object instance = providerClass.newInstance(); if (debug) { // Extra check to avoid computing cl strings dPrint("created new instance of " + providerClass + " using ClassLoader: " + cl); } return instance; - } + } catch (ClassNotFoundException x) { throw new ConfigurationError( "Provider " + className + " not found", x); - } + } catch (Exception x) { throw new ConfigurationError( "Provider " + className + " could not be instantiated: " + x, x); } } - + /** * Finds the implementation Class object in the specified order. Main * entry point. @@ -174,17 +174,17 @@ */ static Object find(String factoryId, String fallbackClassName) throws ConfigurationError - { + { dPrint("find factoryId =" + factoryId); - + // Use the system property first try { String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { + if (systemProp != null) { dPrint("found system property, value=" + systemProp); return newInstance(systemProp, null, true); } - } + } catch (SecurityException se) { if (debug) se.printStackTrace(); } @@ -206,13 +206,13 @@ } } } - factoryClassName = cacheProps.getProperty(factoryId); + factoryClassName = cacheProps.getProperty(factoryId); if (factoryClassName != null) { dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); return newInstance(factoryClassName, null, true); } - } + } catch (Exception ex) { if (debug) ex.printStackTrace(); } @@ -230,26 +230,26 @@ dPrint("loaded from fallback value: " + fallbackClassName); return newInstance(fallbackClassName, null, true); } - + /* * Try to find provider using Jar Service Provider Mechanism * * @return instance of provider class if found or null */ private static Object findJarServiceProvider(String factoryId) - throws ConfigurationError + throws ConfigurationError { String serviceId = "META-INF/services/" + factoryId; InputStream is = null; - + // First try the Context ClassLoader ClassLoader cl = ss.getContextClassLoader(); if (cl != null) { is = ss.getResourceAsStream(cl, serviceId); - + // If no provider found then try the current ClassLoader if (is == null) { - cl = FactoryFinder.class.getClassLoader(); + cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); } } else { @@ -257,24 +257,24 @@ cl = FactoryFinder.class.getClassLoader(); is = ss.getResourceAsStream(cl, serviceId); } - + if (is == null) { // No provider found return null; } - + if (debug) { // Extra check to avoid computing cl strings dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); } - + BufferedReader rd; try { rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); - } + } catch (java.io.UnsupportedEncodingException e) { rd = new BufferedReader(new InputStreamReader(is)); } - + String factoryClassName = null; try { // XXX Does not handle all possible input as specified by the @@ -285,24 +285,24 @@ // No provider found return null; } - + if (factoryClassName != null && !"".equals(factoryClassName)) { dPrint("found in resource, value=" + factoryClassName); - + // Note: here we do not want to fall back to the current // ClassLoader because we want to avoid the case where the // resource file was found using one ClassLoader and the // provider class was instantiated using a different one. return newInstance(factoryClassName, cl, false); } - + // No provider found return null; } - + static class ConfigurationError extends Error { private Exception exception; - + /** * Construct a new instance with the specified detail string and * exception. @@ -311,10 +311,17 @@ super(msg); this.exception = x; } - + Exception getException() { return exception; } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } } - + }
--- a/sources/jaxp_src/src/javax/xml/transform/TransformerFactoryConfigurationError.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/javax/xml/transform/TransformerFactoryConfigurationError.java Wed Sep 28 17:10:18 2011 +0100 @@ -119,4 +119,11 @@ public Exception getException() { return exception; } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } }
--- a/sources/jaxp_src/src/org/xml/sax/helpers/XMLReaderFactory.java Wed Sep 28 17:02:12 2011 +0100 +++ b/sources/jaxp_src/src/org/xml/sax/helpers/XMLReaderFactory.java Wed Sep 28 17:10:18 2011 +0100 @@ -34,6 +34,8 @@ import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; +import java.security.AccessController; +import java.security.PrivilegedAction; import org.xml.sax.XMLReader; import org.xml.sax.SAXException; @@ -69,6 +71,7 @@ * * @since SAX 2.0 * @author David Megginson, David Brownell + * @version 2.0.1 (sax2r2) */ final public class XMLReaderFactory { @@ -83,6 +86,8 @@ private static final String property = "org.xml.sax.driver"; + private static String _clsFromJar = null; + private static boolean _jarread = false; /** * Attempt to create an XMLReader from system defaults. * In environments which can support it, the name of the XMLReader @@ -126,60 +131,71 @@ * @see #createXMLReader(java.lang.String) */ public static XMLReader createXMLReader () - throws SAXException + throws SAXException { - String className = null; - ClassLoader loader = NewInstance.getClassLoader (); - - // 1. try the JVM-instance-wide system property - try { className = System.getProperty (property); } - catch (RuntimeException e) { /* normally fails for applets */ } - - // 2. if that fails, try META-INF/services/ - if (className == null) { - try { - String service = "META-INF/services/" + property; - InputStream in; - BufferedReader reader; + String className = null; + ClassLoader loader = NewInstance.getClassLoader (); + + // 1. try the JVM-instance-wide system property + try { className = System.getProperty (property); } + catch (RuntimeException e) { /* normally fails for applets */ } - if (loader == null) - in = ClassLoader.getSystemResourceAsStream (service); - else - in = loader.getResourceAsStream (service); + // 2. if that fails, try META-INF/services/ + if (className == null) { + if (!_jarread) { + final ClassLoader loader1 = loader; + _jarread = true; + _clsFromJar = (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + String clsName = null; + try { + String service = "META-INF/services/" + property; + InputStream in; + BufferedReader reader; + if (loader1 == null) + in = ClassLoader.getSystemResourceAsStream (service); + else + in = loader1.getResourceAsStream (service); - if (in != null) { - reader = new BufferedReader ( - new InputStreamReader (in, "UTF8")); - className = reader.readLine (); - in.close (); - } - } catch (Exception e) { + if (in != null) { + reader = new BufferedReader ( + new InputStreamReader (in, "UTF8")); + clsName = reader.readLine (); + in.close (); + } + } catch (Exception e) { + } + return clsName; + } + }); } - } + className = _clsFromJar; + } - // 3. Distro-specific fallback - if (className == null) { + // 3. Distro-specific fallback + if (className == null) { // BEGIN DISTRIBUTION-SPECIFIC - // EXAMPLE: - // className = "com.example.sax.XmlReader"; - // or a $JAVA_HOME/jre/lib/*properties setting... + // EXAMPLE: + // className = "com.example.sax.XmlReader"; + // or a $JAVA_HOME/jre/lib/*properties setting... className = "com.sun.org.apache.xerces.internal.parsers.SAXParser"; // END DISTRIBUTION-SPECIFIC - } - - // do we know the XMLReader implementation class yet? - if (className != null) - return loadClass (loader, className); + } + + // do we know the XMLReader implementation class yet? + if (className != null) + return loadClass (loader, className); - // 4. panic -- adapt any SAX1 parser - try { - return new ParserAdapter (ParserFactory.makeParser ()); - } catch (Exception e) { - throw new SAXException ("Can't create default XMLReader; " - + "is system property org.xml.sax.driver set?"); - } + // 4. panic -- adapt any SAX1 parser + try { + return new ParserAdapter (ParserFactory.makeParser ()); + } catch (Exception e) { + throw new SAXException ("Can't create default XMLReader; " + + "is system property org.xml.sax.driver set?"); + } } @@ -199,29 +215,29 @@ * @see #createXMLReader() */ public static XMLReader createXMLReader (String className) - throws SAXException + throws SAXException { - return loadClass (NewInstance.getClassLoader (), className); + return loadClass (NewInstance.getClassLoader (), className); } private static XMLReader loadClass (ClassLoader loader, String className) throws SAXException { - try { - return (XMLReader) NewInstance.newInstance (loader, className); - } catch (ClassNotFoundException e1) { - throw new SAXException("SAX2 driver class " + className + - " not found", e1); - } catch (IllegalAccessException e2) { - throw new SAXException("SAX2 driver class " + className + - " found but cannot be loaded", e2); - } catch (InstantiationException e3) { - throw new SAXException("SAX2 driver class " + className + - " loaded but cannot be instantiated (no empty public constructor?)", - e3); - } catch (ClassCastException e4) { - throw new SAXException("SAX2 driver class " + className + - " does not implement XMLReader", e4); - } + try { + return (XMLReader) NewInstance.newInstance (loader, className); + } catch (ClassNotFoundException e1) { + throw new SAXException("SAX2 driver class " + className + + " not found", e1); + } catch (IllegalAccessException e2) { + throw new SAXException("SAX2 driver class " + className + + " found but cannot be loaded", e2); + } catch (InstantiationException e3) { + throw new SAXException("SAX2 driver class " + className + + " loaded but cannot be instantiated (no empty public constructor?)", + e3); + } catch (ClassCastException e4) { + throw new SAXException("SAX2 driver class " + className + + " does not implement XMLReader", e4); + } } }