Mercurial > hg > release > icedtea7-forest-2.5 > jaxp
changeset 853:78bd066359f2
Merge
author | goetz |
---|---|
date | Tue, 17 Sep 2013 16:33:44 +0200 |
parents | e9b2b5130b07 (current diff) c500d4ec41ff (diff) |
children | ef6ba85bd2a8 |
files | .hgtags src/com/sun/org/apache/xerces/internal/xinclude/ObjectFactory.java src/com/sun/org/apache/xml/internal/serialize/ObjectFactory.java |
diffstat | 68 files changed, 2766 insertions(+), 2527 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgtags Mon Jun 03 15:27:00 2013 +0200 +++ b/.hgtags Tue Sep 17 16:33:44 2013 +0200 @@ -279,6 +279,7 @@ 7863a60ae4b4a0c7d762a95e77e589fafa4e50ae jdk7u17-b02 a5e6594fc1ae20101b5d69632f65078d7a99b76d jdk7u17-b30 8fb34202383ece5386acecc3a6c1dac68dccbf05 jdk7u17-b31 +f7d8d2c003a10c38beac2f57e77d19303c71d6fc jdk7u17-b32 0a6a09e5174a4c15632ff7e06d6b215164e3fa15 jdk7u21-b01 99ed1a3d29509fee659aabec4810c896b7234d80 jdk7u21-b02 38d4d23d167c5a623e6d771a15b1fe2ee771ce38 jdk7u21-b03 @@ -291,7 +292,30 @@ bf2d62ea518d5e4130e442e07705e7a50b821ad9 jdk7u21-b10 3e0e331bdfb8f3adfd0cc78118e0ac588e73a2b5 jdk7u21-b11 980fe893d8fd86d8aee14771167b6e0ac75fa208 jdk7u21-b30 +a320a590b4cac6eeff53829bde520ef46880b006 jdk7u21-b50 a320a590b4cac6eeff53829bde520ef46880b006 jdk7u21-b12 +19b243d00f7740072d051d3fb531f01083cbe999 jdk7u21-b31 +5704dc942da676677a820d16c9a08fc6cad5b3bb jdk7u25-b01 +f9c1fe7cd1194e785807f07005369631b35b28d8 jdk7u25-b02 +fe858d7d6a13829d0ef0a1f762bd0e769cd24fa1 jdk7u25-b03 +1a2822a1d6a40c6e469f4089f39e41f642a87843 jdk7u25-b04 +e927605d1678c5d94adfc44183160d6c4df05b8b jdk7u25-b05 +8dfb4db227e7795120c072781927ba7d35186559 jdk7u25-b06 +ad2732999848b6e57f564d85e18ddebab6315ac2 jdk7u25-b07 +df9def2569705ebe316b50e673f847d2ec47eccf jdk7u25-b08 +5952538d55e624132f97400332a50b71880c874c jdk7u25-b09 +aa00dd983dd0f5b07269d0648a0325e9b3e0d957 jdk7u25-b10 +0fb6d76bcd2e8d54d0a69e1c3d2a85d84b3e17a4 jdk7u25-b11 +5e87aee78c91efa65bd5aeb37bcc1c1c637a7f0c jdk7u25-b12 +83b80c094befd08cbac4247d9b8f12c6a039f23f jdk7u25-b13 +68cc0d2a49f09b5c611b2775f2e66de1022bdedc jdk7u25-b14 +503f75b55b34ae22f43b2992b1e56c96e35a60de jdk7u25-b15 +35710c8bd73dbfdd4805e8b3c506f500daf553c7 jdk7u25-b31 +c02dbd8fd8ca142e3987537f7ac43da361fcf9d4 jdk7u25-b33 +ebe5d88948e9f2fd707c808eceb9343f4f32e122 jdk7u25-b34 +8c35f2344beeb42e85d718e95813e6fdc2f0a605 jdk7u25-b30 +9cebeb3118aca6e356f80a37ac38088ddcc8fb73 jdk7u25-b16 +0d4cfe518086198516e6729fc28b161f66524a66 jdk7u25-b32 7b47e1a26f7cbb8d8d22ea165f2d7fbbbd354c77 jdk7u14-b16 77ac1ef42b2fd47cc87b9800f63efdd4cf2fa05d jdk7u14-b17 d47975f80a24b55410fa2e2c5f50f3405d83fe73 jdk7u14-b18 @@ -303,3 +327,23 @@ d1c6afebdfe28eb07eb2d03a6911a0f33b619165 jdk7u14-b22 0e4c549d3635122145ac88bad7b98716976ca49e jdk7u40-b23 d17acb2ee133811baa8eae3436a8c191fc433da1 jdk7u40-b24 +52bcce690998b4ad91abddae118847f4358c6110 jdk7u40-b25 +cd764ada36b50e2096ba35b4c27ca8f83b3db964 jdk7u40-b26 +7626b3fbc822fd4efd5ba3b5fc18f2fef5749597 jdk7u40-b27 +9186b6efd2b2eafa7fee5be1b043f59f25db12a6 jdk7u40-b28 +740942c76fb668a04bf89feccf069f6958651d54 jdk7u40-b29 +09b080236bc1a1a68f8b411196cbfa52475c0755 jdk7u40-b30 +5b31380e2e0b6f8386dcf0ca122461154f2d2704 jdk7u40-b31 +75bb397c4ae26c384e1fcb75bbf4b70479f2c5f7 jdk7u40-b32 +ce771024e07d2bb6521735a14ce68745a2376bd8 jdk7u40-b33 +23ba797b9e78231806d837f7fb4f9feef6dcd61a jdk7u40-b34 +4056df34b559b904edc9f94a323769f19cf8f426 jdk7u40-b35 +07024f18376ce9597ec8679ebcb9f2efdc5afab0 jdk7u40-b36 +f40f45bd95d4140f691c03132f2ab2c8a0233a8f jdk7u40-b37 +680bf140cdd58e7878318ecafc41c9db47ebfacd jdk7u40-b38 +322af0a5cdce6cad8421a73c1b9af345361dfba0 jdk7u40-b39 +6ea57bdf603007be4d25568f7759ca0381aa8382 jdk7u40-b40 +7255fb6c9060b0626aeedb1066e73c4bb46b1a7c jdk7u40-b41 +66363323f14d85d4ab28e883a3323b9d72dea5fd jdk7u40-b42 +c0bd71414ea513f54f23965936a837fca093ac91 jdk7u40-b43 +91bc4534851265291bb3b16452a0968d6909979f jdk7u40-b60
--- a/THIRD_PARTY_README Mon Jun 03 15:27:00 2013 +0200 +++ b/THIRD_PARTY_README Tue Sep 17 16:33:44 2013 +0200 @@ -1912,6 +1912,35 @@ ------------------------------------------------------------------------------- +%% This notice is provided with respect to Sparkle v.1.5, +which is included with JRE 7 on Mac OS X. + +--- begin of LICENSE --- + +Copyright (c) 2012 Sparkle.org and Andy Matuschak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- end of LICENSE --- + +------------------------------------------------------------------------------- + %% Portions licensed from Taligent, Inc. ------------------------------------------------------------------------------- @@ -3169,12 +3198,12 @@ %% This notice is provided with respect to the following which is included with JRE 7, JDK 7, and OpenJDK 7, except where noted: - Apache Derby 10.8.1.2 [included with JDK 7 only] + Apache Derby 10.8.3.0 [included with JDK 7 only] Apache Jakarta BCEL 5.2 Apache Jakarta Regexp 1.4 Apache Santuario XMLSec-Java 1.4.2 Apache Xalan-Java 2.7.1 - Apache Xerces2 Java 2.10.0 + Apache Xerces2 Java 2.11.0 Apache XML Resolver 1.1
--- a/src/com/sun/org/apache/bcel/internal/generic/BasicType.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/BasicType.java Tue Sep 17 16:33:44 2013 +0200 @@ -97,8 +97,14 @@ /** @return true if both type objects refer to the same type */ + @Override public boolean equals(Object type) { return (type instanceof BasicType)? ((BasicType)type).type == this.type : false; } + + @Override + public int hashCode() { + return type; + } }
--- a/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/BranchInstruction.java Tue Sep 17 16:33:44 2013 +0200 @@ -93,6 +93,7 @@ * Dump instruction as byte code to stream out. * @param out Output stream */ + @Override public void dump(DataOutputStream out) throws IOException { out.writeByte(opcode); @@ -153,6 +154,7 @@ * @param verbose long/short format switch * @return mnemonic for instruction */ + @Override public String toString(boolean verbose) { String s = super.toString(verbose); String t = "null"; @@ -184,6 +186,7 @@ * @param wide wide prefix? * @see InstructionList */ + @Override protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException { length = 3; @@ -204,26 +207,41 @@ * Set branch target * @param target branch target */ - public void setTarget(InstructionHandle target) { - notifyTarget(this.target, target, this); + public final void setTarget(InstructionHandle target) { + notifyTargetChanging(this.target, this); this.target = target; + notifyTargetChanged(this.target, this); } /** - * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen. + * Must be called before the target is actually changed in the + * InstructionTargeter. */ - static final void notifyTarget(InstructionHandle old_ih, InstructionHandle new_ih, + static void notifyTargetChanging(InstructionHandle old_ih, InstructionTargeter t) { - if(old_ih != null) + if(old_ih != null) { old_ih.removeTargeter(t); - if(new_ih != null) + } + } + + /** + * Used by BranchInstruction, LocalVariableGen, CodeExceptionGen. + * Must be called after the target is actually changed in the + * InstructionTargeter. + */ + static void notifyTargetChanged(InstructionHandle new_ih, + InstructionTargeter t) { + if(new_ih != null) { new_ih.addTargeter(t); + } } /** * @param old_ih old target * @param new_ih new target */ + @Override public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { if(target == old_ih) setTarget(new_ih); @@ -234,6 +252,7 @@ /** * @return true, if ih is target of this instruction */ + @Override public boolean containsTarget(InstructionHandle ih) { return (target == ih); } @@ -241,6 +260,7 @@ /** * Inform target that it's not targeted anymore. */ + @Override void dispose() { setTarget(null); index=-1;
--- a/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/CodeExceptionGen.java Tue Sep 17 16:33:44 2013 +0200 @@ -58,7 +58,6 @@ * <http://www.apache.org/>. */ -import com.sun.org.apache.bcel.internal.Constants; import com.sun.org.apache.bcel.internal.classfile.*; /** @@ -118,31 +117,35 @@ /* Set start of handler * @param start_pc Start of handled region (inclusive) */ - public void setStartPC(InstructionHandle start_pc) { - BranchInstruction.notifyTarget(this.start_pc, start_pc, this); + public final void setStartPC(InstructionHandle start_pc) { + BranchInstruction.notifyTargetChanging(this.start_pc, this); this.start_pc = start_pc; + BranchInstruction.notifyTargetChanged(this.start_pc, this); } /* Set end of handler * @param end_pc End of handled region (inclusive) */ - public void setEndPC(InstructionHandle end_pc) { - BranchInstruction.notifyTarget(this.end_pc, end_pc, this); + public final void setEndPC(InstructionHandle end_pc) { + BranchInstruction.notifyTargetChanging(this.end_pc, this); this.end_pc = end_pc; + BranchInstruction.notifyTargetChanged(this.end_pc, this); } /* Set handler code * @param handler_pc Start of handler */ - public void setHandlerPC(InstructionHandle handler_pc) { - BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this); + public final void setHandlerPC(InstructionHandle handler_pc) { + BranchInstruction.notifyTargetChanging(this.handler_pc, this); this.handler_pc = handler_pc; + BranchInstruction.notifyTargetChanged(this.handler_pc, this); } /** * @param old_ih old target, either start or end * @param new_ih new target */ + @Override public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { boolean targeted = false; @@ -169,6 +172,7 @@ /** * @return true, if ih is target of this handler */ + @Override public boolean containsTarget(InstructionHandle ih) { return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih); } @@ -190,10 +194,12 @@ */ public InstructionHandle getHandlerPC() { return handler_pc; } + @Override public String toString() { return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")"; } + @Override public Object clone() { try { return super.clone();
--- a/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/LineNumberGen.java Tue Sep 17 16:33:44 2013 +0200 @@ -58,7 +58,6 @@ * <http://www.apache.org/>. */ -import com.sun.org.apache.bcel.internal.Constants; import com.sun.org.apache.bcel.internal.classfile.*; /** @@ -88,6 +87,7 @@ /** * @return true, if ih is target of this line number */ + @Override public boolean containsTarget(InstructionHandle ih) { return this.ih == ih; } @@ -96,6 +96,7 @@ * @param old_ih old target * @param new_ih new target */ + @Override public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { if(old_ih != ih) throw new ClassGenException("Not targeting " + old_ih + ", but " + ih + "}"); @@ -113,12 +114,13 @@ return new LineNumber(ih.getPosition(), src_line); } - public void setInstruction(InstructionHandle ih) { - BranchInstruction.notifyTarget(this.ih, ih, this); - + public final void setInstruction(InstructionHandle ih) { + BranchInstruction.notifyTargetChanging(this.ih, this); this.ih = ih; + BranchInstruction.notifyTargetChanged(this.ih, this); } + @Override public Object clone() { try { return super.clone();
--- a/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/LocalVariableGen.java Tue Sep 17 16:33:44 2013 +0200 @@ -60,6 +60,7 @@ import com.sun.org.apache.bcel.internal.Constants; import com.sun.org.apache.bcel.internal.classfile.*; +import com.sun.org.apache.bcel.internal.util.Objects; /** * This class represents a local variable within a method. It contains its @@ -75,7 +76,7 @@ implements InstructionTargeter, NamedAndTyped, Cloneable, java.io.Serializable { - private int index; + private final int index; private String name; private Type type; private InstructionHandle start, end; @@ -131,30 +132,96 @@ signature_index, index, cp.getConstantPool()); } - public void setIndex(int index) { this.index = index; } - public int getIndex() { return index; } + public int getIndex() { return index; } + @Override public void setName(String name) { this.name = name; } + @Override public String getName() { return name; } + @Override public void setType(Type type) { this.type = type; } + @Override public Type getType() { return type; } public InstructionHandle getStart() { return start; } public InstructionHandle getEnd() { return end; } - public void setStart(InstructionHandle start) { - BranchInstruction.notifyTarget(this.start, start, this); - this.start = start; + /** + * Remove this from any known HashSet in which it might be registered. + */ + void notifyTargetChanging() { + // hashCode depends on 'index', 'start', and 'end'. + // Therefore before changing any of these values we + // need to unregister 'this' from any HashSet where + // this is registered, and then we need to add it + // back... + + // Unregister 'this' from the HashSet held by 'start'. + BranchInstruction.notifyTargetChanging(this.start, this); + if (this.end != this.start) { + // Since hashCode() is going to change we need to unregister + // 'this' both form 'start' and 'end'. + // Unregister 'this' from the HashSet held by 'end'. + BranchInstruction.notifyTargetChanging(this.end, this); + } } - public void setEnd(InstructionHandle end) { - BranchInstruction.notifyTarget(this.end, end, this); + /** + * Add back 'this' in all HashSet in which it should be registered. + **/ + void notifyTargetChanged() { + // hashCode depends on 'index', 'start', and 'end'. + // Therefore before changing any of these values we + // need to unregister 'this' from any HashSet where + // this is registered, and then we need to add it + // back... + + // Register 'this' in the HashSet held by start. + BranchInstruction.notifyTargetChanged(this.start, this); + if (this.end != this.start) { + // Since hashCode() has changed we need to register + // 'this' again in 'end'. + // Add back 'this' in the HashSet held by 'end'. + BranchInstruction.notifyTargetChanged(this.end, this); + } + } + + public final void setStart(InstructionHandle start) { + + // Call notifyTargetChanging *before* modifying this, + // as the code triggered by notifyTargetChanging + // depends on this pointing to the 'old' start. + notifyTargetChanging(); + + this.start = start; + + // call notifyTargetChanged *after* modifying this, + // as the code triggered by notifyTargetChanged + // depends on this pointing to the 'new' start. + notifyTargetChanged(); + } + + public final void setEnd(InstructionHandle end) { + // call notifyTargetChanging *before* modifying this, + // as the code triggered by notifyTargetChanging + // depends on this pointing to the 'old' end. + // Unregister 'this' from the HashSet held by the 'old' end. + notifyTargetChanging(); + this.end = end; + + // call notifyTargetChanged *after* modifying this, + // as the code triggered by notifyTargetChanged + // depends on this pointing to the 'new' end. + // Register 'this' in the HashSet held by the 'new' end. + notifyTargetChanged(); + } /** * @param old_ih old target, either start or end * @param new_ih new target */ + @Override public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { boolean targeted = false; @@ -176,15 +243,20 @@ /** * @return true, if ih is target of this variable */ + @Override public boolean containsTarget(InstructionHandle ih) { return (start == ih) || (end == ih); } /** - * We consider to local variables to be equal, if the use the same index and + * We consider two local variables to be equal, if they use the same index and * are valid in the same range. */ + @Override public boolean equals(Object o) { + if (o==this) + return true; + if(!(o instanceof LocalVariableGen)) return false; @@ -192,10 +264,21 @@ return (l.index == index) && (l.start == start) && (l.end == end); } + @Override + public int hashCode() { + int hash = 7; + hash = 59 * hash + this.index; + hash = 59 * hash + Objects.hashCode(this.start); + hash = 59 * hash + Objects.hashCode(this.end); + return hash; + } + + @Override public String toString() { return "LocalVariableGen(" + name + ", " + type + ", " + start + ", " + end + ")"; } + @Override public Object clone() { try { return super.clone();
--- a/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/ReturnaddressType.java Tue Sep 17 16:33:44 2013 +0200 @@ -58,7 +58,7 @@ * <http://www.apache.org/>. */ import com.sun.org.apache.bcel.internal.Constants; -import com.sun.org.apache.bcel.internal.generic.InstructionHandle; +import com.sun.org.apache.bcel.internal.util.Objects; /** * Returnaddress, the type JSR or JSR_W instructions push upon the stack. @@ -86,9 +86,15 @@ this.returnTarget = returnTarget; } + @Override + public int hashCode() { + return Objects.hashCode(this.returnTarget); + } + /** * Returns if the two Returnaddresses refer to the same target. */ + @Override public boolean equals(Object rat){ if(!(rat instanceof ReturnaddressType)) return false;
--- a/src/com/sun/org/apache/bcel/internal/generic/Select.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/bcel/internal/generic/Select.java Tue Sep 17 16:33:44 2013 +0200 @@ -97,8 +97,9 @@ super(opcode, target); this.targets = targets; - for(int i=0; i < targets.length; i++) - notifyTarget(null, targets[i], this); + for(int i=0; i < targets.length; i++) { + BranchInstruction.notifyTargetChanged(targets[i], this); + } this.match = match; @@ -121,6 +122,7 @@ * @param max_offset the maximum offset that may be caused by these instructions * @return additional offset caused by possible change of this instruction's length */ + @Override protected int updatePosition(int offset, int max_offset) { position += offset; // Additional offset caused by preceding SWITCHs, GOTOs, etc. @@ -138,6 +140,7 @@ * Dump instruction as byte code to stream out. * @param out Output stream */ + @Override public void dump(DataOutputStream out) throws IOException { out.writeByte(opcode); @@ -151,6 +154,7 @@ /** * Read needed data (e.g. index) from file. */ + @Override protected void initFromFile(ByteSequence bytes, boolean wide) throws IOException { padding = (4 - (bytes.getIndex() % 4)) % 4; // Compute number of pad bytes @@ -166,8 +170,9 @@ /** * @return mnemonic for instruction */ + @Override public String toString(boolean verbose) { - StringBuffer buf = new StringBuffer(super.toString(verbose)); + final StringBuilder buf = new StringBuilder(super.toString(verbose)); if(verbose) { for(int i=0; i < match_length; i++) { @@ -176,7 +181,8 @@ if(targets[i] != null) s = targets[i].getInstruction().toString(); - buf.append("(" + match[i] + ", " + s + " = {" + indices[i] + "})"); + buf.append("(").append(match[i]).append(", ") + .append(s).append(" = {").append(indices[i]).append("})"); } } else @@ -188,15 +194,17 @@ /** * Set branch target for `i'th case */ - public void setTarget(int i, InstructionHandle target) { - notifyTarget(targets[i], target, this); + public final void setTarget(int i, InstructionHandle target) { + notifyTargetChanging(targets[i], this); targets[i] = target; + notifyTargetChanged(targets[i], this); } /** * @param old_ih old target * @param new_ih new target */ + @Override public void updateTarget(InstructionHandle old_ih, InstructionHandle new_ih) { boolean targeted = false; @@ -219,6 +227,7 @@ /** * @return true, if ih is target of this instruction */ + @Override public boolean containsTarget(InstructionHandle ih) { if(target == ih) return true; @@ -233,6 +242,7 @@ /** * Inform targets that they're not targeted anymore. */ + @Override void dispose() { super.dispose();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/bcel/internal/util/Objects.java Tue Sep 17 16:33:44 2013 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 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.bcel.internal.util; + +/** + * Emulate two methods of java.util.Objects. We can't use JDK 7 new APIs in + * JAXP because the jaxp repository is built before the jdk repository. This + * is a temporary solution to simplify backports from JDK 8 to JDK 7. + **/ +public final class Objects { + private Objects() { + throw new IllegalAccessError(); + } + + public static int hashCode(final Object o) { + return o == null ? 0 : o.hashCode(); + } + + public static boolean equals(Object one, Object two) { + return one == two || one != null && one.equals(two); + } + +}
--- a/src/com/sun/org/apache/xalan/internal/XalanConstants.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/XalanConstants.java Tue Sep 17 16:33:44 2013 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -73,45 +73,19 @@ * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true */ public static final String EXTERNAL_ACCESS_DEFAULT_FSP = ""; - /** - * JDK version by which the default is to restrict external connection - */ - public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8; + /** * FEATURE_SECURE_PROCESSING (FSP) is false by default */ - public static final String EXTERNAL_ACCESS_DEFAULT = getExternalAccessDefault(false); + public static final String EXTERNAL_ACCESS_DEFAULT = ACCESS_EXTERNAL_ALL; + + public static final String XML_SECURITY_PROPERTY_MANAGER = + ORACLE_JAXP_PROPERTY_PREFIX + "xmlSecurityPropertyManager"; /** - * Determine the default value of the external access properties - * - * jaxp 1.5 does not require implementations to restrict by default - * - * For JDK8: - * The default value is 'file' (including jar:file); The keyword "all" grants permission - * to all protocols. When {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is on, - * the default value is an empty string indicating no access is allowed. - * - * For JDK7: - * The default value is 'all' granting permission to all protocols. If by default, - * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is true, it should - * not change the default value. However, if {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} - * is set explicitly, the values of the properties shall be set to an empty string - * indicating no access is allowed. - * - * @param isSecureProcessing indicating if Secure Processing is set - * @return default value + * Check if we're in jdk8 or above */ - public static String getExternalAccessDefault(boolean isSecureProcessing) { - String defaultValue = "all"; - if (isJDKandAbove(RESTRICT_BY_DEFAULT_JDK_VERSION)) { - defaultValue = "file"; - if (isSecureProcessing) { - defaultValue = EXTERNAL_ACCESS_DEFAULT_FSP; - } - } - return defaultValue; - } + public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); /* * Check the version of the current JDK against that specified in the @@ -125,7 +99,7 @@ * @return true if the current version is the same or above that represented * by the parameter */ - public static boolean isJDKandAbove(int compareTo) { + public static boolean isJavaVersionAtLeast(int compareTo) { String javaVersion = SecuritySupport.getSystemProperty("java.version"); String versions[] = javaVersion.split("\\.", 3); if (Integer.parseInt(versions[0]) >= compareTo || @@ -134,5 +108,4 @@ } return false; } - } // class Constants
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/utils/Objects.java Tue Sep 17 16:33:44 2013 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 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.xalan.internal.utils; + +/** + * Emulate two methods of java.util.Objects. We can't use JDK 7 new APIs in + * JAXP because the jaxp repository is built before the jdk repository. This + * is a temporary solution to simplify backports from JDK 8 to JDK 7. + **/ +public final class Objects { + private Objects() { + throw new IllegalAccessError(); + } + + public static int hashCode(final Object o) { + return o == null ? 0 : o.hashCode(); + } + + public static boolean equals(Object one, Object two) { + return one == two || one != null && one.equals(two); + } + +}
--- a/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java Tue Sep 17 16:33:44 2013 +0200 @@ -229,7 +229,8 @@ * @return the name of the protocol if rejected, null otherwise */ public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException { - if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) { + if (systemId == null || (allowedProtocols != null && + allowedProtocols.equalsIgnoreCase(accessAny))) { return null; } @@ -262,6 +263,9 @@ * @return true if the protocol is in the list */ private static boolean isProtocolAllowed(String protocol, String allowedProtocols) { + if (allowedProtocols == null) { + return false; + } String temp[] = allowedProtocols.split(","); for (String t : temp) { t = t.trim(); @@ -273,18 +277,16 @@ } /** - * Read from $java.home/lib/jaxp.properties for the specified property + * Read JAXP system property in this order: system property, + * $java.home/lib/jaxp.properties if the system property is not specified * * @param propertyId the Id of the property * @return the value of the property */ - public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) { - String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId); + public static String getJAXPSystemProperty(String sysPropertyId) { + String accessExternal = getSystemProperty(sysPropertyId); if (accessExternal == null) { accessExternal = readJAXPProperty(sysPropertyId); - if (accessExternal == null) { - accessExternal = defaultVal; - } } return accessExternal; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java Tue Sep 17 16:33:44 2013 +0200 @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2013 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.xalan.internal.utils; + + +import com.sun.org.apache.xalan.internal.XalanConstants; +import javax.xml.XMLConstants; + +/** + * This class manages security related properties + * + */ +public final class XMLSecurityPropertyManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + } + + /** + * Limits managed by the security manager + */ + public static enum Property { + ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, + XalanConstants.EXTERNAL_ACCESS_DEFAULT), + ACCESS_EXTERNAL_STYLESHEET(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, + XalanConstants.EXTERNAL_ACCESS_DEFAULT); + + final String name; + final String defaultValue; + + Property(String name, String value) { + this.name = name; + this.defaultValue = value; + } + + public boolean equalsName(String propertyName) { + return (propertyName == null) ? false : name.equals(propertyName); + } + + String defaultValue() { + return defaultValue; + } + } + + + /** + * Values of the properties as defined in enum Properties + */ + private final String[] values; + /** + * States of the settings for each property in Properties above + */ + private State[] states = {State.DEFAULT, State.DEFAULT}; + + /** + * Default constructor. Establishes default values + */ + public XMLSecurityPropertyManager() { + values = new String[Property.values().length]; + for (Property property : Property.values()) { + values[property.ordinal()] = property.defaultValue(); + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Set the value for a specific property. + * + * @param property the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(Property property, State state, String value) { + //only update if it shall override + if (state.compareTo(states[property.ordinal()]) >= 0) { + values[property.ordinal()] = value; + states[property.ordinal()] = state; + } + } + + /** + * Set the value of a property by its index + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(int index, State state, String value) { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + } + } + /** + * Return the value of the specified property + * + * @param property the property + * @return the value of the property + */ + public String getValue(Property property) { + return values[property.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * @param index the index of a property + * @return value of a property + */ + public String getValueByIndex(int index) { + return values[index]; + } + + /** + * Get the index by property name + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName){ + for (Property property : Property.values()) { + if (property.equalsName(propertyName)) { + //internally, ordinal is used as index + return property.ordinal(); + } + } + return -1; + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + getSystemProperty(Property.ACCESS_EXTERNAL_DTD, + XalanConstants.SP_ACCESS_EXTERNAL_DTD); + getSystemProperty(Property.ACCESS_EXTERNAL_STYLESHEET, + XalanConstants.SP_ACCESS_EXTERNAL_STYLESHEET); + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the property + * @param systemProperty the name of the system property + */ + private void getSystemProperty(Property property, String systemProperty) { + try { + String value = SecuritySupport.getSystemProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.SYSTEMPROPERTY; + return; + } + + value = SecuritySupport.readJAXPProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.JAXPDOTPROPERTIES; + } + } catch (NumberFormatException e) { + //invalid setting ignored + } + } +}
--- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/FunctionCall.java Tue Sep 17 16:33:44 2013 +0200 @@ -54,6 +54,7 @@ import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; +import com.sun.org.apache.xalan.internal.utils.Objects; /** * @author Jacek Ambroziak @@ -156,8 +157,15 @@ this.type = type; this.distance = distance; } + + @Override + public int hashCode() { + return Objects.hashCode(this.type); + } + + @Override public boolean equals(Object query){ - return query.equals(type); + return query != null && query.equals(type); } } @@ -277,6 +285,7 @@ return(_fname.toString()); } + @Override public void setParser(Parser parser) { super.setParser(parser); if (_arguments != null) { @@ -319,6 +328,7 @@ * Type check a function call. Since different type conversions apply, * type checking is different for standard and external (Java) functions. */ + @Override public Type typeCheck(SymbolTable stable) throws TypeCheckError { @@ -680,6 +690,7 @@ * Compile the function call and treat as an expression * Update true/false-lists. */ + @Override public void translateDesynthesized(ClassGenerator classGen, MethodGenerator methodGen) { @@ -700,6 +711,7 @@ * Translate a function call. The compiled code will leave the function's * return value on the JVM's stack. */ + @Override public void translate(ClassGenerator classGen, MethodGenerator methodGen) { final int n = argumentCount(); final ConstantPoolGen cpg = classGen.getConstantPool(); @@ -857,6 +869,7 @@ } } + @Override public String toString() { return "funcall(" + _fname + ", " + _arguments + ')'; } @@ -1069,7 +1082,7 @@ protected static String replaceDash(String name) { char dash = '-'; - StringBuffer buff = new StringBuffer(""); + final StringBuilder buff = new StringBuilder(""); for (int i = 0; i < name.length(); i++) { if (i > 0 && name.charAt(i-1) == dash) buff.append(Character.toUpperCase(name.charAt(i)));
--- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/Parser.java Tue Sep 17 16:33:44 2013 +0200 @@ -52,6 +52,7 @@ import org.xml.sax.InputSource; import org.xml.sax.Locator; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.AttributesImpl; @@ -476,8 +477,15 @@ factory.setNamespaceAware(true); } final SAXParser parser = factory.newSAXParser(); - parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); + try { + parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, + _xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); + } catch (SAXNotRecognizedException e) { + ErrorMsg err = new ErrorMsg(ErrorMsg.WARNING_MSG, + parser.getClass().getName() + ": " + e.getMessage()); + reportError(WARNING, err); + } + final XMLReader reader = parser.getXMLReader(); return(parse(reader, input)); }
--- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/VariableRefBase.java Tue Sep 17 16:33:44 2013 +0200 @@ -23,6 +23,7 @@ package com.sun.org.apache.xalan.internal.xsltc.compiler; +import com.sun.org.apache.xalan.internal.utils.Objects; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.Type; import com.sun.org.apache.xalan.internal.xsltc.compiler.util.TypeCheckError; @@ -97,13 +98,15 @@ * Two variable references are deemed equal if they refer to the * same variable. */ + @Override public boolean equals(Object obj) { - try { - return (_variable == ((VariableRefBase) obj)._variable); - } - catch (ClassCastException e) { - return false; - } + return obj == this || (obj instanceof VariableRefBase) + && (_variable == ((VariableRefBase) obj)._variable); + } + + @Override + public int hashCode() { + return Objects.hashCode(this._variable); } /** @@ -111,10 +114,12 @@ * format 'variable-ref(<var-name>)'. * @return Variable reference description */ + @Override public String toString() { return "variable-ref("+_variable.getName()+'/'+_variable.getType()+')'; } + @Override public Type typeCheck(SymbolTable stable) throws TypeCheckError {
--- a/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java Tue Sep 17 16:33:44 2013 +0200 @@ -449,7 +449,7 @@ * Note to translators: access to the stylesheet target is denied */ {ErrorMsg.ACCESSING_XSLT_TARGET_ERR, - "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed."}, + "Could not read stylesheet target ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalStylesheet property."}, /* * Note to translators: This message represents an internal error in
--- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java Tue Sep 17 16:33:44 2013 +0200 @@ -74,6 +74,9 @@ import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.State; import org.xml.sax.InputSource; import org.xml.sax.XMLFilter; @@ -228,11 +231,13 @@ * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element. */ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + /** * protocols allowed for external DTD references in source file and/or stylesheet. */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityPropertyManager _xmlSecurityPropertyMgr; /** * javax.xml.transform.sax.TransformerFactory implementation. @@ -249,16 +254,16 @@ this.m_DTMManagerClass = XSLTCDTMManager.getDTMManagerClass(useServicesMechanism); this._useServicesMechanism = useServicesMechanism; - String defaultAccess = XalanConstants.EXTERNAL_ACCESS_DEFAULT; if (System.getSecurityManager() != null) { _isSecureMode = true; _isNotSecureProcessing = false; - defaultAccess = XalanConstants.getExternalAccessDefault(true); } - _accessExternalStylesheet = SecuritySupport.getDefaultAccessProperty( - XalanConstants.SP_ACCESS_EXTERNAL_STYLESHEET, defaultAccess); - _accessExternalDTD = SecuritySupport.getDefaultAccessProperty( - XalanConstants.SP_ACCESS_EXTERNAL_DTD, defaultAccess); + + _xmlSecurityPropertyMgr = new XMLSecurityPropertyManager(); + _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_DTD); + _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_STYLESHEET); } /** @@ -318,11 +323,10 @@ else return Boolean.FALSE; } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { - return _accessExternalStylesheet; - } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { - return _accessExternalDTD; + + int index = _xmlSecurityPropertyMgr.getIndex(name); + if (index > -1) { + return _xmlSecurityPropertyMgr.getValueByIndex(index); } // Throw an exception for all other attributes @@ -424,12 +428,15 @@ return; } } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { - _accessExternalStylesheet = (String)value; - return; - } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { - _accessExternalDTD = (String)value; + + int index = _xmlSecurityPropertyMgr.getIndex(name); + if (index > -1) { + _xmlSecurityPropertyMgr.setValue(index, + State.APIPROPERTY, (String)value); + _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_DTD); + _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_STYLESHEET); return; } @@ -476,11 +483,18 @@ } _isNotSecureProcessing = !value; - // set restriction, allowing no access to external stylesheet - if (value) { - _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP; - _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP; + // set external access restriction when FSP is explicitly set + if (value && XalanConstants.IS_JDK8_OR_ABOVE) { + _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, + State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP); + _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_STYLESHEET, + State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP); + _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_DTD); + _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_STYLESHEET); } + return; } else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) {
--- a/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java Tue Sep 17 16:33:44 2013 +0200 @@ -105,8 +105,6 @@ if (reader == null) { try { reader= XMLReaderFactory.createXMLReader(); - reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); } catch (Exception e ) { try { @@ -138,6 +136,14 @@ reader.setFeature ("http://xml.org/sax/features/namespace-prefixes",false); + try { + reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, + xsltc.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); + } catch (SAXNotRecognizedException e) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + e.getMessage()); + } + xsltc.setXMLReader(reader); }catch (SAXNotRecognizedException snre ) { throw new TransformerConfigurationException
--- a/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java Tue Sep 17 16:33:44 2013 +0200 @@ -33,7 +33,7 @@ import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.utils.ObjectFactory; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; @@ -156,13 +156,9 @@ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; - /** Property identifier: access to external dtd */ - protected static final String ACCESS_EXTERNAL_DTD = - XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - protected static final String ACCESS_EXTERNAL_SCHEMA = - XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; // // Data @@ -283,8 +279,7 @@ JAXP_SCHEMA_LANGUAGE, DTD_VALIDATOR_FACTORY_PROPERTY, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -318,14 +313,8 @@ fValidationManager = createValidationManager(); setProperty(VALIDATION_MANAGER, fValidationManager); - //For DOM, the secure feature is set to true by default - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - setProperty(ACCESS_EXTERNAL_DTD, accessExternal); - - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal); + setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, + new XMLSecurityPropertyManager()); // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
--- a/src/com/sun/org/apache/xerces/internal/impl/Constants.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/Constants.java Tue Sep 17 16:33:44 2013 +0200 @@ -184,6 +184,9 @@ public static final String ORACLE_JAXP_PROPERTY_PREFIX = "http://www.oracle.com/xml/jaxp/properties/"; + public static final String XML_SECURITY_PROPERTY_MANAGER = + ORACLE_JAXP_PROPERTY_PREFIX + "xmlSecurityPropertyManager"; + //System Properties corresponding to ACCESS_EXTERNAL_* properties public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD"; public static final String SP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema"; @@ -194,15 +197,16 @@ * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true */ public static final String EXTERNAL_ACCESS_DEFAULT_FSP = ""; - /** - * JDK version by which the default is to restrict external connection - */ - public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8; /** * FEATURE_SECURE_PROCESSING (FSP) is true by default */ - public static final String EXTERNAL_ACCESS_DEFAULT = getExternalAccessDefault(true); + public static final String EXTERNAL_ACCESS_DEFAULT = ACCESS_EXTERNAL_ALL; + + /** + * Check if we're in jdk8 or above + */ + public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); // // DOM features @@ -697,37 +701,6 @@ ? new ArrayEnumeration(fgXercesProperties) : fgEmptyEnumeration; } // getXercesProperties():Enumeration - /** - * Determine the default value of the external access properties - * - * jaxp 1.5 does not require implementations to restrict by default - * - * For JDK8: - * The default value is 'file' (including jar:file); The keyword "all" grants permission - * to all protocols. When {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is on, - * the default value is an empty string indicating no access is allowed. - * - * For JDK7: - * The default value is 'all' granting permission to all protocols. If by default, - * {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} is true, it should - * not change the default value. However, if {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} - * is set explicitly, the values of the properties shall be set to an empty string - * indicating no access is allowed. - * - * @param isSecureProcessing indicating if Secure Processing is set - * @return default value - */ - public static String getExternalAccessDefault(boolean isSecureProcessing) { - String defaultValue = "all"; - if (isJDKandAbove(RESTRICT_BY_DEFAULT_JDK_VERSION)) { - defaultValue = "file"; - if (isSecureProcessing) { - defaultValue = EXTERNAL_ACCESS_DEFAULT_FSP; - } - } - return defaultValue; - } - /* * Check the version of the current JDK against that specified in the * parameter @@ -740,7 +713,7 @@ * @return true if the current version is the same or above that represented * by the parameter */ - public static boolean isJDKandAbove(int compareTo) { + public static boolean isJavaVersionAtLeast(int compareTo) { String javaVersion = SecuritySupport.getSystemProperty("java.version"); String versions[] = javaVersion.split("\\.", 3); if (Integer.parseInt(versions[0]) >= compareTo ||
--- a/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java Tue Sep 17 16:33:44 2013 +0200 @@ -25,10 +25,9 @@ package com.sun.org.apache.xerces.internal.impl; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.xml.internal.stream.StaxEntityResolverWrapper; import java.util.HashMap; -import javax.xml.XMLConstants; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLResolver; @@ -51,15 +50,14 @@ private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning"; - - /** Property identifier: access to external dtd */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; HashMap supportedProps = new HashMap(); + private XMLSecurityPropertyManager fSecurityPropertyMgr; + public static final int CONTEXT_READER = 1; public static final int CONTEXT_WRITER = 2; @@ -84,6 +82,7 @@ HashMap properties = propertyManager.getProperties(); supportedProps.putAll(properties); + fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER); } private HashMap getProperties(){ @@ -125,14 +124,8 @@ supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false)); supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false)); - //For DOM/SAX, the secure feature is set to true by default - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - supportedProps.put(ACCESS_EXTERNAL_DTD, accessExternal); - - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - supportedProps.put(ACCESS_EXTERNAL_SCHEMA, accessExternal); + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); } private void initWriterProps(){ @@ -148,7 +141,8 @@ * } */ public boolean containsProperty(String property){ - return supportedProps.containsKey(property) ; + return supportedProps.containsKey(property) || + (fSecurityPropertyMgr!=null && fSecurityPropertyMgr.getIndex(property) > -1) ; } public Object getProperty(String property){ @@ -174,7 +168,15 @@ //add internal stax property supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; } - supportedProps.put(property, value ) ; + + int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(property) : -1; + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + } else { + supportedProps.put(property, value); + } + if(equivalentProperty != null){ supportedProps.put(equivalentProperty, value ) ; }
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java Tue Sep 17 16:33:44 2013 +0200 @@ -53,6 +53,7 @@ import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.xml.internal.stream.Entity; import javax.xml.XMLConstants; @@ -166,8 +167,9 @@ protected static final String STANDARD_URI_CONFORMANT = Constants.XERCES_FEATURE_PREFIX +Constants.STANDARD_URI_CONFORMANT_FEATURE; - /** property identifier: access external dtd. */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; /** access external dtd: file protocol * For DOM/SAX, the secure feature is set to true by default @@ -199,7 +201,7 @@ SYMBOL_TABLE, ERROR_REPORTER, ENTITY_MANAGER, - ACCESS_EXTERNAL_DTD + XML_SECURITY_PROPERTY_MANAGER }; /** Property defaults. */ @@ -610,7 +612,10 @@ dtdGrammarUtil = null; // JAXP 1.5 features and properties - fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false); //fEntityManager.test(); @@ -662,9 +667,10 @@ dtdGrammarUtil = null; - // Oracle jdk feature - fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD); - + // JAXP 1.5 features and properties + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); } // reset(XMLComponentManager) /** @@ -762,11 +768,10 @@ } //JAXP 1.5 properties - if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) { - if (propertyId.equals(ACCESS_EXTERNAL_DTD)) - { - fAccessExternalDTD = (String)value; - } + if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) + { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value; + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); } } // setProperty(String,Object)
--- a/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java Tue Sep 17 16:33:44 2013 +0200 @@ -31,6 +31,7 @@ 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.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; @@ -166,8 +167,9 @@ protected static final String PARSER_SETTINGS = Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; - /** property identifier: access external dtd. */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; /** access external dtd: file protocol */ static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT; @@ -203,7 +205,7 @@ VALIDATION_MANAGER, BUFFER_SIZE, SECURITY_MANAGER, - ACCESS_EXTERNAL_DTD + XML_SECURITY_PROPERTY_MANAGER }; /** Property defaults. */ @@ -214,7 +216,7 @@ null, new Integer(DEFAULT_BUFFER_SIZE), null, - EXTERNAL_ACCESS_DEFAULT + null }; private static final String XMLEntity = "[xml]".intern(); @@ -1421,7 +1423,8 @@ fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue(); // JAXP 1.5 feature - fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); // initialize state //fStandalone = false; @@ -1485,7 +1488,11 @@ fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); // JAXP 1.5 feature - fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); + if (spm == null) { + spm = new XMLSecurityPropertyManager(); + } + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); //reset general state reset(); @@ -1641,11 +1648,10 @@ } //JAXP 1.5 properties - if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) { - if (propertyId.equals(ACCESS_EXTERNAL_DTD)) - { - fAccessExternalDTD = (String)value; - } + if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) + { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value; + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); } }
--- a/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/dv/xs/AbstractDateTimeDV.java Tue Sep 17 16:33:44 2013 +0200 @@ -51,456 +51,471 @@ */ public abstract class AbstractDateTimeDV extends TypeValidator { - //debugging - private static final boolean DEBUG=false; - - //define shared variables for date/time - - - //define constants to be used in assigning default values for - //all date/time excluding duration - protected final static int YEAR=2000; - protected final static int MONTH=01; - protected final static int DAY = 01; - + //debugging + private static final boolean DEBUG = false; + //define shared variables for date/time + //define constants to be used in assigning default values for + //all date/time excluding duration + protected final static int YEAR = 2000; + protected final static int MONTH = 01; + protected final static int DAY = 01; protected static final DatatypeFactory datatypeFactory = new DatatypeFactoryImpl(); - public short getAllowedFacets(){ - return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE ); - }//getAllowedFacets() + @Override + public short getAllowedFacets() { + return (XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION | XSSimpleTypeDecl.FACET_MAXINCLUSIVE | XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE); + }//getAllowedFacets() + + // distinguishes between identity and equality for date/time values + // ie: two values representing the same "moment in time" but with different + // remembered timezones are now equal but not identical. + @Override + public boolean isIdentical(Object value1, Object value2) { + if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) { + return false; + } + + DateTimeData v1 = (DateTimeData) value1; + DateTimeData v2 = (DateTimeData) value2; + + // original timezones must be the same in addition to date/time values + // being 'equal' + if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) { + return v1.equals(v2); + } + + return false; + }//isIdentical() + + // the parameters are in compiled form (from getActualValue) + @Override + public int compare(Object value1, Object value2) { + return compareDates(((DateTimeData) value1), + ((DateTimeData) value2), true); + }//compare() + /** + * Compare algorithm described in dateDime (3.2.7). Duration datatype + * overwrites this method + * + * @param date1 normalized date representation of the first value + * @param date2 normalized date representation of the second value + * @param strict + * @return less, greater, less_equal, greater_equal, equal + */ + protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) { + if (date1.utc == date2.utc) { + return compareOrder(date1, date2); + } + short c1, c2; + + DateTimeData tempDate = new DateTimeData(null, this); + + if (date1.utc == 'Z') { + + //compare date1<=date1<=(date2 with time zone -14) + // + cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate + tempDate.timezoneHr = 14; + tempDate.timezoneMin = 0; + tempDate.utc = '+'; + normalize(tempDate); + c1 = compareOrder(date1, tempDate); + if (c1 == LESS_THAN) { + return c1; + } + + //compare date1>=(date2 with time zone +14) + // + cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate + tempDate.timezoneHr = -14; + tempDate.timezoneMin = 0; + tempDate.utc = '-'; + normalize(tempDate); + c2 = compareOrder(date1, tempDate); + if (c2 == GREATER_THAN) { + return c2; + } + + return INDETERMINATE; + } else if (date2.utc == 'Z') { - // distinguishes between identity and equality for date/time values - // ie: two values representing the same "moment in time" but with different - // remembered timezones are now equal but not identical. - public boolean isIdentical (Object value1, Object value2) { - if (!(value1 instanceof DateTimeData) || !(value2 instanceof DateTimeData)) { - return false; - } + //compare (date1 with time zone -14)<=date2 + // + cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate + tempDate.timezoneHr = -14; + tempDate.timezoneMin = 0; + tempDate.utc = '-'; + if (DEBUG) { + System.out.println("tempDate=" + dateToString(tempDate)); + } + normalize(tempDate); + c1 = compareOrder(tempDate, date2); + if (DEBUG) { + System.out.println("date=" + dateToString(date2)); + System.out.println("tempDate=" + dateToString(tempDate)); + } + if (c1 == LESS_THAN) { + return c1; + } + + //compare (date1 with time zone +14)<=date2 + // + cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate + tempDate.timezoneHr = 14; + tempDate.timezoneMin = 0; + tempDate.utc = '+'; + normalize(tempDate); + c2 = compareOrder(tempDate, date2); + if (DEBUG) { + System.out.println("tempDate=" + dateToString(tempDate)); + } + if (c2 == GREATER_THAN) { + return c2; + } + + return INDETERMINATE; + } + return INDETERMINATE; + + } + + /** + * Given normalized values, determines order-relation between give date/time + * objects. + * + * @param date1 date/time object + * @param date2 date/time object + * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is + * less than date2, a value greater than 0 if date1 is greater than date2 + */ + protected short compareOrder(DateTimeData date1, DateTimeData date2) { + if (date1.position < 1) { + if (date1.year < date2.year) { + return -1; + } + if (date1.year > date2.year) { + return 1; + } + } + if (date1.position < 2) { + if (date1.month < date2.month) { + return -1; + } + if (date1.month > date2.month) { + return 1; + } + } + if (date1.day < date2.day) { + return -1; + } + if (date1.day > date2.day) { + return 1; + } + if (date1.hour < date2.hour) { + return -1; + } + if (date1.hour > date2.hour) { + return 1; + } + if (date1.minute < date2.minute) { + return -1; + } + if (date1.minute > date2.minute) { + return 1; + } + if (date1.second < date2.second) { + return -1; + } + if (date1.second > date2.second) { + return 1; + } + if (date1.utc < date2.utc) { + return -1; + } + if (date1.utc > date2.utc) { + return 1; + } + return 0; + } - DateTimeData v1 = (DateTimeData)value1; - DateTimeData v2 = (DateTimeData)value2; + /** + * Parses time hh:mm:ss.sss and time zone if any + * + * @param start + * @param end + * @param data + * @exception RuntimeException + */ + protected void getTime(String buffer, int start, int end, DateTimeData data) throws RuntimeException { + + int stop = start + 2; + + //get hours (hh) + data.hour = parseInt(buffer, start, stop); + + //get minutes (mm) + + if (buffer.charAt(stop++) != ':') { + throw new RuntimeException("Error in parsing time zone"); + } + start = stop; + stop = stop + 2; + data.minute = parseInt(buffer, start, stop); + + //get seconds (ss) + if (buffer.charAt(stop++) != ':') { + throw new RuntimeException("Error in parsing time zone"); + } + + //find UTC sign if any + int sign = findUTCSign(buffer, start, end); + + //get seconds (ms) + start = stop; + stop = sign < 0 ? end : sign; + data.second = parseSecond(buffer, start, stop); - // original timezones must be the same in addition to date/time values - // being 'equal' - if ((v1.timezoneHr == v2.timezoneHr) && (v1.timezoneMin == v2.timezoneMin)) { - return v1.equals(v2); - } + //parse UTC time zone (hh:mm) + if (sign > 0) { + getTimeZone(buffer, data, sign, end); + } + } + + /** + * Parses date CCYY-MM-DD + * + * @param buffer + * @param start start position + * @param end end position + * @param date + * @exception RuntimeException + */ + protected int getDate(String buffer, int start, int end, DateTimeData date) throws RuntimeException { + + start = getYearMonth(buffer, start, end, date); + + if (buffer.charAt(start++) != '-') { + throw new RuntimeException("CCYY-MM must be followed by '-' sign"); + } + int stop = start + 2; + date.day = parseInt(buffer, start, stop); + return stop; + } + + /** + * Parses date CCYY-MM + * + * @param buffer + * @param start start position + * @param end end position + * @param date + * @exception RuntimeException + */ + protected int getYearMonth(String buffer, int start, int end, DateTimeData date) throws RuntimeException { - return false; - }//isIdentical() + if (buffer.charAt(0) == '-') { + // REVISIT: date starts with preceding '-' sign + // do we have to do anything with it? + // + start++; + } + int i = indexOf(buffer, start, end, '-'); + if (i == -1) { + throw new RuntimeException("Year separator is missing or misplaced"); + } + int length = i - start; + if (length < 4) { + throw new RuntimeException("Year must have 'CCYY' format"); + } else if (length > 4 && buffer.charAt(start) == '0') { + throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden"); + } + date.year = parseIntYear(buffer, i); + if (buffer.charAt(i) != '-') { + throw new RuntimeException("CCYY must be followed by '-' sign"); + } + start = ++i; + i = start + 2; + date.month = parseInt(buffer, start, i); + return i; //fStart points right after the MONTH + } + + /** + * Shared code from Date and YearMonth datatypes. Finds if time zone sign is + * present + * + * @param end + * @param date + * @exception RuntimeException + */ + protected void parseTimeZone(String buffer, int start, int end, DateTimeData date) throws RuntimeException { + + //fStart points right after the date + + if (start < end) { + if (!isNextCharUTCSign(buffer, start, end)) { + throw new RuntimeException("Error in month parsing"); + } else { + getTimeZone(buffer, date, start, end); + } + } + } + + /** + * Parses time zone: 'Z' or {+,-} followed by hh:mm + * + * @param data + * @param sign + * @exception RuntimeException + */ + protected void getTimeZone(String buffer, DateTimeData data, int sign, int end) throws RuntimeException { + data.utc = buffer.charAt(sign); - // the parameters are in compiled form (from getActualValue) - public int compare (Object value1, Object value2) { - return compareDates(((DateTimeData)value1), - ((DateTimeData)value2), true); - }//compare() + if (buffer.charAt(sign) == 'Z') { + if (end > (++sign)) { + throw new RuntimeException("Error in parsing time zone"); + } + return; + } + if (sign <= (end - 6)) { + + int negate = buffer.charAt(sign) == '-' ? -1 : 1; + //parse hr + int stop = ++sign + 2; + data.timezoneHr = negate * parseInt(buffer, sign, stop); + if (buffer.charAt(stop++) != ':') { + throw new RuntimeException("Error in parsing time zone"); + } + + //parse min + data.timezoneMin = negate * parseInt(buffer, stop, stop + 2); + + if (stop + 2 != end) { + throw new RuntimeException("Error in parsing time zone"); + } + if (data.timezoneHr != 0 || data.timezoneMin != 0) { + data.normalized = false; + } + } else { + throw new RuntimeException("Error in parsing time zone"); + } + if (DEBUG) { + System.out.println("time[hh]=" + data.timezoneHr + " time[mm]=" + data.timezoneMin); + } + } + + /** + * Computes index of given char within StringBuffer + * + * @param start + * @param end + * @param ch character to look for in StringBuffer + * @return index of ch within StringBuffer + */ + protected int indexOf(String buffer, int start, int end, char ch) { + for (int i = start; i < end; i++) { + if (buffer.charAt(i) == ch) { + return i; + } + } + return -1; + } + + /** + * Validates given date/time object accoring to W3C PR Schema [D.1 ISO 8601 + * Conventions] + * + * @param data + */ + protected void validateDateTime(DateTimeData data) { + + //REVISIT: should we throw an exception for not valid dates + // or reporting an error message should be sufficient? /** - * Compare algorithm described in dateDime (3.2.7). - * Duration datatype overwrites this method - * - * @param date1 normalized date representation of the first value - * @param date2 normalized date representation of the second value - * @param strict - * @return less, greater, less_equal, greater_equal, equal + * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types. */ - protected short compareDates(DateTimeData date1, DateTimeData date2, boolean strict) { - if (date1.utc == date2.utc) { - return compareOrder(date1, date2); - } - short c1, c2; - - DateTimeData tempDate = new DateTimeData(null, this); - - if ( date1.utc=='Z' ) { - - //compare date1<=date1<=(date2 with time zone -14) - // - cloneDate(date2, tempDate); //clones date1 value to global temporary storage: fTempDate - tempDate.timezoneHr=14; - tempDate.timezoneMin = 0; - tempDate.utc='+'; - normalize(tempDate); - c1 = compareOrder(date1, tempDate); - if (c1 == LESS_THAN) - return c1; - - //compare date1>=(date2 with time zone +14) - // - cloneDate(date2, tempDate); //clones date1 value to global temporary storage: tempDate - tempDate.timezoneHr = -14; - tempDate.timezoneMin = 0; - tempDate.utc='-'; - normalize(tempDate); - c2 = compareOrder(date1, tempDate); - if (c2 == GREATER_THAN) - return c2; - - return INDETERMINATE; - } - else if ( date2.utc=='Z' ) { - - //compare (date1 with time zone -14)<=date2 - // - cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate - tempDate.timezoneHr = -14; - tempDate.timezoneMin = 0; - tempDate.utc='-'; - if (DEBUG) { - System.out.println("tempDate=" + dateToString(tempDate)); - } - normalize(tempDate); - c1 = compareOrder(tempDate, date2); - if (DEBUG) { - System.out.println("date=" + dateToString(date2)); - System.out.println("tempDate=" + dateToString(tempDate)); - } - if (c1 == LESS_THAN) - return c1; - - //compare (date1 with time zone +14)<=date2 - // - cloneDate(date1, tempDate); //clones date1 value to global temporary storage: tempDate - tempDate.timezoneHr = 14; - tempDate.timezoneMin = 0; - tempDate.utc='+'; - normalize(tempDate); - c2 = compareOrder(tempDate, date2); - if (DEBUG) { - System.out.println("tempDate=" + dateToString(tempDate)); - } - if (c2 == GREATER_THAN) - return c2; - - return INDETERMINATE; - } - return INDETERMINATE; + if (!Constants.SCHEMA_1_1_SUPPORT && data.year == 0) { + throw new RuntimeException("The year \"0000\" is an illegal year value"); } - /** - * Given normalized values, determines order-relation - * between give date/time objects. - * - * @param date1 date/time object - * @param date2 date/time object - * @return 0 if date1 and date2 are equal, a value less than 0 if date1 is less than date2, a value greater than 0 if date1 is greater than date2 - */ - protected short compareOrder(DateTimeData date1, DateTimeData date2) { - if(date1.position < 1) { - if (date1.year < date2.year) - return -1; - if (date1.year > date2.year) - return 1; - } - if(date1.position < 2) { - if (date1.month < date2.month) - return -1; - if (date1.month > date2.month) - return 1; - } - if (date1.day < date2.day) - return -1; - if (date1.day > date2.day) - return 1; - if (date1.hour < date2.hour) - return -1; - if (date1.hour > date2.hour) - return 1; - if (date1.minute < date2.minute) - return -1; - if (date1.minute > date2.minute) - return 1; - if (date1.second < date2.second) - return -1; - if (date1.second > date2.second) - return 1; - if (date1.utc < date2.utc) - return -1; - if (date1.utc > date2.utc) - return 1; - return 0; - } - - /** - * Parses time hh:mm:ss.sss and time zone if any - * - * @param start - * @param end - * @param data - * @exception RuntimeException - */ - protected void getTime (String buffer, int start, int end, DateTimeData data) throws RuntimeException{ - - int stop = start+2; - - //get hours (hh) - data.hour=parseInt(buffer, start,stop); - - //get minutes (mm) - - if (buffer.charAt(stop++)!=':') { - throw new RuntimeException("Error in parsing time zone" ); - } - start = stop; - stop = stop+2; - data.minute=parseInt(buffer, start,stop); - - //get seconds (ss) - if (buffer.charAt(stop++)!=':') { - throw new RuntimeException("Error in parsing time zone" ); - } - - //find UTC sign if any - int sign = findUTCSign(buffer, start, end); - - //get seconds (ms) - start = stop; - stop = sign < 0 ? end : sign; - data.second = parseSecond(buffer, start, stop); - - //parse UTC time zone (hh:mm) - if (sign > 0) { - getTimeZone(buffer, data, sign, end); - } - } - - /** - * Parses date CCYY-MM-DD - * - * @param buffer - * @param start start position - * @param end end position - * @param date - * @exception RuntimeException - */ - protected int getDate (String buffer, int start, int end, DateTimeData date) throws RuntimeException{ - - start = getYearMonth(buffer, start, end, date); - - if (buffer.charAt(start++) !='-') { - throw new RuntimeException("CCYY-MM must be followed by '-' sign"); - } - int stop = start + 2; - date.day=parseInt(buffer, start, stop); - return stop; - } - - /** - * Parses date CCYY-MM - * - * @param buffer - * @param start start position - * @param end end position - * @param date - * @exception RuntimeException - */ - protected int getYearMonth (String buffer, int start, int end, DateTimeData date) throws RuntimeException{ - - if ( buffer.charAt(0)=='-' ) { - // REVISIT: date starts with preceding '-' sign - // do we have to do anything with it? - // - start++; - } - int i = indexOf(buffer, start, end, '-'); - if ( i==-1 ) throw new RuntimeException("Year separator is missing or misplaced"); - int length = i-start; - if (length<4) { - throw new RuntimeException("Year must have 'CCYY' format"); - } - else if (length > 4 && buffer.charAt(start)=='0'){ - throw new RuntimeException("Leading zeros are required if the year value would otherwise have fewer than four digits; otherwise they are forbidden"); - } - date.year= parseIntYear(buffer, i); - if (buffer.charAt(i)!='-') { - throw new RuntimeException("CCYY must be followed by '-' sign"); - } - start = ++i; - i = start +2; - date.month=parseInt(buffer, start, i); - return i; //fStart points right after the MONTH - } - - /** - * Shared code from Date and YearMonth datatypes. - * Finds if time zone sign is present - * - * @param end - * @param date - * @exception RuntimeException - */ - protected void parseTimeZone (String buffer, int start, int end, DateTimeData date) throws RuntimeException{ - - //fStart points right after the date - - if ( start < end ) { - if (!isNextCharUTCSign(buffer, start, end)) { - throw new RuntimeException ("Error in month parsing"); - } - else { - getTimeZone(buffer, date, start, end); - } - } - } - - /** - * Parses time zone: 'Z' or {+,-} followed by hh:mm - * - * @param data - * @param sign - * @exception RuntimeException - */ - protected void getTimeZone (String buffer, DateTimeData data, int sign, int end) throws RuntimeException{ - data.utc=buffer.charAt(sign); - - if ( buffer.charAt(sign) == 'Z' ) { - if (end>(++sign)) { - throw new RuntimeException("Error in parsing time zone"); - } - return; - } - if ( sign<=(end-6) ) { - - int negate = buffer.charAt(sign) == '-'?-1:1; - //parse hr - int stop = ++sign+2; - data.timezoneHr = negate*parseInt(buffer, sign, stop); - if (buffer.charAt(stop++)!=':') { - throw new RuntimeException("Error in parsing time zone" ); - } - - //parse min - data.timezoneMin = negate*parseInt(buffer, stop, stop+2); - - if ( stop+2!=end ) { - throw new RuntimeException("Error in parsing time zone"); - } - if(data.timezoneHr != 0 || data.timezoneMin != 0) - data.normalized = false; - } - else { - throw new RuntimeException("Error in parsing time zone"); - } - if ( DEBUG ) { - System.out.println("time[hh]="+data.timezoneHr + " time[mm]=" +data.timezoneMin); - } - } - - /** - * Computes index of given char within StringBuffer - * - * @param start - * @param end - * @param ch character to look for in StringBuffer - * @return index of ch within StringBuffer - */ - protected int indexOf (String buffer, int start, int end, char ch) { - for ( int i=start;i<end;i++ ) { - if ( buffer.charAt(i) == ch ) { - return i; - } - } - return -1; - } - - /** - * Validates given date/time object accoring to W3C PR Schema - * [D.1 ISO 8601 Conventions] - * - * @param data - */ - protected void validateDateTime (DateTimeData data) { - - //REVISIT: should we throw an exception for not valid dates - // or reporting an error message should be sufficient? - - /** - * XML Schema 1.1 - RQ-123: Allow year 0000 in date related types. - */ - if (!Constants.SCHEMA_1_1_SUPPORT && data.year==0 ) { - throw new RuntimeException("The year \"0000\" is an illegal year value"); - - } - - if ( data.month<1 || data.month>12 ) { - throw new RuntimeException("The month must have values 1 to 12"); - - } - - //validate days - if ( data.day>maxDayInMonthFor(data.year, data.month) || data.day<1 ) { - throw new RuntimeException("The day must have values 1 to 31"); - } - - //validate hours - if ( data.hour>23 || data.hour<0 ) { - if (data.hour == 24 && data.minute == 0 && data.second == 0) { - data.hour = 0; - if (++data.day > maxDayInMonthFor(data.year, data.month)) { - data.day = 1; - if (++data.month > 12) { - data.month = 1; - if (Constants.SCHEMA_1_1_SUPPORT) { - ++data.year; - } - else if (++data.year == 0) { - data.year = 1; - } - } - } - } - else { - throw new RuntimeException("Hour must have values 0-23, unless 24:00:00"); - } - } - - //validate - if ( data.minute>59 || data.minute<0 ) { - throw new RuntimeException("Minute must have values 0-59"); - } - - //validate - if ( data.second>=60 || data.second<0 ) { - throw new RuntimeException("Second must have values 0-59"); - - } - - //validate - if ( data.timezoneHr>14 || data.timezoneHr<-14 ) { - throw new RuntimeException("Time zone should have range -14:00 to +14:00"); - } - else { - if((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0) - throw new RuntimeException("Time zone should have range -14:00 to +14:00"); - else if(data.timezoneMin > 59 || data.timezoneMin < -59) - throw new RuntimeException("Minute must have values 0-59"); - } + if (data.month < 1 || data.month > 12) { + throw new RuntimeException("The month must have values 1 to 12"); } - /** - * Return index of UTC char: 'Z', '+', '-' - * - * @param start - * @param end - * @return index of the UTC character that was found - */ - protected int findUTCSign (String buffer, int start, int end) { - int c; - for ( int i=start;i<end;i++ ) { - c=buffer.charAt(i); - if ( c == 'Z' || c=='+' || c=='-' ) { - return i; + //validate days + if (data.day > maxDayInMonthFor(data.year, data.month) || data.day < 1) { + throw new RuntimeException("The day must have values 1 to 31"); + } + + //validate hours + if (data.hour > 23 || data.hour < 0) { + if (data.hour == 24 && data.minute == 0 && data.second == 0) { + data.hour = 0; + if (++data.day > maxDayInMonthFor(data.year, data.month)) { + data.day = 1; + if (++data.month > 12) { + data.month = 1; + if (Constants.SCHEMA_1_1_SUPPORT) { + ++data.year; + } else if (++data.year == 0) { + data.year = 1; } - + } } - return -1; + } else { + throw new RuntimeException("Hour must have values 0-23, unless 24:00:00"); + } + } + + //validate + if (data.minute > 59 || data.minute < 0) { + throw new RuntimeException("Minute must have values 0-59"); + } + + //validate + if (data.second >= 60 || data.second < 0) { + throw new RuntimeException("Second must have values 0-59"); + } + //validate + if (data.timezoneHr > 14 || data.timezoneHr < -14) { + throw new RuntimeException("Time zone should have range -14:00 to +14:00"); + } else { + if ((data.timezoneHr == 14 || data.timezoneHr == -14) && data.timezoneMin != 0) { + throw new RuntimeException("Time zone should have range -14:00 to +14:00"); + } else if (data.timezoneMin > 59 || data.timezoneMin < -59) { + throw new RuntimeException("Minute must have values 0-59"); + } + } + + } + /** - * Returns <code>true</code> if the character at start is 'Z', '+' or '-'. + * Return index of UTC char: 'Z', '+', '-' + * + * @param start + * @param end + * @return index of the UTC character that was found + */ + protected int findUTCSign(String buffer, int start, int end) { + int c; + for (int i = start; i < end; i++) { + c = buffer.charAt(i); + if (c == 'Z' || c == '+' || c == '-') { + return i; + } + + } + return -1; + } + + /** + * Returns + * <code>true</code> if the character at start is 'Z', '+' or '-'. */ protected final boolean isNextCharUTCSign(String buffer, int start, int end) { if (start < end) { @@ -510,135 +525,145 @@ return false; } - /** - * Given start and end position, parses string value - * - * @param buffer string to parse - * @param start start position - * @param end end position - * @return return integer representation of characters - */ - protected int parseInt (String buffer, int start, int end) - throws NumberFormatException{ - //REVISIT: more testing on this parsing needs to be done. - int radix=10; - int result = 0; - int digit=0; - int limit = -Integer.MAX_VALUE; - int multmin = limit / radix; - int i = start; - do { - digit = getDigit(buffer.charAt(i)); - if ( digit < 0 ) throw new NumberFormatException("'" + buffer + "' has wrong format"); - if ( result < multmin ) throw new NumberFormatException("'" + buffer + "' has wrong format"); - result *= radix; - if ( result < limit + digit ) throw new NumberFormatException("'" + buffer + "' has wrong format"); - result -= digit; + /** + * Given start and end position, parses string value + * + * @param buffer string to parse + * @param start start position + * @param end end position + * @return return integer representation of characters + */ + protected int parseInt(String buffer, int start, int end) + throws NumberFormatException { + //REVISIT: more testing on this parsing needs to be done. + int radix = 10; + int result = 0; + int digit = 0; + int limit = -Integer.MAX_VALUE; + int multmin = limit / radix; + int i = start; + do { + digit = getDigit(buffer.charAt(i)); + if (digit < 0) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + if (result < multmin) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + result *= radix; + if (result < limit + digit) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + result -= digit; - }while ( ++i < end ); - return -result; + } while (++i < end); + return -result; + } + + // parse Year differently to support negative value. + protected int parseIntYear(String buffer, int end) { + int radix = 10; + int result = 0; + boolean negative = false; + int i = 0; + int limit; + int multmin; + int digit = 0; + + if (buffer.charAt(0) == '-') { + negative = true; + limit = Integer.MIN_VALUE; + i++; + + } else { + limit = -Integer.MAX_VALUE; + } + multmin = limit / radix; + while (i < end) { + digit = getDigit(buffer.charAt(i++)); + if (digit < 0) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + if (result < multmin) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + result *= radix; + if (result < limit + digit) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + result -= digit; } - // parse Year differently to support negative value. - protected int parseIntYear (String buffer, int end){ - int radix=10; - int result = 0; - boolean negative = false; - int i=0; - int limit; - int multmin; - int digit=0; + if (negative) { + if (i > 1) { + return result; + } else { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + } + return -result; - if (buffer.charAt(0) == '-'){ - negative = true; - limit = Integer.MIN_VALUE; - i++; + } + + /** + * If timezone present - normalize dateTime [E Adding durations to + * dateTimes] + * + * @param date CCYY-MM-DDThh:mm:ss+03 + */ + protected void normalize(DateTimeData date) { - } - else{ - limit = -Integer.MAX_VALUE; - } - multmin = limit / radix; - while (i < end) - { - digit = getDigit(buffer.charAt(i++)); - if (digit < 0) throw new NumberFormatException("'" + buffer + "' has wrong format"); - if (result < multmin) throw new NumberFormatException("'" + buffer + "' has wrong format"); - result *= radix; - if (result < limit + digit) throw new NumberFormatException("'" + buffer + "' has wrong format"); - result -= digit; - } + // REVISIT: we have common code in addDuration() for durations + // should consider reorganizing it. + // + + //add minutes (from time zone) + int negate = -1; - if (negative) - { - if (i > 1) return result; - else throw new NumberFormatException("'" + buffer + "' has wrong format"); - } - return -result; + if (DEBUG) { + System.out.println("==>date.minute" + date.minute); + System.out.println("==>date.timezoneMin" + date.timezoneMin); + } + int temp = date.minute + negate * date.timezoneMin; + int carry = fQuotient(temp, 60); + date.minute = mod(temp, 60, carry); + if (DEBUG) { + System.out.println("==>carry: " + carry); + } + //add hours + temp = date.hour + negate * date.timezoneHr + carry; + carry = fQuotient(temp, 24); + date.hour = mod(temp, 24, carry); + if (DEBUG) { + System.out.println("==>date.hour" + date.hour); + System.out.println("==>carry: " + carry); } - /** - * If timezone present - normalize dateTime [E Adding durations to dateTimes] - * - * @param date CCYY-MM-DDThh:mm:ss+03 - */ - protected void normalize(DateTimeData date) { - - // REVISIT: we have common code in addDuration() for durations - // should consider reorganizing it. - // - - //add minutes (from time zone) - int negate = -1; - - if ( DEBUG ) { - System.out.println("==>date.minute"+date.minute); - System.out.println("==>date.timezoneMin" +date.timezoneMin); - } - int temp = date.minute + negate * date.timezoneMin; - int carry = fQuotient (temp, 60); - date.minute= mod(temp, 60, carry); + date.day = date.day + carry; - if ( DEBUG ) { - System.out.println("==>carry: " + carry); - } - //add hours - temp = date.hour + negate * date.timezoneHr + carry; - carry = fQuotient(temp, 24); - date.hour=mod(temp, 24, carry); - if ( DEBUG ) { - System.out.println("==>date.hour"+date.hour); - System.out.println("==>carry: " + carry); - } - - date.day=date.day+carry; + while (true) { + temp = maxDayInMonthFor(date.year, date.month); + if (date.day < 1) { + date.day = date.day + maxDayInMonthFor(date.year, date.month - 1); + carry = -1; + } else if (date.day > temp) { + date.day = date.day - temp; + carry = 1; + } else { + break; + } + temp = date.month + carry; + date.month = modulo(temp, 1, 13); + date.year = date.year + fQuotient(temp, 1, 13); + if (date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) { + date.year = (date.timezoneHr < 0 || date.timezoneMin < 0) ? 1 : -1; + } + } + date.utc = 'Z'; + } - while ( true ) { - temp=maxDayInMonthFor(date.year, date.month); - if (date.day<1) { - date.day = date.day + maxDayInMonthFor(date.year, date.month-1); - carry=-1; - } - else if ( date.day>temp ) { - date.day=date.day-temp; - carry=1; - } - else { - break; - } - temp=date.month+carry; - date.month=modulo(temp, 1, 13); - date.year=date.year+fQuotient(temp, 1, 13); - if(date.year == 0 && !Constants.SCHEMA_1_1_SUPPORT) { - date.year = (date.timezoneHr < 0 || date.timezoneMin < 0)?1:-1; - } - } - date.utc='Z'; - } - - - /** + /** * @param date */ protected void saveUnnormalized(DateTimeData date) { @@ -651,154 +676,149 @@ } /** - * Resets object representation of date/time - * - * @param data date/time object - */ - protected void resetDateObj(DateTimeData data) { - data.year = 0; - data.month = 0; - data.day = 0; - data.hour = 0; - data.minute = 0; - data.second = 0; - data.utc = 0; - data.timezoneHr = 0; - data.timezoneMin = 0; - } + * Resets object representation of date/time + * + * @param data date/time object + */ + protected void resetDateObj(DateTimeData data) { + data.year = 0; + data.month = 0; + data.day = 0; + data.hour = 0; + data.minute = 0; + data.second = 0; + data.utc = 0; + data.timezoneHr = 0; + data.timezoneMin = 0; + } - /** - * Given {year,month} computes maximum - * number of days for given month - * - * @param year - * @param month - * @return integer containg the number of days in a given month - */ - protected int maxDayInMonthFor(int year, int month) { - //validate days - if ( month==4 || month==6 || month==9 || month==11 ) { - return 30; - } - else if ( month==2 ) { - if ( isLeapYear(year) ) { - return 29; - } - else { - return 28; - } - } - else { - return 31; - } + /** + * Given {year,month} computes maximum number of days for given month + * + * @param year + * @param month + * @return integer containg the number of days in a given month + */ + protected int maxDayInMonthFor(int year, int month) { + //validate days + if (month == 4 || month == 6 || month == 9 || month == 11) { + return 30; + } else if (month == 2) { + if (isLeapYear(year)) { + return 29; + } else { + return 28; + } + } else { + return 31; } + } - private boolean isLeapYear(int year) { + private boolean isLeapYear(int year) { - //REVISIT: should we take care about Julian calendar? - return((year%4 == 0) && ((year%100 != 0) || (year%400 == 0))); - } + //REVISIT: should we take care about Julian calendar? + return ((year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0))); + } - // - // help function described in W3C PR Schema [E Adding durations to dateTimes] - // - protected int mod (int a, int b, int quotient) { - //modulo(a, b) = a - fQuotient(a,b)*b - return (a - quotient*b) ; - } + // + // help function described in W3C PR Schema [E Adding durations to dateTimes] + // + protected int mod(int a, int b, int quotient) { + //modulo(a, b) = a - fQuotient(a,b)*b + return (a - quotient * b); + } - // - // help function described in W3C PR Schema [E Adding durations to dateTimes] - // - protected int fQuotient (int a, int b) { + // + // help function described in W3C PR Schema [E Adding durations to dateTimes] + // + protected int fQuotient(int a, int b) { - //fQuotient(a, b) = the greatest integer less than or equal to a/b - return (int)Math.floor((float)a/b); - } + //fQuotient(a, b) = the greatest integer less than or equal to a/b + return (int) Math.floor((float) a / b); + } - // - // help function described in W3C PR Schema [E Adding durations to dateTimes] - // - protected int modulo (int temp, int low, int high) { - //modulo(a - low, high - low) + low - int a = temp - low; - int b = high - low; - return (mod (a, b, fQuotient(a, b)) + low) ; - } + // + // help function described in W3C PR Schema [E Adding durations to dateTimes] + // + protected int modulo(int temp, int low, int high) { + //modulo(a - low, high - low) + low + int a = temp - low; + int b = high - low; + return (mod(a, b, fQuotient(a, b)) + low); + } - // - // help function described in W3C PR Schema [E Adding durations to dateTimes] - // - protected int fQuotient (int temp, int low, int high) { - //fQuotient(a - low, high - low) + // + // help function described in W3C PR Schema [E Adding durations to dateTimes] + // + protected int fQuotient(int temp, int low, int high) { + //fQuotient(a - low, high - low) - return fQuotient(temp - low, high - low); - } - + return fQuotient(temp - low, high - low); + } - protected String dateToString(DateTimeData date) { - StringBuffer message = new StringBuffer(25); - append(message, date.year, 4); - message.append('-'); - append(message, date.month, 2); - message.append('-'); - append(message, date.day, 2); - message.append('T'); - append(message, date.hour, 2); - message.append(':'); - append(message, date.minute, 2); - message.append(':'); - append(message, date.second); - append(message, (char)date.utc, 0); - return message.toString(); - } + protected String dateToString(DateTimeData date) { + StringBuffer message = new StringBuffer(25); + append(message, date.year, 4); + message.append('-'); + append(message, date.month, 2); + message.append('-'); + append(message, date.day, 2); + message.append('T'); + append(message, date.hour, 2); + message.append(':'); + append(message, date.minute, 2); + message.append(':'); + append(message, date.second); + append(message, (char) date.utc, 0); + return message.toString(); + } - protected final void append(StringBuffer message, int value, int nch) { + protected final void append(StringBuffer message, int value, int nch) { if (value == Integer.MIN_VALUE) { message.append(value); return; } - if (value < 0) { - message.append('-'); - value = -value; - } - if (nch == 4) { - if (value < 10) - message.append("000"); - else if (value < 100) - message.append("00"); - else if (value < 1000) - message.append('0'); - message.append(value); - } - else if (nch == 2) { - if (value < 10) - message.append('0'); - message.append(value); - } - else { - if (value != 0) - message.append((char)value); - } + if (value < 0) { + message.append('-'); + value = -value; } - - protected final void append(StringBuffer message, double value) { - if (value < 0) { - message.append('-'); - value = -value; + if (nch == 4) { + if (value < 10) { + message.append("000"); + } else if (value < 100) { + message.append("00"); + } else if (value < 1000) { + message.append('0'); } + message.append(value); + } else if (nch == 2) { if (value < 10) { message.append('0'); } - append2(message, value); + message.append(value); + } else { + if (value != 0) { + message.append((char) value); + } } + } + + protected final void append(StringBuffer message, double value) { + if (value < 0) { + message.append('-'); + value = -value; + } + if (value < 10) { + message.append('0'); + } + append2(message, value); + } protected final void append2(StringBuffer message, double value) { final int intValue = (int) value; if (value == intValue) { message.append(intValue); - } - else { + } else { append3(message, value); } } @@ -815,9 +835,8 @@ // Need to convert from scientific notation of the form // n.nnn...E-N (N >= 4) to a normal decimal value. try { - exp = parseInt(d, eIndex+2, d.length()); - } - // This should never happen. + exp = parseInt(d, eIndex + 2, d.length()); + } // This should never happen. // It's only possible if String.valueOf(double) is broken. catch (Exception e) { message.append(d); @@ -843,14 +862,12 @@ message.append(c); } } - } - else { + } else { // Need to convert from scientific notation of the form // n.nnn...EN (N >= 7) to a normal decimal value. try { - exp = parseInt(d, eIndex+1, d.length()); - } - // This should never happen. + exp = parseInt(d, eIndex + 1, d.length()); + } // This should never happen. // It's only possible if String.valueOf(double) is broken. catch (Exception e) { message.append(d); @@ -873,174 +890,220 @@ } } - protected double parseSecond(String buffer, int start, int end) - throws NumberFormatException { - int dot = -1; - for (int i = start; i < end; i++) { - char ch = buffer.charAt(i); - if (ch == '.') - dot = i; - else if (ch > '9' || ch < '0') - throw new NumberFormatException("'" + buffer + "' has wrong format"); - } - if (dot == -1) { - if (start+2 != end) - throw new NumberFormatException("'" + buffer + "' has wrong format"); - } - else if (start+2 != dot || dot+1 == end) { - throw new NumberFormatException("'" + buffer + "' has wrong format"); - } - return Double.parseDouble(buffer.substring(start, end)); + protected double parseSecond(String buffer, int start, int end) + throws NumberFormatException { + int dot = -1; + for (int i = start; i < end; i++) { + char ch = buffer.charAt(i); + if (ch == '.') { + dot = i; + } else if (ch > '9' || ch < '0') { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } } + if (dot == -1) { + if (start + 2 != end) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + } else if (start + 2 != dot || dot + 1 == end) { + throw new NumberFormatException("'" + buffer + "' has wrong format"); + } + return Double.parseDouble(buffer.substring(start, end)); + } - // - //Private help functions - // + // + //Private help functions + // + private void cloneDate(DateTimeData finalValue, DateTimeData tempDate) { + tempDate.year = finalValue.year; + tempDate.month = finalValue.month; + tempDate.day = finalValue.day; + tempDate.hour = finalValue.hour; + tempDate.minute = finalValue.minute; + tempDate.second = finalValue.second; + tempDate.utc = finalValue.utc; + tempDate.timezoneHr = finalValue.timezoneHr; + tempDate.timezoneMin = finalValue.timezoneMin; + } - private void cloneDate (DateTimeData finalValue, DateTimeData tempDate) { - tempDate.year = finalValue.year; - tempDate.month = finalValue.month; - tempDate.day = finalValue.day; - tempDate.hour = finalValue.hour; - tempDate.minute = finalValue.minute; - tempDate.second = finalValue.second; - tempDate.utc = finalValue.utc; - tempDate.timezoneHr = finalValue.timezoneHr; - tempDate.timezoneMin = finalValue.timezoneMin; - } + /** + * Represents date time data + */ + static final class DateTimeData implements XSDateTime { - /** - * Represents date time data - */ - static final class DateTimeData implements XSDateTime { - int year, month, day, hour, minute, utc; - double second; - int timezoneHr, timezoneMin; + int year, month, day, hour, minute, utc; + double second; + int timezoneHr, timezoneMin; private String originalValue; boolean normalized = true; - int unNormYear; int unNormMonth; int unNormDay; int unNormHour; int unNormMinute; double unNormSecond; + // used for comparisons - to decide the 'interesting' portions of + // a date/time based data type. + int position; + // a pointer to the type that was used go generate this data + // note that this is not the actual simple type, but one of the + // statically created XXXDV objects, so this won't cause any GC problem. + final AbstractDateTimeDV type; + private volatile String canonical; - // used for comparisons - to decide the 'interesting' portions of - // a date/time based data type. - int position; - // a pointer to the type that was used go generate this data - // note that this is not the actual simple type, but one of the - // statically created XXXDV objects, so this won't cause any GC problem. - final AbstractDateTimeDV type; - private String canonical; - public DateTimeData(String originalValue, AbstractDateTimeDV type) { + public DateTimeData(String originalValue, AbstractDateTimeDV type) { this.originalValue = originalValue; - this.type = type; - } - public DateTimeData(int year, int month, int day, int hour, int minute, - double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) { - this.year = year; - this.month = month; - this.day = day; - this.hour = hour; - this.minute = minute; - this.second = second; - this.utc = utc; - this.type = type; + this.type = type; + } + + public DateTimeData(int year, int month, int day, int hour, int minute, + double second, int utc, String originalValue, boolean normalized, AbstractDateTimeDV type) { + this.year = year; + this.month = month; + this.day = day; + this.hour = hour; + this.minute = minute; + this.second = second; + this.utc = utc; + this.type = type; this.originalValue = originalValue; - } - public boolean equals(Object obj) { - if (!(obj instanceof DateTimeData)) - return false; - return type.compareDates(this, (DateTimeData)obj, true)==0; - } - public synchronized String toString() { - if (canonical == null) { - canonical = type.dateToString(this); - } - return canonical; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear() - */ - public int getYears() { - if(type instanceof DurationDV) + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof DateTimeData)) { + return false; + } + return type.compareDates(this, (DateTimeData) obj, true) == 0; + } + + // If two DateTimeData are equals - then they should have the same + // hashcode. This means we need to convert the date to UTC before + // we return its hashcode. + // The DateTimeData is unfortunately mutable - so we cannot + // cache the result of the conversion... + // + @Override + public int hashCode() { + final DateTimeData tempDate = new DateTimeData(null, type); + type.cloneDate(this, tempDate); + type.normalize(tempDate); + return type.dateToString(tempDate).hashCode(); + } + + @Override + public String toString() { + if (canonical == null) { + canonical = type.dateToString(this); + } + return canonical; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getYear() + */ + + @Override + public int getYears() { + if (type instanceof DurationDV) { return 0; - return normalized?year:unNormYear; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth() - */ - public int getMonths() { - if(type instanceof DurationDV) { - return year*12 + month; } - return normalized?month:unNormMonth; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay() - */ - public int getDays() { - if(type instanceof DurationDV) + return normalized ? year : unNormYear; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getMonth() + */ + + @Override + public int getMonths() { + if (type instanceof DurationDV) { + return year * 12 + month; + } + return normalized ? month : unNormMonth; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getDay() + */ + + @Override + public int getDays() { + if (type instanceof DurationDV) { return 0; - return normalized?day:unNormDay; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour() - */ - public int getHours() { - if(type instanceof DurationDV) - return 0; - return normalized?hour:unNormHour; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes() - */ - public int getMinutes() { - if(type instanceof DurationDV) + } + return normalized ? day : unNormDay; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getHour() + */ + + @Override + public int getHours() { + if (type instanceof DurationDV) { return 0; - return normalized?minute:unNormMinute; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds() - */ - public double getSeconds() { - if(type instanceof DurationDV) { - return day*24*60*60 + hour*60*60 + minute*60 + second; + } + return normalized ? hour : unNormHour; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getMinutes() + */ + + @Override + public int getMinutes() { + if (type instanceof DurationDV) { + return 0; + } + return normalized ? minute : unNormMinute; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getSeconds() + */ + + @Override + public double getSeconds() { + if (type instanceof DurationDV) { + return day * 24 * 60 * 60 + hour * 60 * 60 + minute * 60 + second; } - return normalized?second:unNormSecond; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone() - */ - public boolean hasTimeZone() { - return utc != 0; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours() - */ - public int getTimeZoneHours() { - return timezoneHr; - } - /* (non-Javadoc) - * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes() - */ - public int getTimeZoneMinutes() { - return timezoneMin; - } + return normalized ? second : unNormSecond; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#hasTimeZone() + */ + + @Override + public boolean hasTimeZone() { + return utc != 0; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneHours() + */ + + @Override + public int getTimeZoneHours() { + return timezoneHr; + } + /* (non-Javadoc) + * @see org.apache.xerces.xs.datatypes.XSDateTime#getTimeZoneMinutes() + */ + + @Override + public int getTimeZoneMinutes() { + return timezoneMin; + } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getLexicalValue() */ + + @Override public String getLexicalValue() { return originalValue; } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#normalize() */ + + @Override public XSDateTime normalize() { - if(!normalized) { - DateTimeData dt = (DateTimeData)this.clone(); + if (!normalized) { + DateTimeData dt = (DateTimeData) this.clone(); dt.normalized = true; return dt; } @@ -1049,13 +1112,16 @@ /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#isNormalized() */ + + @Override public boolean isNormalized() { return normalized; } + @Override public Object clone() { DateTimeData dt = new DateTimeData(this.year, this.month, this.day, this.hour, - this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type); + this.minute, this.second, this.utc, this.originalValue, this.normalized, this.type); dt.canonical = this.canonical; dt.position = position; dt.timezoneHr = this.timezoneHr; @@ -1072,16 +1138,19 @@ /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getXMLGregorianCalendar() */ + @Override public XMLGregorianCalendar getXMLGregorianCalendar() { return type.getXMLGregorianCalendar(this); } /* (non-Javadoc) * @see org.apache.xerces.xs.datatypes.XSDateTime#getDuration() */ + + @Override public Duration getDuration() { return type.getDuration(this); } - } + } protected XMLGregorianCalendar getXMLGregorianCalendar(DateTimeData data) { return null;
--- a/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DecimalDV.java Tue Sep 17 16:33:44 2013 +0200 @@ -25,6 +25,7 @@ import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException; import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext; +import com.sun.org.apache.xerces.internal.utils.Objects; import com.sun.org.apache.xerces.internal.xs.datatypes.XSDecimal; /** @@ -38,10 +39,12 @@ */ public class DecimalDV extends TypeValidator { + @Override public final short getAllowedFacets(){ return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS); } + @Override public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException { try { return new XDecimal(content); @@ -50,20 +53,23 @@ } } + @Override public final int compare(Object value1, Object value2){ return ((XDecimal)value1).compareTo((XDecimal)value2); } + @Override public final int getTotalDigits(Object value){ return ((XDecimal)value).totalDigits; } + @Override public final int getFractionDigits(Object value){ return ((XDecimal)value).fracDigits; } // Avoid using the heavy-weight java.math.BigDecimal - static class XDecimal implements XSDecimal { + static final class XDecimal implements XSDecimal { // sign: 0 for vlaue 0; 1 for positive values; -1 for negative values int sign = 1; // total digits. >= 1 @@ -216,6 +222,8 @@ integer = true; } + + @Override public boolean equals(Object val) { if (val == this) return true; @@ -232,6 +240,19 @@ return intDigits == oval.intDigits && fracDigits == oval.fracDigits && ivalue.equals(oval.ivalue) && fvalue.equals(oval.fvalue); } + + @Override + public int hashCode() { + int hash = 7; + hash = 17 * hash + this.sign; + if (this.sign == 0) return hash; + hash = 17 * hash + this.intDigits; + hash = 17 * hash + this.fracDigits; + hash = 17 * hash + Objects.hashCode(this.ivalue); + hash = 17 * hash + Objects.hashCode(this.fvalue); + return hash; + } + public int compareTo(XDecimal val) { if (sign != val.sign) return sign > val.sign ? 1 : -1; @@ -248,7 +269,9 @@ ret = fvalue.compareTo(val.fvalue); return ret == 0 ? 0 : (ret > 0 ? 1 : -1); } + private String canonical; + @Override public synchronized String toString() { if (canonical == null) { makeCanonical(); @@ -269,7 +292,7 @@ return; } // for -0.1, total digits is 1, so we need 3 extra spots - StringBuffer buffer = new StringBuffer(totalDigits+3); + final StringBuilder buffer = new StringBuilder(totalDigits+3); if (sign == -1) buffer.append('-'); if (intDigits != 0) @@ -288,6 +311,7 @@ canonical = buffer.toString(); } + @Override public BigDecimal getBigDecimal() { if (sign == 0) { return new BigDecimal(BigInteger.ZERO); @@ -295,6 +319,7 @@ return new BigDecimal(toString()); } + @Override public BigInteger getBigInteger() throws NumberFormatException { if (fracDigits != 0) { throw new NumberFormatException(); @@ -308,6 +333,7 @@ return new BigInteger("-" + ivalue); } + @Override public long getLong() throws NumberFormatException { if (fracDigits != 0) { throw new NumberFormatException(); @@ -321,6 +347,7 @@ return Long.parseLong("-" + ivalue); } + @Override public int getInt() throws NumberFormatException { if (fracDigits != 0) { throw new NumberFormatException(); @@ -334,6 +361,7 @@ return Integer.parseInt("-" + ivalue); } + @Override public short getShort() throws NumberFormatException { if (fracDigits != 0) { throw new NumberFormatException(); @@ -347,6 +375,7 @@ return Short.parseShort("-" + ivalue); } + @Override public byte getByte() throws NumberFormatException { if (fracDigits != 0) { throw new NumberFormatException();
--- a/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/dv/xs/PrecisionDecimalDV.java Tue Sep 17 16:33:44 2013 +0200 @@ -32,7 +32,7 @@ */ class PrecisionDecimalDV extends TypeValidator { - static class XPrecisionDecimal { + static final class XPrecisionDecimal { // sign: 0 for absent; 1 for positive values; -1 for negative values (except in case of INF, -INF) int sign = 1; @@ -144,7 +144,71 @@ totalDigits = intDigits + fracDigits; } + // Construct a canonical String representation of this number + // for the purpose of deriving a hashCode value compliant with + // equals. + // The toString representation will be: + // NaN for NaN, INF for +infinity, -INF for -infinity, 0 for zero, + // and [1-9].[0-9]*[1-9]?(E[1-9][0-9]*)? for other numbers. + private static String canonicalToStringForHashCode(String ivalue, String fvalue, int sign, int pvalue) { + if ("NaN".equals(ivalue)) { + return "NaN"; + } + if ("INF".equals(ivalue)) { + return sign < 0 ? "-INF" : "INF"; + } + final StringBuilder builder = new StringBuilder(); + final int ilen = ivalue.length(); + final int flen0 = fvalue.length(); + int lastNonZero; + for (lastNonZero = flen0; lastNonZero > 0 ; lastNonZero--) { + if (fvalue.charAt(lastNonZero -1 ) != '0') break; + } + final int flen = lastNonZero; + int iStart; + int exponent = pvalue; + for (iStart = 0; iStart < ilen; iStart++) { + if (ivalue.charAt(iStart) != '0') break; + } + int fStart = 0; + if (iStart < ivalue.length()) { + builder.append(sign == -1 ? "-" : ""); + builder.append(ivalue.charAt(iStart)); + iStart++; + } else { + if (flen > 0) { + for (fStart = 0; fStart < flen; fStart++) { + if (fvalue.charAt(fStart) != '0') break; + } + if (fStart < flen) { + builder.append(sign == -1 ? "-" : ""); + builder.append(fvalue.charAt(fStart)); + exponent -= ++fStart; + } else { + return "0"; + } + } else { + return "0"; + } + } + if (iStart < ilen || fStart < flen) { + builder.append('.'); + } + while (iStart < ilen) { + builder.append(ivalue.charAt(iStart++)); + exponent++; + } + while (fStart < flen) { + builder.append(fvalue.charAt(fStart++)); + } + if (exponent != 0) { + builder.append("E").append(exponent); + } + return builder.toString(); + } + + @Override public boolean equals(Object val) { if (val == this) return true; @@ -156,6 +220,20 @@ return this.compareTo(oval) == EQUAL; } + @Override + public int hashCode() { + // There's nothing else we can use easily, because equals could + // return true for widely different representation of the + // same number - and we don't have any canonical representation. + // The problem here is that we must ensure that if two numbers + // are equals then their hash code must also be equals. + // hashCode for 1.01E1 should be the same as hashCode for 0.101E2 + // So we call cannonicalToStringForHashCode - which implements an + // algorithm that invents a normalized string representation + // for this number, and we return a hash for that. + return canonicalToStringForHashCode(ivalue, fvalue, sign, pvalue).hashCode(); + } + /** * @return */ @@ -295,6 +373,7 @@ private String canonical; + @Override public synchronized String toString() { if (canonical == null) { makeCanonical(); @@ -325,6 +404,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.impl.dv.xs.TypeValidator#getAllowedFacets() */ + @Override public short getAllowedFacets() { return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE | XSSimpleTypeDecl.FACET_TOTALDIGITS | XSSimpleTypeDecl.FACET_FRACTIONDIGITS); } @@ -332,6 +412,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.impl.dv.xs.TypeValidator#getActualValue(java.lang.String, com.sun.org.apache.xerces.internal.impl.dv.ValidationContext) */ + @Override public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException { try { @@ -341,18 +422,22 @@ } } + @Override public int compare(Object value1, Object value2) { return ((XPrecisionDecimal)value1).compareTo((XPrecisionDecimal)value2); } + @Override public int getFractionDigits(Object value) { return ((XPrecisionDecimal)value).fracDigits; } + @Override public int getTotalDigits(Object value) { return ((XPrecisionDecimal)value).totalDigits; } + @Override public boolean isIdentical(Object value1, Object value2) { if(!(value2 instanceof XPrecisionDecimal) || !(value1 instanceof XPrecisionDecimal)) return false;
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties Tue Sep 17 16:33:44 2013 +0200 @@ -261,8 +261,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = The external entity reference \"&{0};\" is not permitted in an attribute value. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = The entity \"{0}\" was referenced, but not declared.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_de.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = Externe Entit\u00E4tsreferenz \"&{0};\" ist in einem Attributwert nicht zul\u00E4ssig. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = Entit\u00E4t \"{0}\" wurde referenziert aber nicht deklariert.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_es.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = La referencia de entidad externa \"&{0};\" no est\u00E1 permitida en un valor de atributo. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = Se hizo referencia a la entidad \"{0}\", pero no se declar\u00F3.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_fr.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = La r\u00E9f\u00E9rence d''entit\u00E9 externe \"&{0};\" n''est pas autoris\u00E9e dans une valeur d''attribut. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = L''entit\u00E9 \"{0}\" \u00E9tait r\u00E9f\u00E9renc\u00E9e, mais pas d\u00E9clar\u00E9e.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_it.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = Il riferimento di entit\u00E0 esterna \"&{0};\" non \u00E8 consentito in un valore di attributo. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = L''entit\u00E0 \"{0}\" \u00E8 indicata da un riferimento, ma non \u00E8 dichiarata.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ja.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = \u5916\u90E8\u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\u53C2\u7167\"&{0};\"\u306F\u3001\u5C5E\u6027\u5024\u3067\u306F\u8A31\u53EF\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = \u30A8\u30F3\u30C6\u30A3\u30C6\u30A3\"{0}\"\u304C\u53C2\u7167\u3055\u308C\u3066\u3044\u307E\u3059\u304C\u3001\u5BA3\u8A00\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_ko.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = \uC18D\uC131\uAC12\uC5D0\uC11C\uB294 \uC678\uBD80 \uC5D4\uD2F0\uD2F0 \uCC38\uC870 \"&{0};\"\uC774 \uD5C8\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = \"{0}\" \uC5D4\uD2F0\uD2F0\uAC00 \uCC38\uC870\uB418\uC5C8\uC9C0\uB9CC \uC120\uC5B8\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_pt_BR.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = A refer\u00EAncia da entidade externa \"&{0};\" n\u00E3o \u00E9 permitida em um valor do atributo. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = A entidade \"{0}\" foi referenciada, mas n\u00E3o declarada.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_sv.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = Den externa enhetsreferensen \"&{0};\" till\u00E5ts inte i ett attributv\u00E4rde. - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = Enheten \"{0}\" har refererats, men \u00E4r inte deklarerad.
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_CN.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = \u5C5E\u6027\u503C\u4E2D\u4E0D\u5141\u8BB8\u91C7\u7528\u5916\u90E8\u5B9E\u4F53\u5F15\u7528 \"&{0};\"\u3002 - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = \u5F15\u7528\u4E86\u5B9E\u4F53 \"{0}\", \u4F46\u672A\u58F0\u660E\u5B83\u3002
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages_zh_TW.properties Tue Sep 17 16:33:44 2013 +0200 @@ -289,8 +289,8 @@ # Entity related messages # 3.1 Start-Tags, End-Tags, and Empty-Element Tags ReferenceToExternalEntity = \u5C6C\u6027\u503C\u4E0D\u5141\u8A31\u53C3\u7167\u5916\u90E8\u500B\u9AD4 \"&{0};\"\u3002 - AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed. - AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed. + AccessExternalDTD = External DTD: Failed to read external DTD ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. + AccessExternalEntity = External Entity: Failed to read external document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalDTD property. # 4.1 Character and Entity References EntityNotDeclared = \u53C3\u7167\u4E86\u500B\u9AD4 \"{0}\"\uFF0C\u4F46\u662F\u672A\u5BA3\u544A\u3002
--- a/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/msg/XMLSchemaMessages.properties Tue Sep 17 16:33:44 2013 +0200 @@ -86,7 +86,7 @@ #schema valid (3.X.3) - schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed. + schema_reference.access = schema_reference: Failed to read schema document ''{0}'', because ''{1}'' access is not allowed due to restriction set by the accessExternalSchema property. schema_reference.4 = schema_reference.4: Failed to read schema document ''{0}'', because 1) could not find the document; 2) the document could not be read; 3) the root element of the document is not <xsd:schema>. src-annotation = src-annotation: <annotation> elements can only contain <appinfo> and <documentation> elements, but ''{0}'' was found. src-attribute.1 = src-attribute.1: The properties ''default'' and ''fixed'' cannot both be present in attribute declaration ''{0}''. Use only one of them.
--- a/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java Tue Sep 17 16:33:44 2013 +0200 @@ -54,6 +54,7 @@ import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -218,6 +219,10 @@ protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + /** Property identifier: access to external dtd */ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; @@ -238,8 +243,7 @@ SECURITY_MANAGER, LOCALE, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; // Data @@ -270,7 +274,6 @@ private final CMNodeFactory fNodeFactory = new CMNodeFactory(); //component mgr will be set later private CMBuilder fCMBuilder; private XSDDescription fXSDDescription = new XSDDescription(); - private String faccessExternalDTD = Constants.EXTERNAL_ACCESS_DEFAULT; private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT; private Map fJAXPCache; @@ -466,11 +469,9 @@ fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter()); } } - else if (propertyId.equals(ACCESS_EXTERNAL_DTD)) { - faccessExternalDTD = (String) state; - } - else if (propertyId.equals(ACCESS_EXTERNAL_SCHEMA)) { - faccessExternalSchema = (String) state; + else if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)state; + faccessExternalSchema = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA); } } // setProperty(String, Object) @@ -1066,8 +1067,8 @@ fSchemaHandler.setGenerateSyntheticAnnotations(componentManager.getFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false)); fSchemaHandler.reset(componentManager); - faccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD); - faccessExternalSchema = (String) componentManager.getProperty(ACCESS_EXTERNAL_SCHEMA); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + faccessExternalSchema = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA); } private void initGrammarBucket(){
--- a/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java Tue Sep 17 16:33:44 2013 +0200 @@ -233,11 +233,9 @@ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; - /** property identifier: access external dtd. */ - private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM; @@ -297,8 +295,7 @@ JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; /** Property defaults. */
--- a/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java Tue Sep 17 16:33:44 2013 +0200 @@ -78,6 +78,7 @@ import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; @@ -112,6 +113,7 @@ import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; @@ -223,11 +225,9 @@ protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; - /** property identifier: access external dtd. */ - public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; protected static final boolean DEBUG_NODE_POOL = false; @@ -260,6 +260,7 @@ protected SecurityManager fSecureProcessing = null; private String fAccessExternalSchema; + private String fAccessExternalDTD; // These tables correspond to the symbol spaces defined in the // spec. @@ -2249,6 +2250,13 @@ } } catch (SAXException se) {} + + try { + parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, fAccessExternalDTD); + } catch (SAXNotRecognizedException exc) { + System.err.println("Warning: " + parser.getClass().getName() + ": " + + exc.getMessage()); + } } // If XML names and Namespace URIs are already internalized we // can avoid running them through the SymbolTable. @@ -3580,11 +3588,17 @@ } catch (XMLConfigurationException e) { } - //For Schema validation, the secure feature is set to true by default - fSchemaParser.setProperty(ACCESS_EXTERNAL_DTD, - componentManager.getProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT)); - fAccessExternalSchema = (String) componentManager.getProperty( - ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); + XMLSecurityPropertyManager securityPropertyMgr = (XMLSecurityPropertyManager) + componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + //Passing on the setting to the parser + fSchemaParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, securityPropertyMgr); + + fAccessExternalDTD = securityPropertyMgr.getValue( + XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + + fAccessExternalSchema = securityPropertyMgr.getValue( + XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA); + } // reset(XMLComponentManager)
--- a/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java Tue Sep 17 16:33:44 2013 +0200 @@ -37,6 +37,9 @@ import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer; import com.sun.org.apache.xerces.internal.parsers.DOMParser; import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager.Property; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager.State; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -97,12 +100,17 @@ private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + /** property identifier: access external dtd. */ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; /** Property identifier: access to external schema */ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + private final DOMParser domParser; private final Schema grammar; @@ -117,6 +125,8 @@ /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; + private XMLSecurityPropertyManager fSecurityPropertyMgr; + DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features) throws SAXNotRecognizedException, SAXNotSupportedException { this(dbf, dbfAttrs, features, false); @@ -160,23 +170,27 @@ domParser.setFeature(XINCLUDE_FEATURE, true); } + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + domParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + // If the secure processing feature is on set a security manager. if (secureProcessing) { domParser.setProperty(SECURITY_MANAGER, new SecurityManager()); /** - * By default, secure processing is set, no external access is allowed. - * However, we need to check if it is actively set on the factory since we - * allow the use of the System Property or jaxp.properties to override - * the default value + * If secure processing is explicitly set on the factory, the + * access properties will be set unless the corresponding + * System Properties or jaxp.properties are set */ if (features != null) { Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); if (temp != null) { boolean value = ((Boolean) temp).booleanValue(); - if (value) { - domParser.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + if (value && Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, + State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_SCHEMA, + State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } } } @@ -220,7 +234,7 @@ setFeatures(features); } - // Set attributes + //setAttribute override those that may be set by other means setDocumentBuilderFactoryAttributes(dbfAttrs); // Initial EntityResolver @@ -236,10 +250,6 @@ String feature = (String) entry.getKey(); boolean value = ((Boolean) entry.getValue()).booleanValue(); domParser.setFeature(feature, value); - if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - domParser.setProperty(ACCESS_EXTERNAL_DTD, ""); - domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, ""); - } } } } @@ -279,26 +289,32 @@ // spec when schema validation is enabled domParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); } - } - } else if(JAXP_SCHEMA_SOURCE.equals(name)){ - if( isValidating() ) { - String value=(String)dbfAttrs.get(JAXP_SCHEMA_LANGUAGE); - if(value !=null && W3C_XML_SCHEMA.equals(value)){ - domParser.setProperty(name, val); - }else{ + } + } else if(JAXP_SCHEMA_SOURCE.equals(name)){ + if( isValidating() ) { + String value=(String)dbfAttrs.get(JAXP_SCHEMA_LANGUAGE); + if(value !=null && W3C_XML_SCHEMA.equals(value)){ + domParser.setProperty(name, val); + }else{ throw new IllegalArgumentException( DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "jaxp-order-not-supported", new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE})); - } - } - } else { - // Let Xerces code handle the property - domParser.setProperty(name, val); - } } - } + } + } else { + int index = fSecurityPropertyMgr.getIndex(name); + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)val); + } else { + // Let Xerces code handle the property + domParser.setProperty(name, val); + } + } + } } + } /** * Non-preferred: use the getDOMImplementation() method instead of this
--- a/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java Tue Sep 17 16:33:44 2013 +0200 @@ -36,6 +36,7 @@ import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -92,11 +93,9 @@ private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; - /** property identifier: access external dtd. */ - public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; private final JAXPSAXParser xmlReader; private String schemaLanguage = null; // null means DTD @@ -113,6 +112,8 @@ /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; + private final XMLSecurityPropertyManager fSecurityPropertyMgr; + /** * Create a SAX parser with the associated features * @param features Hashtable of SAX features, may be null @@ -129,8 +130,10 @@ SAXParserImpl(SAXParserFactoryImpl spf, Hashtable features, boolean secureProcessing) throws SAXException { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + // Instantiate a SAXParser directly and not through SAX so that we use the right ClassLoader - xmlReader = new JAXPSAXParser(this); + xmlReader = new JAXPSAXParser(this, fSecurityPropertyMgr); // JAXP "namespaceAware" == SAX Namespaces feature // Note: there is a compatibility problem here with default values: @@ -149,6 +152,8 @@ xmlReader.setFeature0(XINCLUDE_FEATURE, true); } + xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + // If the secure processing feature is on set a security manager. if (secureProcessing) { xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager()); @@ -162,9 +167,12 @@ Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); if (temp != null) { boolean value = ((Boolean) temp).booleanValue(); - if (value) { - xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + if (value && Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + } } } @@ -242,10 +250,6 @@ String feature = (String) entry.getKey(); boolean value = ((Boolean) entry.getValue()).booleanValue(); xmlReader.setFeature0(feature, value); - if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING) && value) { - xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, ""); - xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, ""); - } } } } @@ -394,14 +398,32 @@ private final HashMap fInitFeatures = new HashMap(); private final HashMap fInitProperties = new HashMap(); private final SAXParserImpl fSAXParser; + private XMLSecurityPropertyManager fSecurityPropertyMgr; + public JAXPSAXParser() { - this(null); + this(null, null); } - JAXPSAXParser(SAXParserImpl saxParser) { + JAXPSAXParser(SAXParserImpl saxParser, XMLSecurityPropertyManager spm) { super(); fSAXParser = saxParser; + fSecurityPropertyMgr = spm; + + /** + * This class may be used directly. So initialize the security manager if + * it is null. + */ + if (fSecurityPropertyMgr == null) { + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + try { + super.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + } catch (SAXException e) { + throw new UnsupportedOperationException( + SAXMessageFormatter.formatMessage(fConfiguration.getLocale(), + "property-not-recognized", new Object [] {SECURITY_MANAGER}), e); + } + } } /** @@ -534,14 +556,21 @@ return; } } - if (!fInitProperties.containsKey(name)) { - fInitProperties.put(name, super.getProperty(name)); - } /** Forward property to the schema validator if there is one. **/ if (fSAXParser != null && fSAXParser.fSchemaValidator != null) { setSchemaValidatorProperty(name, value); } - super.setProperty(name, value); + /** Check to see if the property is managed by the property manager **/ + int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(name) : -1; + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + } else { + if (!fInitProperties.containsKey(name)) { + fInitProperties.put(name, super.getProperty(name)); + } + super.setProperty(name, value); + } } public synchronized Object getProperty(String name) @@ -554,6 +583,11 @@ // JAXP 1.2 support return fSAXParser.schemaLanguage; } + int index = (fSecurityPropertyMgr != null) ? fSecurityPropertyMgr.getIndex(name) : -1; + if (index > -1) { + return fSecurityPropertyMgr.getValueByIndex(index); + } + return super.getProperty(name); }
--- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java Tue Sep 17 16:33:44 2013 +0200 @@ -177,11 +177,11 @@ } config.setProperty(SYMBOL_TABLE, fComponentManager.getProperty(SYMBOL_TABLE)); config.setProperty(VALIDATION_MANAGER, fComponentManager.getProperty(VALIDATION_MANAGER)); - config.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); config.setDocumentHandler(fSchemaValidator); config.setDTDHandler(null); config.setDTDContentModelHandler(null); + config.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, + fComponentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER)); fConfiguration = new SoftReference(config); return config; }
--- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java Tue Sep 17 16:33:44 2013 +0200 @@ -53,6 +53,7 @@ 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; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -134,6 +135,10 @@ private static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + // // Data // @@ -675,8 +680,6 @@ spf.setNamespaceAware(true); try { reader = spf.newSAXParser().getXMLReader(); - reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); // If this is a Xerces SAX parser, set the security manager if there is one if (reader instanceof com.sun.org.apache.xerces.internal.parsers.SAXParser) { SecurityManager securityManager = (SecurityManager) fComponentManager.getProperty(SECURITY_MANAGER); @@ -687,8 +690,15 @@ // Ignore the exception if the security manager cannot be set. catch (SAXException exc) {} } - reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); + try { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + fComponentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, + spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD)); + } catch (SAXException exc) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + exc.getMessage()); + } } } catch( Exception e ) { // this is impossible, but better safe than sorry
--- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java Tue Sep 17 16:33:44 2013 +0200 @@ -45,7 +45,7 @@ import com.sun.org.apache.xerces.internal.util.StAXInputSource; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -83,11 +83,10 @@ private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; - /** property identifier: access external dtd. */ - public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; - /** Property identifier: access to external schema */ - public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; // // Data @@ -111,6 +110,9 @@ /** The SecurityManager. */ private SecurityManager fSecurityManager; + /** The Security property manager. */ + private XMLSecurityPropertyManager fSecurityPropertyMgr; + /** The container for the real grammar pool. */ private XMLGrammarPoolWrapper fXMLGrammarPoolWrapper; @@ -120,6 +122,8 @@ * Note the default value (false) is the safe option.. */ private final boolean fUseServicesMechanism; + + public XMLSchemaFactory() { this(true); } @@ -140,13 +144,9 @@ fSecurityManager = new SecurityManager(); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); - //by default, the secure feature is set to true, otherwise the default would have been 'file' - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, accessExternal); - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal); + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + fXMLSchemaLoader.setProperty(XML_SECURITY_PROPERTY_MANAGER, + fSecurityPropertyMgr); } /** @@ -282,6 +282,7 @@ schema = new EmptyXMLSchema(); } propagateFeatures(schema); + propagateProperties(schema); return schema; } @@ -364,10 +365,20 @@ SAXMessageFormatter.formatMessage(null, "jaxp-secureprocessing-feature", null)); } - fSecurityManager = value ? new SecurityManager() : null; + if (value) { + fSecurityManager = new SecurityManager(); + + if (Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + } + } else { + fSecurityManager = null; + } + fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); return; } else if (name.equals(Constants.ORACLE_FEATURE_SERVICE_MECHANISM)) { //in secure mode, let _useServicesMechanism be determined by the constructor @@ -409,7 +420,13 @@ "property-not-supported", new Object [] {name})); } try { - fXMLSchemaLoader.setProperty(name, object); + int index = fSecurityPropertyMgr.getIndex(name); + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)object); + } else { + fXMLSchemaLoader.setProperty(name, object); + } } catch (XMLConfigurationException e) { String identifier = e.getIdentifier();
--- a/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java Tue Sep 17 16:33:44 2013 +0200 @@ -42,6 +42,7 @@ import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; @@ -107,6 +108,10 @@ private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Property identifier: security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + /** Property identifier: symbol table. */ private static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; @@ -123,12 +128,6 @@ private static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; - /** property identifier: access external dtd. */ - private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; - // // Data // @@ -184,6 +183,9 @@ /** Stores the initial security manager. */ private final SecurityManager fInitSecurityManager; + /** Stores the initial security property manager. */ + private final XMLSecurityPropertyManager fSecurityPropertyMgr; + // // User Objects // @@ -250,8 +252,9 @@ fComponents.put(SECURITY_MANAGER, fInitSecurityManager); //pass on properties set on SchemaFactory - setProperty(ACCESS_EXTERNAL_DTD, grammarContainer.getProperty(ACCESS_EXTERNAL_DTD)); - setProperty(ACCESS_EXTERNAL_SCHEMA, grammarContainer.getProperty(ACCESS_EXTERNAL_SCHEMA)); + fSecurityPropertyMgr = (XMLSecurityPropertyManager) + grammarContainer.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER); + setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); } /** @@ -309,6 +312,15 @@ throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING); } setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null); + + if (value && Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + } + return; } fConfigUpdated = true;
--- a/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java Tue Sep 17 16:33:44 2013 +0200 @@ -29,6 +29,7 @@ import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; @@ -74,6 +75,10 @@ protected static final String REPORT_WHITESPACE = Constants.SUN_SCHEMA_FEATURE_PREFIX + Constants.SUN_REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + // recognized features: private static final String[] RECOGNIZED_FEATURES = { REPORT_WHITESPACE @@ -579,6 +584,13 @@ } try { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + fConfiguration.getProperty(XML_SECURITY_PROPERTY_MANAGER); + int index = spm.getIndex(propertyId); + if (index > -1) { + return spm.getValueByIndex(index); + } + return fConfiguration.getProperty(propertyId); } catch (XMLConfigurationException e) {
--- a/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/parsers/DTDConfiguration.java Tue Sep 17 16:33:44 2013 +0200 @@ -38,6 +38,7 @@ import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLLocator; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; @@ -184,6 +185,10 @@ protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Property identifier: Security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -328,7 +333,8 @@ VALIDATION_MANAGER, JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, - LOCALE + LOCALE, + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -406,6 +412,7 @@ // REVISIT: What is the right thing to do? -Ac } + setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); } // <init>(SymbolTable,XMLGrammarPool) //
--- a/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/parsers/NonValidatingConfiguration.java Tue Sep 17 16:33:44 2013 +0200 @@ -36,6 +36,7 @@ import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLLocator; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; @@ -157,6 +158,10 @@ protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; + /** Property identifier: Security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + // debugging /** Set to true and recompile to print exception stack trace. */ @@ -310,7 +315,8 @@ XMLGRAMMAR_POOL, DATATYPE_VALIDATOR_FACTORY, VALIDATION_MANAGER, - LOCALE + LOCALE, + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -367,6 +373,7 @@ // REVISIT: What is the right thing to do? -Ac } + setProperty(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); } // <init>(SymbolTable,XMLGrammarPool) //
--- a/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java Tue Sep 17 16:33:44 2013 +0200 @@ -22,8 +22,11 @@ import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; /** * This is the main Xerces SAX parser class. It uses the abstract SAX @@ -73,6 +76,7 @@ XMLGRAMMAR_POOL, }; + XMLSecurityPropertyManager securityPropertyManager; // // Constructors // @@ -120,4 +124,27 @@ } // <init>(SymbolTable,XMLGrammarPool) + /** + * Sets the particular property in the underlying implementation of + * org.xml.sax.XMLReader. + */ + public void setProperty(String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException { + if (securityPropertyManager == null) { + securityPropertyManager = new XMLSecurityPropertyManager(); + } + int index = securityPropertyManager.getIndex(name); + + if (index > -1) { + /** + * this is a direct call to this parser, not a subclass since + * internally the support of this property is done through + * XMLSecurityPropertyManager + */ + securityPropertyManager.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, securityPropertyManager); + } else { + super.setProperty(name, value); + } + } } // class SAXParser
--- a/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java Tue Sep 17 16:33:44 2013 +0200 @@ -20,12 +20,10 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; -import java.util.Properties; import javax.xml.XMLConstants; import com.sun.org.apache.xerces.internal.impl.Constants; @@ -53,9 +51,8 @@ import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; -import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; @@ -278,11 +275,10 @@ protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; - /** Property identifier: access to external dtd */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; - /** Property identifier: access to external schema */ - protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; // debugging @@ -535,8 +531,7 @@ SCHEMA_NONS_LOCATION, LOCALE, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -584,14 +579,7 @@ fVersionDetector = new XMLVersionDetector(); - //FEATURE_SECURE_PROCESSING is true, see the feature above - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - fProperties.put(ACCESS_EXTERNAL_DTD, accessExternal); - - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - fProperties.put(ACCESS_EXTERNAL_SCHEMA, accessExternal); + fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) {
--- a/src/com/sun/org/apache/xerces/internal/util/URI.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/util/URI.java Tue Sep 17 16:33:44 2013 +0200 @@ -20,6 +20,7 @@ package com.sun.org.apache.xerces.internal.util; +import com.sun.org.apache.xerces.internal.utils.Objects; import java.io.IOException; import java.io.Serializable; @@ -1212,7 +1213,7 @@ * @return the scheme-specific part for this URI */ public String getSchemeSpecificPart() { - StringBuffer schemespec = new StringBuffer(); + final StringBuilder schemespec = new StringBuilder(); if (m_host != null || m_regAuthority != null) { schemespec.append("//"); @@ -1297,7 +1298,7 @@ * @return the authority */ public String getAuthority() { - StringBuffer authority = new StringBuffer(); + final StringBuilder authority = new StringBuilder(); if (m_host != null || m_regAuthority != null) { authority.append("//"); @@ -1340,7 +1341,7 @@ */ public String getPath(boolean p_includeQueryString, boolean p_includeFragment) { - StringBuffer pathString = new StringBuffer(m_path); + final StringBuilder pathString = new StringBuilder(m_path); if (p_includeQueryString && m_queryString != null) { pathString.append('?'); @@ -1683,6 +1684,7 @@ * @return true if p_test is a URI with all values equal to this * URI, false otherwise */ + @Override public boolean equals(Object p_test) { if (p_test instanceof URI) { URI testURI = (URI) p_test; @@ -1711,13 +1713,27 @@ return false; } + @Override + public int hashCode() { + int hash = 5; + hash = 47 * hash + Objects.hashCode(this.m_scheme); + hash = 47 * hash + Objects.hashCode(this.m_userinfo); + hash = 47 * hash + Objects.hashCode(this.m_host); + hash = 47 * hash + this.m_port; + hash = 47 * hash + Objects.hashCode(this.m_path); + hash = 47 * hash + Objects.hashCode(this.m_queryString); + hash = 47 * hash + Objects.hashCode(this.m_fragment); + return hash; + } + /** * Get the URI as a string specification. See RFC 2396 Section 5.2. * * @return the URI string specification */ + @Override public String toString() { - StringBuffer uriSpecString = new StringBuffer(); + final StringBuilder uriSpecString = new StringBuilder(); if (m_scheme != null) { uriSpecString.append(m_scheme);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xerces/internal/utils/Objects.java Tue Sep 17 16:33:44 2013 +0200 @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013 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.utils; + +/** + * Emulate two methods of java.util.Objects. We can't use JDK 7 new APIs in + * JAXP because the jaxp repository is built before the jdk repository. This + * is a temporary solution to simplify backports from JDK 8 to JDK 7. + **/ +public final class Objects { + private Objects() { + throw new IllegalAccessError(); + } + + public static int hashCode(final Object o) { + return o == null ? 0 : o.hashCode(); + } + + public static boolean equals(Object one, Object two) { + return one == two || one != null && one.equals(two); + } + +}
--- a/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java Tue Sep 17 16:33:44 2013 +0200 @@ -223,7 +223,8 @@ * @return the name of the protocol if rejected, null otherwise */ public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException { - if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) { + if (systemId == null || (allowedProtocols != null && + allowedProtocols.equalsIgnoreCase(accessAny))) { return null; } @@ -256,6 +257,9 @@ * @return true if the protocol is in the list */ private static boolean isProtocolAllowed(String protocol, String allowedProtocols) { + if (allowedProtocols == null) { + return false; + } String temp[] = allowedProtocols.split(","); for (String t : temp) { t = t.trim(); @@ -267,18 +271,16 @@ } /** - * Read from $java.home/lib/jaxp.properties for the specified property + * Read JAXP system property in this order: system property, + * $java.home/lib/jaxp.properties if the system property is not specified * * @param propertyId the Id of the property * @return the value of the property */ - public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) { - String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId); + public static String getJAXPSystemProperty(String sysPropertyId) { + String accessExternal = getSystemProperty(sysPropertyId); if (accessExternal == null) { accessExternal = readJAXPProperty(sysPropertyId); - if (accessExternal == null) { - accessExternal = defaultVal; - } } return accessExternal; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java Tue Sep 17 16:33:44 2013 +0200 @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013 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.utils; + +import com.sun.org.apache.xerces.internal.impl.Constants; +import javax.xml.XMLConstants; + +/** + * This class manages security related properties + * + */ +public final class XMLSecurityPropertyManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + } + + /** + * Limits managed by the security manager + */ + public static enum Property { + ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, + Constants.EXTERNAL_ACCESS_DEFAULT), + ACCESS_EXTERNAL_SCHEMA(XMLConstants.ACCESS_EXTERNAL_SCHEMA, + Constants.EXTERNAL_ACCESS_DEFAULT); + + final String name; + final String defaultValue; + + Property(String name, String value) { + this.name = name; + this.defaultValue = value; + } + + public boolean equalsName(String propertyName) { + return (propertyName == null) ? false : name.equals(propertyName); + } + + String defaultValue() { + return defaultValue; + } + } + + /** + * Values of the properties as defined in enum Properties + */ + private final String[] values; + /** + * States of the settings for each property in Properties above + */ + private State[] states = {State.DEFAULT, State.DEFAULT}; + + /** + * Default constructor. Establishes default values + */ + public XMLSecurityPropertyManager() { + values = new String[Property.values().length]; + for (Property property : Property.values()) { + values[property.ordinal()] = property.defaultValue(); + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Set the value for a specific property. + * + * @param property the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(Property property, State state, String value) { + //only update if it shall override + if (state.compareTo(states[property.ordinal()]) >= 0) { + values[property.ordinal()] = value; + states[property.ordinal()] = state; + } + } + + /** + * Set the value of a property by its index + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(int index, State state, String value) { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + } + } + /** + * Return the value of the specified property + * + * @param property the property + * @return the value of the property + */ + public String getValue(Property property) { + return values[property.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * @param index the index of a property + * @return value of a property + */ + public String getValueByIndex(int index) { + return values[index]; + } + + /** + * Get the index by property name + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName){ + for (Property property : Property.values()) { + if (property.equalsName(propertyName)) { + //internally, ordinal is used as index + return property.ordinal(); + } + } + return -1; + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + getSystemProperty(Property.ACCESS_EXTERNAL_DTD, + Constants.SP_ACCESS_EXTERNAL_DTD); + getSystemProperty(Property.ACCESS_EXTERNAL_SCHEMA, + Constants.SP_ACCESS_EXTERNAL_SCHEMA); + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the property + * @param systemProperty the name of the system property + */ + private void getSystemProperty(Property property, String systemProperty) { + try { + String value = SecuritySupport.getSystemProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.SYSTEMPROPERTY; + return; + } + + value = SecuritySupport.readJAXPProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.JAXPDOTPROPERTIES; + } + } catch (NumberFormatException e) { + //invalid setting ignored + } + } +}
--- a/src/com/sun/org/apache/xerces/internal/xinclude/ObjectFactory.java Mon Jun 03 15:27:00 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,553 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed 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.xinclude; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * This class is duplicated for each JAXP subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the JAXP - * API. - * <p> - * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - * <p> - * - */ -final class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** - * Default columns per line. - */ - private static final int DEFAULT_LINE_LENGTH = 80; - - /** cache the contents of the xerces.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXercesProperties = null; - - /*** - * Cache the time stamp of the xerces.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - * <ol> - * <li>query the system property using <code>System.getProperty</code> - * <li>read <code>META-INF/services/<i>factoryId</i></code> file - * <li>use fallback classname - * </ol> - * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - * <ol> - * <li>query the system property using <code>System.getProperty</code> - * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file - * <li>read <code>META-INF/services/<i>factoryId</i></code> file - * <li>use fallback classname - * </ol> - * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xerces.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - if (DEBUG) debugPrintln("debug is on"); - - SecuritySupport ss = SecuritySupport.getInstance(); - ClassLoader cl = findClassLoader(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return newInstance(systemProp, cl, true); - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // JAXP specific change - // always use fallback class to avoid the expense of constantly - // "stat"ing a non-existent "xerces.properties" and jar SPI entry - // see CR 6400863: Expensive creating of SAX parser in Mustang - if (true) { - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } - - // Try to read from propertiesFilename, or $java.home/lib/xerces.properties - String factoryClassName = null; - // no properties file name specified; use $JAVA_HOME/lib/xerces.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXercesProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXercesProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xerces.properties before (or it's outdeated) - fXercesProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXercesProperties.load(fis); - } - } catch (Exception x) { - fXercesProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXercesProperties != null) { - factoryClassName = fXercesProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); - return newInstance(factoryClassName, cl, true); - } - - // Try Jar Service Provider Mechanism - Object provider = findJarServiceProvider(factoryId); - if (provider != null) { - return provider; - } - - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } // createObject(String,String,String):Object - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - throws ConfigurationError - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Figure out which ClassLoader to use for loading the provider - // class. If there is a Context ClassLoader then use it. - ClassLoader context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xerces - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("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); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the package - //restrict the access to package as speicified in java.security policy - SecurityManager security = System.getSecurityManager(); - if (security != null) { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - Class providerClass; - if (cl == null) { - // XXX Use the bootstrap ClassLoader. There is no way to - // load a class using the bootstrap ClassLoader that works - // in both JDK 1.1 and Java 2. However, this should still - // work b/c the following should be true: - // - // (cl == null) iff current ClassLoader == null - // - // Thus Class.forName(String) will use the current - // ClassLoader which will be the bootstrap ClassLoader. - providerClass = Class.forName(className); - } else { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /* - * 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 - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = "META-INF/services/" + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // Read the service provider name in UTF-8 as specified in - // the jar spec. Unfortunately this fails in Microsoft - // VJ++, which does not implement the UTF-8 - // encoding. Theoretically, we should simply let it fail in - // that case, since the JVM is obviously broken if it - // doesn't support such a basic standard. But since there - // are still some users attempting to use VJ++ for - // development, we have dropped in a fallback which makes a - // second attempt using the platform's default encoding. In - // VJ++ this is apparently ASCII, which is a subset of - // UTF-8... and since the strings we'll be reading here are - // also primarily limited to the 7-bit ASCII range (at - // least, in English versions), this should work well - // enough to keep us on the air until we're ready to - // officially decommit from VJ++. [Edited comment from - // jkesselm] - BufferedReader rd; - try { - rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("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; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static final class ConfigurationError - extends Error { - - /** Serialization version. */ - static final long serialVersionUID = 5061904944269807898L; - - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // <init>(String,Exception) - - // - // methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory
--- a/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java Tue Sep 17 16:33:44 2013 +0200 @@ -68,6 +68,8 @@ import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler; import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor; import com.sun.org.apache.xerces.internal.utils.ObjectFactory; +import com.sun.org.apache.xerces.internal.utils.Objects; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; /** * <p> @@ -230,13 +232,9 @@ protected static final String PARSER_SETTINGS = Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; - /** property identifier: access external dtd. */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** access external dtd: file protocol - * For DOM/SAX, the secure feature is set to true by default - */ - final static String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT; + /** property identifier: XML security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; /** Recognized features. */ private static final String[] RECOGNIZED_FEATURES = @@ -292,12 +290,7 @@ protected XMLErrorReporter fErrorReporter; protected XMLEntityResolver fEntityResolver; protected SecurityManager fSecurityManager; - /** - * comma-delimited list of protocols that are allowed for the purpose - * of accessing external dtd or entity references - */ - protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT; - + protected XMLSecurityPropertyManager fSecurityPropertyMgr; // these are needed for text include processing protected XIncludeTextReader fXInclude10TextReader; @@ -390,6 +383,7 @@ // XMLComponent methods + @Override public void reset(XMLComponentManager componentManager) throws XNIException { fNamespaceContext = null; @@ -538,7 +532,8 @@ fSecurityManager = null; } - fAccessExternalDTD = (String)componentManager.getProperty(ACCESS_EXTERNAL_DTD); + fSecurityPropertyMgr = (XMLSecurityPropertyManager) + componentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER); // Get buffer size. try { @@ -597,6 +592,7 @@ * this component. This method may return null if no features * are recognized by this component. */ + @Override public String[] getRecognizedFeatures() { return (String[])(RECOGNIZED_FEATURES.clone()); } // getRecognizedFeatures():String[] @@ -616,6 +612,7 @@ * @throws SAXNotSupportedException The component should not throw * this exception. */ + @Override public void setFeature(String featureId, boolean state) throws XMLConfigurationException { if (featureId.equals(ALLOW_UE_AND_NOTATION_EVENTS)) { @@ -632,6 +629,7 @@ * this component. This method may return null if no properties * are recognized by this component. */ + @Override public String[] getRecognizedProperties() { return (String[])(RECOGNIZED_PROPERTIES.clone()); } // getRecognizedProperties():String[] @@ -651,6 +649,7 @@ * @throws SAXNotSupportedException The component should not throw * this exception. */ + @Override public void setProperty(String propertyId, Object value) throws XMLConfigurationException { if (propertyId.equals(SYMBOL_TABLE)) { @@ -681,11 +680,13 @@ } return; } - if (propertyId.equals(ACCESS_EXTERNAL_DTD)) { - fAccessExternalDTD = (String)value; + if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) { + fSecurityPropertyMgr = (XMLSecurityPropertyManager)value; + if (fChildConfig != null) { - fChildConfig.setProperty(propertyId, value); + fChildConfig.setProperty(XML_SECURITY_PROPERTY_MANAGER, value); } + return; } @@ -719,6 +720,7 @@ * * @since Xerces 2.2.0 */ + @Override public Boolean getFeatureDefault(String featureId) { for (int i = 0; i < RECOGNIZED_FEATURES.length; i++) { if (RECOGNIZED_FEATURES[i].equals(featureId)) { @@ -737,6 +739,7 @@ * * @since Xerces 2.2.0 */ + @Override public Object getPropertyDefault(String propertyId) { for (int i = 0; i < RECOGNIZED_PROPERTIES.length; i++) { if (RECOGNIZED_PROPERTIES[i].equals(propertyId)) { @@ -746,10 +749,12 @@ return null; } // getPropertyDefault(String):Object + @Override public void setDocumentHandler(XMLDocumentHandler handler) { fDocumentHandler = handler; } + @Override public XMLDocumentHandler getDocumentHandler() { return fDocumentHandler; } @@ -764,6 +769,7 @@ * * This event is only passed on to the document handler if this is the root document. */ + @Override public void startDocument( XMLLocator locator, String encoding, @@ -811,6 +817,7 @@ } } + @Override public void xmlDecl( String version, String encoding, @@ -823,6 +830,7 @@ } } + @Override public void doctypeDecl( String rootElement, String publicId, @@ -834,6 +842,7 @@ } } + @Override public void comment(XMLString text, Augmentations augs) throws XNIException { if (!fInDTD) { @@ -850,6 +859,7 @@ } } + @Override public void processingInstruction( String target, XMLString data, @@ -870,6 +880,7 @@ } } + @Override public void startElement( QName element, XMLAttributes attributes, @@ -940,6 +951,7 @@ } } + @Override public void emptyElement( QName element, XMLAttributes attributes, @@ -1021,6 +1033,7 @@ fDepth--; } + @Override public void endElement(QName element, Augmentations augs) throws XNIException { @@ -1066,6 +1079,7 @@ fDepth--; } + @Override public void startGeneralEntity( String name, XMLResourceIdentifier resId, @@ -1084,6 +1098,7 @@ } } + @Override public void textDecl(String version, String encoding, Augmentations augs) throws XNIException { if (fDocumentHandler != null @@ -1092,6 +1107,7 @@ } } + @Override public void endGeneralEntity(String name, Augmentations augs) throws XNIException { if (fDocumentHandler != null @@ -1101,6 +1117,7 @@ } } + @Override public void characters(XMLString text, Augmentations augs) throws XNIException { if (getState() == STATE_NORMAL_PROCESSING) { @@ -1117,6 +1134,7 @@ } } + @Override public void ignorableWhitespace(XMLString text, Augmentations augs) throws XNIException { if (fDocumentHandler != null @@ -1126,6 +1144,7 @@ } } + @Override public void startCDATA(Augmentations augs) throws XNIException { if (fDocumentHandler != null && getState() == STATE_NORMAL_PROCESSING @@ -1134,6 +1153,7 @@ } } + @Override public void endCDATA(Augmentations augs) throws XNIException { if (fDocumentHandler != null && getState() == STATE_NORMAL_PROCESSING @@ -1142,6 +1162,7 @@ } } + @Override public void endDocument(Augmentations augs) throws XNIException { if (isRootDocument()) { if (!fSeenRootElement) { @@ -1153,10 +1174,12 @@ } } + @Override public void setDocumentSource(XMLDocumentSource source) { fDocumentSource = source; } + @Override public XMLDocumentSource getDocumentSource() { return fDocumentSource; } @@ -1168,6 +1191,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#attributeDecl(java.lang.String, java.lang.String, java.lang.String, java.lang.String[], java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void attributeDecl( String elementName, String attributeName, @@ -1194,6 +1218,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#elementDecl(java.lang.String, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void elementDecl( String name, String contentModel, @@ -1207,6 +1232,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endAttlist(com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void endAttlist(Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { fDTDHandler.endAttlist(augmentations); @@ -1216,6 +1242,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endConditional(com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void endConditional(Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { @@ -1226,6 +1253,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endDTD(com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void endDTD(Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { fDTDHandler.endDTD(augmentations); @@ -1236,6 +1264,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endExternalSubset(com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void endExternalSubset(Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { @@ -1246,6 +1275,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#endParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void endParameterEntity(String name, Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { @@ -1256,6 +1286,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#externalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void externalEntityDecl( String name, XMLResourceIdentifier identifier, @@ -1269,6 +1300,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#getDTDSource() */ + @Override public XMLDTDSource getDTDSource() { return fDTDSource; } @@ -1276,6 +1308,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#ignoredCharacters(com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void ignoredCharacters(XMLString text, Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { @@ -1286,6 +1319,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#internalEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.XMLString, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void internalEntityDecl( String name, XMLString text, @@ -1304,6 +1338,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#notationDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void notationDecl( String name, XMLResourceIdentifier identifier, @@ -1318,6 +1353,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#setDTDSource(com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource) */ + @Override public void setDTDSource(XMLDTDSource source) { fDTDSource = source; } @@ -1325,6 +1361,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startAttlist(java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void startAttlist(String elementName, Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { @@ -1335,6 +1372,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startConditional(short, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void startConditional(short type, Augmentations augmentations) throws XNIException { if (fDTDHandler != null) { @@ -1345,6 +1383,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startDTD(com.sun.org.apache.xerces.internal.xni.XMLLocator, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void startDTD(XMLLocator locator, Augmentations augmentations) throws XNIException { fInDTD = true; @@ -1356,6 +1395,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startExternalSubset(com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void startExternalSubset( XMLResourceIdentifier identifier, Augmentations augmentations) @@ -1368,6 +1408,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#startParameterEntity(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void startParameterEntity( String name, XMLResourceIdentifier identifier, @@ -1386,6 +1427,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.XMLDTDHandler#unparsedEntityDecl(java.lang.String, com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier, java.lang.String, com.sun.org.apache.xerces.internal.xni.Augmentations) */ + @Override public void unparsedEntityDecl( String name, XMLResourceIdentifier identifier, @@ -1405,6 +1447,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#getDTDHandler() */ + @Override public XMLDTDHandler getDTDHandler() { return fDTDHandler; } @@ -1412,6 +1455,7 @@ /* (non-Javadoc) * @see com.sun.org.apache.xerces.internal.xni.parser.XMLDTDSource#setDTDHandler(com.sun.org.apache.xerces.internal.xni.XMLDTDHandler) */ + @Override public void setDTDHandler(XMLDTDHandler handler) { fDTDHandler = handler; } @@ -1603,7 +1647,7 @@ if (fErrorReporter != null) fChildConfig.setProperty(ERROR_REPORTER, fErrorReporter); if (fEntityResolver != null) fChildConfig.setProperty(ENTITY_RESOLVER, fEntityResolver); fChildConfig.setProperty(SECURITY_MANAGER, fSecurityManager); - fChildConfig.setProperty(ACCESS_EXTERNAL_DTD, fAccessExternalDTD); + fChildConfig.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); fChildConfig.setProperty(BUFFER_SIZE, new Integer(fBufferSize)); // features must be copied to child configuration @@ -1641,11 +1685,10 @@ fNamespaceContext); ((XPointerHandler)fXPtrProcessor).setProperty(XINCLUDE_FIXUP_BASE_URIS, - new Boolean(fFixupBaseURIs)); + fFixupBaseURIs); ((XPointerHandler)fXPtrProcessor).setProperty( - XINCLUDE_FIXUP_LANGUAGE, - new Boolean (fFixupLanguage)); + XINCLUDE_FIXUP_LANGUAGE, fFixupLanguage); if (fErrorReporter != null) ((XPointerHandler)fXPtrProcessor).setProperty(ERROR_REPORTER, fErrorReporter); @@ -2119,14 +2162,14 @@ /** Check whether the scheme components are equal. */ final String baseScheme = base.getScheme(); final String literalScheme = uri.getScheme(); - if (!isEqual(baseScheme, literalScheme)) { + if (!Objects.equals(baseScheme, literalScheme)) { return relativeURI; } /** Check whether the authority components are equal. */ final String baseAuthority = base.getAuthority(); final String literalAuthority = uri.getAuthority(); - if (!isEqual(baseAuthority, literalAuthority)) { + if (!Objects.equals(baseAuthority, literalAuthority)) { return uri.getSchemeSpecificPart(); } @@ -2139,7 +2182,7 @@ final String literalQuery = uri.getQueryString(); final String literalFragment = uri.getFragment(); if (literalQuery != null || literalFragment != null) { - StringBuffer buffer = new StringBuffer(); + final StringBuilder buffer = new StringBuilder(); if (literalPath != null) { buffer.append(literalPath); } @@ -2650,15 +2693,15 @@ // equals() returns true if two Notations have the same name. // Useful for searching Vectors for notations with the same name + @Override public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj instanceof Notation) { - Notation other = (Notation)obj; - return name.equals(other.name); - } - return false; + return obj == this || obj instanceof Notation + && Objects.equals(name, ((Notation)obj).name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); } // from 4.5.2 @@ -2671,16 +2714,12 @@ public boolean isDuplicate(Object obj) { if (obj != null && obj instanceof Notation) { Notation other = (Notation)obj; - return name.equals(other.name) - && isEqual(publicId, other.publicId) - && isEqual(expandedSystemId, other.expandedSystemId); + return Objects.equals(name, other.name) + && Objects.equals(publicId, other.publicId) + && Objects.equals(expandedSystemId, other.expandedSystemId); } return false; } - - private boolean isEqual(String one, String two) { - return (one == two || (one != null && one.equals(two))); - } } // This is a storage class to hold information about the unparsed entities. @@ -2696,15 +2735,15 @@ // equals() returns true if two UnparsedEntities have the same name. // Useful for searching Vectors for entities with the same name + @Override public boolean equals(Object obj) { - if (obj == null) { - return false; - } - if (obj instanceof UnparsedEntity) { - UnparsedEntity other = (UnparsedEntity)obj; - return name.equals(other.name); - } - return false; + return obj == this || obj instanceof UnparsedEntity + && Objects.equals(name, ((UnparsedEntity)obj).name); + } + + @Override + public int hashCode() { + return Objects.hashCode(name); } // from 4.5.1: @@ -2717,17 +2756,13 @@ public boolean isDuplicate(Object obj) { if (obj != null && obj instanceof UnparsedEntity) { UnparsedEntity other = (UnparsedEntity)obj; - return name.equals(other.name) - && isEqual(publicId, other.publicId) - && isEqual(expandedSystemId, other.expandedSystemId) - && isEqual(notation, other.notation); + return Objects.equals(name, other.name) + && Objects.equals(publicId, other.publicId) + && Objects.equals(expandedSystemId, other.expandedSystemId) + && Objects.equals(notation, other.notation); } return false; } - - private boolean isEqual(String one, String two) { - return (one == two || (one != null && one.equals(two))); - } } // The following methods are used for XML Base processing @@ -2917,17 +2952,13 @@ return httpSource; } - private boolean isEqual(String one, String two) { - return (one == two || (one != null && one.equals(two))); - } - // which ASCII characters need to be escaped - private static boolean gNeedEscaping[] = new boolean[128]; + private static final boolean gNeedEscaping[] = new boolean[128]; // the first hex character if a character needs to be escaped - private static char gAfterEscaping1[] = new char[128]; + private static final char gAfterEscaping1[] = new char[128]; // the second hex character if a character needs to be escaped - private static char gAfterEscaping2[] = new char[128]; - private static char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7', + private static final char gAfterEscaping2[] = new char[128]; + private static final char[] gHexChs = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'}; // initialize the above 3 arrays static { @@ -2957,7 +2988,7 @@ private String escapeHref(String href) { int len = href.length(); int ch; - StringBuffer buffer = new StringBuffer(len*3); + final StringBuilder buffer = new StringBuilder(len*3); // for each character in the href int i = 0;
--- a/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xml/internal/dtm/ref/DTMNodeProxy.java Tue Sep 17 16:33:44 2013 +0200 @@ -24,6 +24,7 @@ import java.util.Vector; +import com.sun.org.apache.xalan.internal.utils.Objects; import com.sun.org.apache.xml.internal.dtm.DTM; import com.sun.org.apache.xml.internal.dtm.DTMDOMException; import com.sun.org.apache.xpath.internal.NodeSet; @@ -141,21 +142,21 @@ * * @return true if the given node has the same handle as this node. */ + @Override public final boolean equals(Object node) { - - try - { - // DTMNodeProxy dtmp = (DTMNodeProxy)node; // return (dtmp.node == this.node); // Patch attributed to Gary L Peskin <garyp@firstech.com> - return equals((Node) node); - } - catch (ClassCastException cce) - { - return false; - } + return node instanceof Node && equals((Node) node); + } + + @Override + public int hashCode() { + int hash = 7; + hash = 29 * hash + Objects.hashCode(this.dtm); + hash = 29 * hash + this.node; + return hash; } /** @@ -181,6 +182,7 @@ * * @see org.w3c.dom.Node */ + @Override public final String getNodeName() { return dtm.getNodeName(node); @@ -199,6 +201,7 @@ * * */ + @Override public final String getTarget() { return dtm.getNodeName(node); @@ -209,6 +212,7 @@ * * @see org.w3c.dom.Node as of DOM Level 2 */ + @Override public final String getLocalName() { return dtm.getLocalName(node); @@ -218,6 +222,7 @@ * @return The prefix for this node. * @see org.w3c.dom.Node as of DOM Level 2 */ + @Override public final String getPrefix() { return dtm.getPrefix(node); @@ -230,6 +235,7 @@ * @throws DOMException * @see org.w3c.dom.Node as of DOM Level 2 -- DTMNodeProxy is read-only */ + @Override public final void setPrefix(String prefix) throws DOMException { throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR); @@ -240,6 +246,7 @@ * * @see org.w3c.dom.Node as of DOM Level 2 */ + @Override public final String getNamespaceURI() { return dtm.getNamespaceURI(node); @@ -277,6 +284,7 @@ * @return false * @see org.w3c.dom.Node as of DOM Level 2 */ + @Override public final boolean isSupported(String feature, String version) { return implementation.hasFeature(feature,version); @@ -290,6 +298,7 @@ * @throws DOMException * @see org.w3c.dom.Node */ + @Override public final String getNodeValue() throws DOMException { return dtm.getNodeValue(node); @@ -312,6 +321,7 @@ * @throws DOMException * @see org.w3c.dom.Node -- DTMNodeProxy is read-only */ + @Override public final void setNodeValue(String nodeValue) throws DOMException { throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR); @@ -322,6 +332,7 @@ * * @see org.w3c.dom.Node */ + @Override public final short getNodeType() { return (short) dtm.getNodeType(node); @@ -332,6 +343,7 @@ * * @see org.w3c.dom.Node */ + @Override public final Node getParentNode() { @@ -361,6 +373,7 @@ * * @see org.w3c.dom.Node */ + @Override public final NodeList getChildNodes() { @@ -377,6 +390,7 @@ * * @see org.w3c.dom.Node */ + @Override public final Node getFirstChild() { @@ -390,6 +404,7 @@ * * @see org.w3c.dom.Node */ + @Override public final Node getLastChild() { @@ -403,6 +418,7 @@ * * @see org.w3c.dom.Node */ + @Override public final Node getPreviousSibling() { @@ -416,6 +432,7 @@ * * @see org.w3c.dom.Node */ + @Override public final Node getNextSibling() { @@ -435,6 +452,7 @@ * * @see org.w3c.dom.Node */ + @Override public final NamedNodeMap getAttributes() { @@ -448,6 +466,7 @@ * @param name * */ + @Override public boolean hasAttribute(String name) { return DTM.NULL != dtm.getAttributeNode(node,null,name); @@ -462,6 +481,7 @@ * * */ + @Override public boolean hasAttributeNS(String namespaceURI, String localName) { return DTM.NULL != dtm.getAttributeNode(node,namespaceURI,localName); @@ -472,6 +492,7 @@ * * @see org.w3c.dom.Node */ + @Override public final Document getOwnerDocument() { // Note that this uses the DOM-compatable version of the call @@ -488,6 +509,7 @@ * @throws DOMException * @see org.w3c.dom.Node -- DTMNodeProxy is read-only */ + @Override public final Node insertBefore(Node newChild, Node refChild) throws DOMException { @@ -504,6 +526,7 @@ * @throws DOMException * @see org.w3c.dom.Node -- DTMNodeProxy is read-only */ + @Override public final Node replaceChild(Node newChild, Node oldChild) throws DOMException { @@ -519,6 +542,7 @@ * @throws DOMException * @see org.w3c.dom.Node -- DTMNodeProxy is read-only */ + @Override public final Node removeChild(Node oldChild) throws DOMException { throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR); @@ -533,6 +557,7 @@ * @throws DOMException * @see org.w3c.dom.Node -- DTMNodeProxy is read-only */ + @Override public final Node appendChild(Node newChild) throws DOMException { throw new DTMDOMException(DOMException.NO_MODIFICATION_ALLOWED_ERR); @@ -543,6 +568,7 @@ * * @see org.w3c.dom.Node */ + @Override public final boolean hasChildNodes() { return (DTM.NULL != dtm.getFirstChild(node)); @@ -555,6 +581,7 @@ * * @see org.w3c.dom.Node -- DTMNodeProxy is read-only */ + @Override public final Node cloneNode(boolean deep) { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -565,6 +592,7 @@ * * @see org.w3c.dom.Document */ + @Override public final DocumentType getDoctype() { return null; @@ -575,6 +603,7 @@ * * @see org.w3c.dom.Document */ + @Override public final DOMImplementation getImplementation() { return implementation; @@ -587,6 +616,7 @@ * * @see org.w3c.dom.Document */ + @Override public final Element getDocumentElement() { int dochandle=dtm.getDocument(); @@ -634,6 +664,7 @@ * @throws DOMException * @see org.w3c.dom.Document */ + @Override public final Element createElement(String tagName) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -644,6 +675,7 @@ * * @see org.w3c.dom.Document */ + @Override public final DocumentFragment createDocumentFragment() { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -656,6 +688,7 @@ * * @see org.w3c.dom.Document */ + @Override public final Text createTextNode(String data) { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -668,6 +701,7 @@ * * @see org.w3c.dom.Document */ + @Override public final Comment createComment(String data) { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -682,6 +716,7 @@ * @throws DOMException * @see org.w3c.dom.Document */ + @Override public final CDATASection createCDATASection(String data) throws DOMException { @@ -698,8 +733,9 @@ * @throws DOMException * @see org.w3c.dom.Document */ + @Override public final ProcessingInstruction createProcessingInstruction( - String target, String data) throws DOMException + String target, String data) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -713,6 +749,7 @@ * @throws DOMException * @see org.w3c.dom.Document */ + @Override public final Attr createAttribute(String name) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -727,6 +764,7 @@ * @throws DOMException * @see org.w3c.dom.Document */ + @Override public final EntityReference createEntityReference(String name) throws DOMException { @@ -739,6 +777,7 @@ * * @see org.w3c.dom.Document */ + @Override public final NodeList getElementsByTagName(String tagname) { Vector listVector = new Vector(); @@ -819,6 +858,7 @@ * @throws DOMException * @see org.w3c.dom.Document as of DOM Level 2 -- DTMNodeProxy is read-only */ + @Override public final Node importNode(Node importedNode, boolean deep) throws DOMException { @@ -835,8 +875,9 @@ * @throws DOMException * @see org.w3c.dom.Document as of DOM Level 2 */ + @Override public final Element createElementNS( - String namespaceURI, String qualifiedName) throws DOMException + String namespaceURI, String qualifiedName) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -851,8 +892,9 @@ * @throws DOMException * @see org.w3c.dom.Document as of DOM Level 2 */ + @Override public final Attr createAttributeNS( - String namespaceURI, String qualifiedName) throws DOMException + String namespaceURI, String qualifiedName) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -865,6 +907,7 @@ * * @see org.w3c.dom.Document as of DOM Level 2 */ + @Override public final NodeList getElementsByTagNameNS(String namespaceURI, String localName) { @@ -952,6 +995,7 @@ * * @see org.w3c.dom.Document as of DOM Level 2 */ + @Override public final Element getElementById(String elementId) { return (Element) dtm.getNode(dtm.getElementById(elementId)); @@ -966,6 +1010,7 @@ * @throws DOMException * @see org.w3c.dom.Text */ + @Override public final Text splitText(int offset) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -978,6 +1023,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final String getData() throws DOMException { return dtm.getNodeValue(node); @@ -990,6 +1036,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final void setData(String data) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1000,6 +1047,7 @@ * * @see org.w3c.dom.CharacterData */ + @Override public final int getLength() { // %OPT% This should do something smarter? @@ -1016,6 +1064,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final String substringData(int offset, int count) throws DOMException { return getData().substring(offset,offset+count); @@ -1028,6 +1077,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final void appendData(String arg) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1041,6 +1091,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final void insertData(int offset, String arg) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1054,6 +1105,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final void deleteData(int offset, int count) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1068,6 +1120,7 @@ * @throws DOMException * @see org.w3c.dom.CharacterData */ + @Override public final void replaceData(int offset, int count, String arg) throws DOMException { @@ -1079,6 +1132,7 @@ * * @see org.w3c.dom.Element */ + @Override public final String getTagName() { return dtm.getNodeName(node); @@ -1091,12 +1145,13 @@ * * @see org.w3c.dom.Element */ + @Override public final String getAttribute(String name) { - DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node); - Node node = map.getNamedItem(name); - return (null == node) ? EMPTYSTRING : node.getNodeValue(); } + Node n = map.getNamedItem(name); + return (null == n) ? EMPTYSTRING : n.getNodeValue(); + } /** * @@ -1106,6 +1161,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final void setAttribute(String name, String value) throws DOMException { @@ -1119,6 +1175,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final void removeAttribute(String name) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1131,9 +1188,9 @@ * * @see org.w3c.dom.Element */ + @Override public final Attr getAttributeNode(String name) { - DTMNamedNodeMap map = new DTMNamedNodeMap(dtm, node); return (Attr)map.getNamedItem(name); } @@ -1147,6 +1204,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final Attr setAttributeNode(Attr newAttr) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1161,6 +1219,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final Attr removeAttributeNode(Attr oldAttr) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1171,12 +1230,14 @@ * * */ + @Override public boolean hasAttributes() { return DTM.NULL != dtm.getFirstAttribute(node); } /** @see org.w3c.dom.Element */ + @Override public final void normalize() { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1190,6 +1251,7 @@ * * @see org.w3c.dom.Element */ + @Override public final String getAttributeNS(String namespaceURI, String localName) { Node retNode = null; @@ -1208,6 +1270,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final void setAttributeNS( String namespaceURI, String qualifiedName, String value) throws DOMException @@ -1223,6 +1286,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final void removeAttributeNS(String namespaceURI, String localName) throws DOMException { @@ -1237,6 +1301,7 @@ * * @see org.w3c.dom.Element */ + @Override public final Attr getAttributeNodeNS(String namespaceURI, String localName) { Attr retAttr = null; @@ -1256,6 +1321,7 @@ * @throws DOMException * @see org.w3c.dom.Element */ + @Override public final Attr setAttributeNodeNS(Attr newAttr) throws DOMException { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1266,6 +1332,7 @@ * * @see org.w3c.dom.Attr */ + @Override public final String getName() { return dtm.getNodeName(node); @@ -1276,6 +1343,7 @@ * * @see org.w3c.dom.Attr */ + @Override public final boolean getSpecified() { // We really don't know which attributes might have come from the @@ -1290,6 +1358,7 @@ * * @see org.w3c.dom.Attr */ + @Override public final String getValue() { return dtm.getNodeValue(node); @@ -1300,6 +1369,7 @@ * @param value * @see org.w3c.dom.Attr */ + @Override public final void setValue(String value) { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1311,6 +1381,7 @@ * * @see org.w3c.dom.Attr as of DOM Level 2 */ + @Override public final Element getOwnerElement() { if (getNodeType() != Node.ATTRIBUTE_NODE) @@ -1331,9 +1402,9 @@ * * @throws DOMException */ + @Override public Node adoptNode(Node source) throws DOMException { - throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -1348,9 +1419,9 @@ * * NEEDSDOC ($objectName$) @return */ + @Override public String getInputEncoding() { - throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -1383,7 +1454,6 @@ */ public boolean getStandalone() { - throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -1418,9 +1488,9 @@ * * NEEDSDOC ($objectName$) @return */ + @Override public boolean getStrictErrorChecking() { - throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -1439,6 +1509,7 @@ * * NEEDSDOC @param strictErrorChecking */ + @Override public void setStrictErrorChecking(boolean strictErrorChecking) { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); @@ -1457,7 +1528,6 @@ */ public String getVersion() { - throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } @@ -1482,10 +1552,12 @@ */ static class DTMNodeProxyImplementation implements DOMImplementation { + @Override public DocumentType createDocumentType(String qualifiedName,String publicId, String systemId) { throw new DTMDOMException(DOMException.NOT_SUPPORTED_ERR); } + @Override public Document createDocument(String namespaceURI,String qualfiedName,DocumentType doctype) { // Could create a DTM... but why, when it'd have to be permanantly empty? @@ -1500,6 +1572,7 @@ * methods we can't support. I'm not sure which would be more useful * to the caller. */ + @Override public boolean hasFeature(String feature,String version) { if( ("CORE".equals(feature.toUpperCase()) || "XML".equals(feature.toUpperCase())) @@ -1530,6 +1603,7 @@ * childNodes, etc. * @since DOM Level 3 */ + @Override public Object getFeature(String feature, String version) { // we don't have any alternate node, either this node does the job // or we don't have anything that does @@ -1542,6 +1616,7 @@ //RAMESH : Pending proper implementation of DOM Level 3 + @Override public Object setUserData(String key, Object data, UserDataHandler handler) { @@ -1557,6 +1632,7 @@ * on this node, or <code>null</code> if there was none. * @since DOM Level 3 */ + @Override public Object getUserData(String key) { return getOwnerDocument().getUserData( key); } @@ -1581,6 +1657,7 @@ * childNodes, etc. * @since DOM Level 3 */ + @Override public Object getFeature(String feature, String version) { // we don't have any alternate node, either this node does the job // or we don't have anything that does @@ -1629,6 +1706,7 @@ * <code>true</code> otherwise <code>false</code>. * @since DOM Level 3 */ + @Override public boolean isEqualNode(Node arg) { if (arg == this) { return true; @@ -1705,6 +1783,7 @@ * @return th URI for the namespace * @since DOM Level 3 */ + @Override public String lookupNamespaceURI(String specifiedPrefix) { short type = this.getNodeType(); switch (type) { @@ -1797,6 +1876,7 @@ * is the default namespace, <code>false</code> otherwise. * @since DOM Level 3 */ + @Override public boolean isDefaultNamespace(String namespaceURI){ /* // REVISIT: remove casts when DOM L3 becomes REC. @@ -1871,6 +1951,7 @@ * @param namespaceURI * @return the prefix for the namespace */ + @Override public String lookupPrefix(String namespaceURI){ // REVISIT: When Namespaces 1.1 comes out this may not be true @@ -1932,6 +2013,7 @@ * <code>false</code> otherwise. * @since DOM Level 3 */ + @Override public boolean isSameNode(Node other) { // we do not use any wrapper so the answer is obvious return this == other; @@ -1980,8 +2062,9 @@ * DOMSTRING_SIZE_ERR: Raised when it would return more characters than * fit in a <code>DOMString</code> variable on the implementation * platform. - * @since DOM Level 3 + * @since DOM Level 3 */ + @Override public void setTextContent(String textContent) throws DOMException { setNodeValue(textContent); @@ -2031,6 +2114,7 @@ * platform. * @since DOM Level 3 */ + @Override public String getTextContent() throws DOMException { return getNodeValue(); // overriden in some subclasses } @@ -2043,6 +2127,7 @@ * node. * @since DOM Level 3 */ + @Override public short compareDocumentPosition(Node other) throws DOMException { return 0; } @@ -2071,14 +2156,16 @@ * Yes. (F2F 26 Sep 2001) * @since DOM Level 3 */ + @Override public String getBaseURI() { return null; } - /** + /** * DOM Level 3 * Renaming node */ + @Override public Node renameNode(Node n, String namespaceURI, String name) @@ -2091,14 +2178,16 @@ * DOM Level 3 * Normalize document. */ + @Override public void normalizeDocument(){ } /** - * The configuration used when <code>Document.normalizeDocument</code> is + * The configuration used when <code>Document.normalizeDocument</code> is * invoked. * @since DOM Level 3 */ + @Override public DOMConfiguration getDomConfig(){ return null; } @@ -2110,8 +2199,8 @@ /** * DOM Level 3 */ + @Override public void setDocumentURI(String documentURI){ - fDocumentURI= documentURI; } @@ -2123,6 +2212,7 @@ * over this attribute. * @since DOM Level 3 */ + @Override public String getDocumentURI(){ return fDocumentURI; } @@ -2154,9 +2244,10 @@ actualEncoding = value; } - /** + /** * DOM Level 3 */ + @Override public Text replaceWholeText(String content) throws DOMException{ /* @@ -2210,6 +2301,7 @@ * nodes to this node, concatenated in document order. * @since DOM Level 3 */ + @Override public String getWholeText(){ /* @@ -2235,13 +2327,11 @@ * Returns whether this text node contains whitespace in element content, * often abusively called "ignorable whitespace". */ + @Override public boolean isElementContentWhitespace(){ return false; } - - - /** * NON-DOM: set the type of this attribute to be ID type. * @@ -2254,6 +2344,7 @@ /** * DOM Level 3: register the given attribute node as an ID attribute */ + @Override public void setIdAttribute(String name, boolean makeId) { //PENDING } @@ -2262,6 +2353,7 @@ /** * DOM Level 3: register the given attribute node as an ID attribute */ + @Override public void setIdAttributeNode(Attr at, boolean makeId) { //PENDING } @@ -2269,6 +2361,7 @@ /** * DOM Level 3: register the given attribute node as an ID attribute */ + @Override public void setIdAttributeNS(String namespaceURI, String localName, boolean makeId) { //PENDING @@ -2277,16 +2370,19 @@ * Method getSchemaTypeInfo. * @return TypeInfo */ + @Override public TypeInfo getSchemaTypeInfo(){ return null; //PENDING } + @Override public boolean isId() { return false; //PENDING } private String xmlEncoding; + @Override public String getXmlEncoding( ) { return xmlEncoding; } @@ -2295,23 +2391,25 @@ } private boolean xmlStandalone; + @Override public boolean getXmlStandalone() { return xmlStandalone; } + @Override public void setXmlStandalone(boolean xmlStandalone) throws DOMException { this.xmlStandalone = xmlStandalone; } private String xmlVersion; + @Override public String getXmlVersion() { return xmlVersion; } + @Override public void setXmlVersion(String xmlVersion) throws DOMException { this.xmlVersion = xmlVersion; } - - }
--- a/src/com/sun/org/apache/xml/internal/serialize/ObjectFactory.java Mon Jun 03 15:27:00 2013 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,553 +0,0 @@ -/* - * reserved comment block - * DO NOT REMOVE OR ALTER! - */ -/* - * Copyright 2001-2005 The Apache Software Foundation. - * - * Licensed 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.xml.internal.serialize; - -import java.io.InputStream; -import java.io.IOException; -import java.io.File; -import java.io.FileInputStream; - -import java.util.Properties; -import java.io.BufferedReader; -import java.io.InputStreamReader; - -/** - * This class is duplicated for each JAXP subpackage so keep it in sync. - * It is package private and therefore is not exposed as part of the JAXP - * API. - * <p> - * This code is designed to implement the JAXP 1.1 spec pluggability - * feature and is designed to run on JDK version 1.1 and - * later, and to compile on JDK 1.2 and onward. - * The code also runs both as part of an unbundled jar file and - * when bundled as part of the JDK. - * <p> - * - */ -final class ObjectFactory { - - // - // Constants - // - - // name of default properties file to look for in JDK's jre/lib directory - private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties"; - - /** Set to true for debugging */ - private static final boolean DEBUG = false; - - /** - * Default columns per line. - */ - private static final int DEFAULT_LINE_LENGTH = 80; - - /** cache the contents of the xerces.properties file. - * Until an attempt has been made to read this file, this will - * be null; if the file does not exist or we encounter some other error - * during the read, this will be empty. - */ - private static Properties fXercesProperties = null; - - /*** - * Cache the time stamp of the xerces.properties file so - * that we know if it's been modified and can invalidate - * the cache when necessary. - */ - private static long fLastModified = -1; - - // - // static methods - // - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - * <ol> - * <li>query the system property using <code>System.getProperty</code> - * <li>read <code>META-INF/services/<i>factoryId</i></code> file - * <li>use fallback classname - * </ol> - * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, String fallbackClassName) - throws ConfigurationError { - return createObject(factoryId, null, fallbackClassName); - } // createObject(String,String):Object - - /** - * Finds the implementation Class object in the specified order. The - * specified order is the following: - * <ol> - * <li>query the system property using <code>System.getProperty</code> - * <li>read <code>$java.home/lib/<i>propertiesFilename</i></code> file - * <li>read <code>META-INF/services/<i>factoryId</i></code> file - * <li>use fallback classname - * </ol> - * - * @return Class object of factory, never null - * - * @param factoryId Name of the factory to find, same as - * a property name - * @param propertiesFilename The filename in the $java.home/lib directory - * of the properties file. If none specified, - * ${java.home}/lib/xerces.properties will be used. - * @param fallbackClassName Implementation class name, if nothing else - * is found. Use null to mean no fallback. - * - * @exception ObjectFactory.ConfigurationError - */ - static Object createObject(String factoryId, - String propertiesFilename, - String fallbackClassName) - throws ConfigurationError - { - if (DEBUG) debugPrintln("debug is on"); - - SecuritySupport ss = SecuritySupport.getInstance(); - ClassLoader cl = findClassLoader(); - - // Use the system property first - try { - String systemProp = ss.getSystemProperty(factoryId); - if (systemProp != null) { - if (DEBUG) debugPrintln("found system property, value=" + systemProp); - return newInstance(systemProp, cl, true); - } - } catch (SecurityException se) { - // Ignore and continue w/ next location - } - - // JAXP specific change - // always use fallback class to avoid the expense of constantly - // "stat"ing a non-existent "xerces.properties" and jar SPI entry - // see CR 6400863: Expensive creating of SAX parser in Mustang - if (true) { - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } - - // Try to read from propertiesFilename, or $java.home/lib/xerces.properties - String factoryClassName = null; - // no properties file name specified; use $JAVA_HOME/lib/xerces.properties: - if (propertiesFilename == null) { - File propertiesFile = null; - boolean propertiesFileExists = false; - try { - String javah = ss.getSystemProperty("java.home"); - propertiesFilename = javah + File.separator + - "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME; - propertiesFile = new File(propertiesFilename); - propertiesFileExists = ss.getFileExists(propertiesFile); - } catch (SecurityException e) { - // try again... - fLastModified = -1; - fXercesProperties = null; - } - - synchronized (ObjectFactory.class) { - boolean loadProperties = false; - FileInputStream fis = null; - try { - // file existed last time - if(fLastModified >= 0) { - if(propertiesFileExists && - (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) { - loadProperties = true; - } else { - // file has stopped existing... - if(!propertiesFileExists) { - fLastModified = -1; - fXercesProperties = null; - } // else, file wasn't modified! - } - } else { - // file has started to exist: - if(propertiesFileExists) { - loadProperties = true; - fLastModified = ss.getLastModified(propertiesFile); - } // else, nothing's changed - } - if(loadProperties) { - // must never have attempted to read xerces.properties before (or it's outdeated) - fXercesProperties = new Properties(); - fis = ss.getFileInputStream(propertiesFile); - fXercesProperties.load(fis); - } - } catch (Exception x) { - fXercesProperties = null; - fLastModified = -1; - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if(fXercesProperties != null) { - factoryClassName = fXercesProperties.getProperty(factoryId); - } - } else { - FileInputStream fis = null; - try { - fis = ss.getFileInputStream(new File(propertiesFilename)); - Properties props = new Properties(); - props.load(fis); - factoryClassName = props.getProperty(factoryId); - } catch (Exception x) { - // assert(x instanceof FileNotFoundException - // || x instanceof SecurityException) - // In both cases, ignore and continue w/ next location - } - finally { - // try to close the input stream if one was opened. - if (fis != null) { - try { - fis.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - } - } - if (factoryClassName != null) { - if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName); - return newInstance(factoryClassName, cl, true); - } - - // Try Jar Service Provider Mechanism - Object provider = findJarServiceProvider(factoryId); - if (provider != null) { - return provider; - } - - if (fallbackClassName == null) { - throw new ConfigurationError( - "Provider for " + factoryId + " cannot be found", null); - } - - if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName); - return newInstance(fallbackClassName, cl, true); - } // createObject(String,String,String):Object - - // - // Private static methods - // - - /** Prints a message to standard error if debugging is enabled. */ - private static void debugPrintln(String msg) { - if (DEBUG) { - System.err.println("JAXP: " + msg); - } - } // debugPrintln(String) - - /** - * Figure out which ClassLoader to use. For JDK 1.2 and later use - * the context ClassLoader. - */ - static ClassLoader findClassLoader() - throws ConfigurationError - { - SecuritySupport ss = SecuritySupport.getInstance(); - - // Figure out which ClassLoader to use for loading the provider - // class. If there is a Context ClassLoader then use it. - ClassLoader context = ss.getContextClassLoader(); - ClassLoader system = ss.getSystemClassLoader(); - - ClassLoader chain = system; - while (true) { - if (context == chain) { - // Assert: we are on JDK 1.1 or we have no Context ClassLoader - // or any Context ClassLoader in chain of system classloader - // (including extension ClassLoader) so extend to widest - // ClassLoader (always look in system ClassLoader if Xerces - // is in boot/extension/system classpath and in current - // ClassLoader otherwise); normal classloaders delegate - // back to system ClassLoader first so this widening doesn't - // change the fact that context ClassLoader will be consulted - ClassLoader current = ObjectFactory.class.getClassLoader(); - - chain = system; - while (true) { - if (current == chain) { - // Assert: Current ClassLoader in chain of - // boot/extension/system ClassLoaders - return system; - } - if (chain == null) { - break; - } - chain = ss.getParentClassLoader(chain); - } - - // Assert: Current ClassLoader not in chain of - // boot/extension/system ClassLoaders - return current; - } - - if (chain == null) { - // boot ClassLoader reached - break; - } - - // Check for any extension ClassLoaders in chain up to - // boot ClassLoader - chain = ss.getParentClassLoader(chain); - }; - - // Assert: Context ClassLoader not in chain of - // boot/extension/system ClassLoaders - return context; - } // findClassLoader():ClassLoader - - /** - * Create an instance of a class using the specified ClassLoader - */ - static Object newInstance(String className, ClassLoader cl, - boolean doFallback) - throws ConfigurationError - { - // assert(className != null); - try{ - Class providerClass = findProviderClass(className, cl, doFallback); - Object instance = providerClass.newInstance(); - if (DEBUG) debugPrintln("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); - } - } - - /** - * Find a Class using the specified ClassLoader - */ - static Class findProviderClass(String className, ClassLoader cl, - boolean doFallback) - throws ClassNotFoundException, ConfigurationError - { - //throw security exception if the calling thread is not allowed to access the package - //restrict the access to package as speicified in java.security policy - SecurityManager security = System.getSecurityManager(); - if (security != null) { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - Class providerClass; - if (cl == null) { - // XXX Use the bootstrap ClassLoader. There is no way to - // load a class using the bootstrap ClassLoader that works - // in both JDK 1.1 and Java 2. However, this should still - // work b/c the following should be true: - // - // (cl == null) iff current ClassLoader == null - // - // Thus Class.forName(String) will use the current - // ClassLoader which will be the bootstrap ClassLoader. - providerClass = Class.forName(className); - } else { - try { - providerClass = cl.loadClass(className); - } catch (ClassNotFoundException x) { - if (doFallback) { - // Fall back to current classloader - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (current == null) { - providerClass = Class.forName(className); - } else if (cl != current) { - cl = current; - providerClass = cl.loadClass(className); - } else { - throw x; - } - } else { - throw x; - } - } - } - - return providerClass; - } - - /* - * 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 - { - SecuritySupport ss = SecuritySupport.getInstance(); - String serviceId = "META-INF/services/" + factoryId; - InputStream is = null; - - // First try the Context ClassLoader - ClassLoader cl = findClassLoader(); - - is = ss.getResourceAsStream(cl, serviceId); - - // If no provider found then try the current ClassLoader - if (is == null) { - ClassLoader current = ObjectFactory.class.getClassLoader(); - if (cl != current) { - cl = current; - is = ss.getResourceAsStream(cl, serviceId); - } - } - - if (is == null) { - // No provider found - return null; - } - - if (DEBUG) debugPrintln("found jar resource=" + serviceId + - " using ClassLoader: " + cl); - - // Read the service provider name in UTF-8 as specified in - // the jar spec. Unfortunately this fails in Microsoft - // VJ++, which does not implement the UTF-8 - // encoding. Theoretically, we should simply let it fail in - // that case, since the JVM is obviously broken if it - // doesn't support such a basic standard. But since there - // are still some users attempting to use VJ++ for - // development, we have dropped in a fallback which makes a - // second attempt using the platform's default encoding. In - // VJ++ this is apparently ASCII, which is a subset of - // UTF-8... and since the strings we'll be reading here are - // also primarily limited to the 7-bit ASCII range (at - // least, in English versions), this should work well - // enough to keep us on the air until we're ready to - // officially decommit from VJ++. [Edited comment from - // jkesselm] - BufferedReader rd; - try { - rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH); - } catch (java.io.UnsupportedEncodingException e) { - rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH); - } - - String factoryClassName = null; - try { - // XXX Does not handle all possible input as specified by the - // Jar Service Provider specification - factoryClassName = rd.readLine(); - } catch (IOException x) { - // No provider found - return null; - } - finally { - try { - // try to close the reader. - rd.close(); - } - // Ignore the exception. - catch (IOException exc) {} - } - - if (factoryClassName != null && - ! "".equals(factoryClassName)) { - if (DEBUG) debugPrintln("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; - } - - // - // Classes - // - - /** - * A configuration error. - */ - static final class ConfigurationError - extends Error { - - /** Serialization version. */ - static final long serialVersionUID = 937647395548533254L; - - // - // Data - // - - /** Exception. */ - private Exception exception; - - // - // Constructors - // - - /** - * Construct a new instance with the specified detail string and - * exception. - */ - ConfigurationError(String msg, Exception x) { - super(msg); - this.exception = x; - } // <init>(String,Exception) - - // - // methods - // - - /** Returns the exception associated to this error. */ - Exception getException() { - return exception; - } // getException():Exception - - } // class ConfigurationError - -} // class ObjectFactory
--- a/src/com/sun/org/apache/xml/internal/serializer/Encodings.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xml/internal/serializer/Encodings.java Tue Sep 17 16:33:44 2013 +0200 @@ -33,6 +33,14 @@ import java.util.HashMap; import java.util.Properties; import java.util.StringTokenizer; +import java.io.IOException; +import java.net.MalformedURLException; +import java.nio.charset.Charset; +import java.nio.charset.IllegalCharsetNameException; +import java.nio.charset.UnsupportedCharsetException; +import java.util.Collections; +import java.util.Map; +import java.util.Map.Entry; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; @@ -79,36 +87,17 @@ throws UnsupportedEncodingException { - for (int i = 0; i < _encodings.length; ++i) - { - if (_encodings[i].name.equalsIgnoreCase(encoding)) - { - try - { - return new BufferedWriter(new OutputStreamWriter( - output, - _encodings[i].javaName)); - } - catch (java.lang.IllegalArgumentException iae) // java 1.1.8 - { - // keep trying - } - catch (UnsupportedEncodingException usee) - { - - // keep trying - } + final EncodingInfo ei = _encodingInfos.findEncoding(toUpperCaseFast(encoding)); + if (ei != null) { + try { + return new BufferedWriter(new OutputStreamWriter( + output, ei.javaName)); + } catch (UnsupportedEncodingException usee) { + // keep trying } } - try - { - return new BufferedWriter(new OutputStreamWriter(output, encoding)); - } - catch (java.lang.IllegalArgumentException iae) // java 1.1.8 - { - throw new UnsupportedEncodingException(encoding); - } + return new BufferedWriter(new OutputStreamWriter(output, encoding)); } @@ -141,12 +130,24 @@ EncodingInfo ei; String normalizedEncoding = toUpperCaseFast(encoding); - ei = (EncodingInfo) _encodingTableKeyJava.get(normalizedEncoding); - if (ei == null) - ei = (EncodingInfo) _encodingTableKeyMime.get(normalizedEncoding); + ei = _encodingInfos.findEncoding(normalizedEncoding); if (ei == null) { // We shouldn't have to do this, but just in case. - ei = new EncodingInfo(null,null); + try { + // This may happen if the caller tries to use + // an encoding that wasn't registered in the + // (java name)->(preferred mime name) mapping file. + // In that case we attempt to load the charset for the + // given encoding, and if that succeeds - we create a new + // EncodingInfo instance - assuming the canonical name + // of the charset can be used as the mime name. + final Charset c = Charset.forName(encoding); + final String name = c.name(); + ei = new EncodingInfo(name, name); + _encodingInfos.putEncoding(normalizedEncoding, ei); + } catch (IllegalCharsetNameException | UnsupportedCharsetException x) { + ei = new EncodingInfo(null,null); + } } return ei; @@ -269,8 +270,8 @@ */ private static String convertJava2MimeEncoding(String encoding) { - EncodingInfo enc = - (EncodingInfo) _encodingTableKeyJava.get(encoding.toUpperCase()); + final EncodingInfo enc = + _encodingInfos.getEncodingFromJavaKey(toUpperCaseFast(encoding)); if (null != enc) return enc.name; return encoding; @@ -285,38 +286,37 @@ */ public static String convertMime2JavaEncoding(String encoding) { - - for (int i = 0; i < _encodings.length; ++i) - { - if (_encodings[i].name.equalsIgnoreCase(encoding)) - { - return _encodings[i].javaName; - } - } - - return encoding; + final EncodingInfo info = _encodingInfos.findEncoding(toUpperCaseFast(encoding)); + return info != null ? info.javaName : encoding; } - /** - * Load a list of all the supported encodings. - * - * System property "encodings" formatted using URL syntax may define an - * external encodings list. Thanks to Sergey Ushakov for the code - * contribution! - */ - private static EncodingInfo[] loadEncodingInfo() - { - try - { + // Using an inner static class here prevent initialization races + // where the hash maps could be used before they were populated. + // + private final static class EncodingInfos { + // These maps are final and not modified after initialization. + private final Map<String, EncodingInfo> _encodingTableKeyJava = new HashMap<>(); + private final Map<String, EncodingInfo> _encodingTableKeyMime = new HashMap<>(); + // This map will be added to after initialization: make sure it's + // thread-safe. This map should not be used frequently - only in cases + // where the mapping requested was not declared in the Encodings.properties + // file. + private final Map<String, EncodingInfo> _encodingDynamicTable = + Collections.synchronizedMap(new HashMap<String, EncodingInfo>()); + + private EncodingInfos() { + loadEncodingInfo(); + } + + // Opens the file/resource containing java charset name -> preferred mime + // name mapping and returns it as an InputStream. + private InputStream openEncodingsFileStream() throws MalformedURLException, IOException { String urlString = null; InputStream is = null; - try - { + try { urlString = SecuritySupport.getSystemProperty(ENCODINGS_PROP, ""); - } - catch (SecurityException e) - { + } catch (SecurityException e) { } if (urlString != null && urlString.length() > 0) { @@ -327,84 +327,193 @@ if (is == null) { is = SecuritySupport.getResourceAsStream(ENCODINGS_FILE); } + return is; + } + // Loads the Properties resource containing the mapping: + // java charset name -> preferred mime name + // and returns it. + private Properties loadProperties() throws MalformedURLException, IOException { Properties props = new Properties(); - if (is != null) { - props.load(is); - is.close(); - } else { - // Seems to be no real need to force failure here, let the - // system do its best... The issue is not really very critical, - // and the output will be in any case _correct_ though maybe not - // always human-friendly... :) - // But maybe report/log the resource problem? - // Any standard ways to report/log errors (in static context)? + final InputStream is = openEncodingsFileStream(); + try { + if (is != null) { + props.load(is); + } else { + // Seems to be no real need to force failure here, let the + // system do its best... The issue is not really very critical, + // and the output will be in any case _correct_ though maybe not + // always human-friendly... :) + // But maybe report/log the resource problem? + // Any standard ways to report/log errors (in static context)? + } + } finally { + if (is != null) { + is.close(); + } } + return props; + } - int totalEntries = props.size(); - int totalMimeNames = 0; - Enumeration keys = props.keys(); - for (int i = 0; i < totalEntries; ++i) - { - String javaName = (String) keys.nextElement(); - String val = props.getProperty(javaName); - totalMimeNames++; - int pos = val.indexOf(' '); - for (int j = 0; j < pos; ++j) - if (val.charAt(j) == ',') - totalMimeNames++; + // Parses the mime list associated to a java charset name. + // The first mime name in the list is supposed to be the preferred + // mime name. + private String[] parseMimeTypes(String val) { + int pos = val.indexOf(' '); + //int lastPrintable; + if (pos < 0) { + // Maybe report/log this problem? + // "Last printable character not defined for encoding " + + // mimeName + " (" + val + ")" ... + return new String[] { val }; + //lastPrintable = 0x00FF; + } + //lastPrintable = + // Integer.decode(val.substring(pos).trim()).intValue(); + StringTokenizer st = + new StringTokenizer(val.substring(0, pos), ","); + String[] values = new String[st.countTokens()]; + for (int i=0; st.hasMoreTokens(); i++) { + values[i] = st.nextToken(); + } + return values; + } + + // This method here attempts to find the canonical charset name for the + // the given name - which is supposed to be either a java name or a mime + // name. + // For that, it attempts to load the charset using the given name, and + // then returns the charset's canonical name. + // If the charset could not be loaded from the given name, + // the method returns null. + private String findCharsetNameFor(String name) { + try { + return Charset.forName(name).name(); + } catch (Exception x) { + return null; } - EncodingInfo[] ret = new EncodingInfo[totalMimeNames]; - int j = 0; - keys = props.keys(); - for (int i = 0; i < totalEntries; ++i) - { - String javaName = (String) keys.nextElement(); - String val = props.getProperty(javaName); - int pos = val.indexOf(' '); - String mimeName; - //int lastPrintable; - if (pos < 0) - { - // Maybe report/log this problem? - // "Last printable character not defined for encoding " + - // mimeName + " (" + val + ")" ... - mimeName = val; - //lastPrintable = 0x00FF; - } - else - { - //lastPrintable = - // Integer.decode(val.substring(pos).trim()).intValue(); - StringTokenizer st = - new StringTokenizer(val.substring(0, pos), ","); - for (boolean first = true; - st.hasMoreTokens(); - first = false) - { - mimeName = st.nextToken(); - ret[j] = - new EncodingInfo(mimeName, javaName); - _encodingTableKeyMime.put( - mimeName.toUpperCase(), - ret[j]); - if (first) - _encodingTableKeyJava.put( - javaName.toUpperCase(), - ret[j]); - j++; + } + + // This method here attempts to find the canonical charset name for the + // the set javaName+mimeNames - which are supposed to all refer to the + // same charset. + // For that it attempts to load the charset using the javaName, and if + // not found, attempts again using each of the mime names in turn. + // If the charset could be loaded from the javaName, then the javaName + // itself is returned as charset name. Otherwise, each of the mime names + // is tried in turn, until a charset can be loaded from one of the names, + // and the loaded charset's canonical name is returned. + // If no charset can be loaded from either the javaName or one of the + // mime names, then null is returned. + // + // Note that the returned name is the 'java' name that will be used in + // instances of EncodingInfo. + // This is important because EncodingInfo uses that 'java name' later on + // in calls to String.getBytes(javaName). + // As it happens, sometimes only one element of the set mime names/javaName + // is known by Charset: sometimes only one of the mime names is known, + // sometime only the javaName is known, sometimes all are known. + // + // By using this method here, we fix the problem where one of the mime + // names is known but the javaName is unknown, by associating the charset + // loaded from one of the mime names with the unrecognized javaName. + // + // When none of the mime names or javaName are known - there's not much we can + // do... It can mean that this encoding is not supported for this + // OS. If such a charset is ever use it will result in having all characters + // escaped. + // + private String findCharsetNameFor(String javaName, String[] mimes) { + String cs = findCharsetNameFor(javaName); + if (cs != null) return javaName; + for (String m : mimes) { + cs = findCharsetNameFor(m); + if (cs != null) break; + } + return cs; + } + + /** + * Loads a list of all the supported encodings. + * + * System property "encodings" formatted using URL syntax may define an + * external encodings list. Thanks to Sergey Ushakov for the code + * contribution! + */ + private void loadEncodingInfo() { + try { + // load (java name)->(preferred mime name) mapping. + final Properties props = loadProperties(); + + // create instances of EncodingInfo from the loaded mapping + Enumeration keys = props.keys(); + Map<String, EncodingInfo> canonicals = new HashMap<>(); + while (keys.hasMoreElements()) { + final String javaName = (String) keys.nextElement(); + final String[] mimes = parseMimeTypes(props.getProperty(javaName)); + + final String charsetName = findCharsetNameFor(javaName, mimes); + if (charsetName != null) { + final String kj = toUpperCaseFast(javaName); + final String kc = toUpperCaseFast(charsetName); + for (int i = 0; i < mimes.length; ++i) { + final String mimeName = mimes[i]; + final String km = toUpperCaseFast(mimeName); + EncodingInfo info = new EncodingInfo(mimeName, charsetName); + _encodingTableKeyMime.put(km, info); + if (!canonicals.containsKey(kc)) { + // canonicals will map the charset name to + // the info containing the prefered mime name + // (the preferred mime name is the first mime + // name in the list). + canonicals.put(kc, info); + _encodingTableKeyJava.put(kc, info); + } + _encodingTableKeyJava.put(kj, info); + } + } else { + // None of the java or mime names on the line were + // recognized => this charset is not supported? } } + + // Fix up the _encodingTableKeyJava so that the info mapped to + // the java name contains the preferred mime name. + // (a given java name can correspond to several mime name, + // but we want the _encodingTableKeyJava to point to the + // preferred mime name). + for (Entry<String, EncodingInfo> e : _encodingTableKeyJava.entrySet()) { + e.setValue(canonicals.get(toUpperCaseFast(e.getValue().javaName))); + } + + } catch (java.net.MalformedURLException mue) { + throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(mue); + } catch (java.io.IOException ioe) { + throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(ioe); } - return ret; } - catch (java.net.MalformedURLException mue) - { - throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(mue); + + EncodingInfo findEncoding(String normalizedEncoding) { + EncodingInfo info = _encodingTableKeyJava.get(normalizedEncoding); + if (info == null) { + info = _encodingTableKeyMime.get(normalizedEncoding); + } + if (info == null) { + info = _encodingDynamicTable.get(normalizedEncoding); + } + return info; } - catch (java.io.IOException ioe) - { - throw new com.sun.org.apache.xml.internal.serializer.utils.WrappedRuntimeException(ioe); + + EncodingInfo getEncodingFromMimeKey(String normalizedMimeName) { + return _encodingTableKeyMime.get(normalizedMimeName); + } + + EncodingInfo getEncodingFromJavaKey(String normalizedJavaName) { + return _encodingTableKeyJava.get(normalizedJavaName); + } + + void putEncoding(String key, EncodingInfo info) { + _encodingDynamicTable.put(key, info); } } @@ -457,7 +566,6 @@ return codePoint; } - private static final HashMap _encodingTableKeyJava = new HashMap(); - private static final HashMap _encodingTableKeyMime = new HashMap(); - private static final EncodingInfo[] _encodings = loadEncodingInfo(); + private final static EncodingInfos _encodingInfos = new EncodingInfos(); + }
--- a/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xml/internal/serializer/utils/URI.java Tue Sep 17 16:33:44 2013 +0200 @@ -22,8 +22,8 @@ */ package com.sun.org.apache.xml.internal.serializer.utils; +import com.sun.org.apache.xalan.internal.utils.Objects; import java.io.IOException; -import java.io.Serializable; /** @@ -863,7 +863,7 @@ public String getSchemeSpecificPart() { - StringBuffer schemespec = new StringBuffer(); + final StringBuilder schemespec = new StringBuilder(); if (m_userinfo != null || m_host != null || m_port != -1) { @@ -955,7 +955,7 @@ boolean p_includeFragment) { - StringBuffer pathString = new StringBuffer(m_path); + final StringBuilder pathString = new StringBuilder(m_path); if (p_includeQueryString && m_queryString != null) { @@ -1321,6 +1321,7 @@ * @return true if p_test is a URI with all values equal to this * URI, false otherwise */ + @Override public boolean equals(Object p_test) { @@ -1343,15 +1344,29 @@ return false; } + @Override + public int hashCode() { + int hash = 5; + hash = 41 * hash + Objects.hashCode(this.m_scheme); + hash = 41 * hash + Objects.hashCode(this.m_userinfo); + hash = 41 * hash + Objects.hashCode(this.m_host); + hash = 41 * hash + this.m_port; + hash = 41 * hash + Objects.hashCode(this.m_path); + hash = 41 * hash + Objects.hashCode(this.m_queryString); + hash = 41 * hash + Objects.hashCode(this.m_fragment); + return hash; + } + /** * Get the URI as a string specification. See RFC 2396 Section 5.2. * * @return the URI string specification */ + @Override public String toString() { - StringBuffer uriSpecString = new StringBuffer(); + final StringBuilder uriSpecString = new StringBuilder(); if (m_scheme != null) { @@ -1543,7 +1558,7 @@ * * * @param p_char the character to check - * @return true if the char is betweeen '0' and '9', 'a' and 'f' + * @return true if the char is between '0' and '9', 'a' and 'f' * or 'A' and 'F', false otherwise */ private static boolean isHex(char p_char)
--- a/src/com/sun/org/apache/xml/internal/utils/URI.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xml/internal/utils/URI.java Tue Sep 17 16:33:44 2013 +0200 @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.Serializable; +import com.sun.org.apache.xalan.internal.utils.Objects; import com.sun.org.apache.xml.internal.res.XMLErrorResources; import com.sun.org.apache.xml.internal.res.XMLMessages; @@ -883,7 +884,7 @@ public String getSchemeSpecificPart() { - StringBuffer schemespec = new StringBuffer(); + final StringBuilder schemespec = new StringBuilder(); if (m_userinfo != null || m_host != null || m_port != -1) { @@ -975,7 +976,7 @@ boolean p_includeFragment) { - StringBuffer pathString = new StringBuffer(m_path); + final StringBuilder pathString = new StringBuilder(m_path); if (p_includeQueryString && m_queryString != null) { @@ -1341,6 +1342,7 @@ * @return true if p_test is a URI with all values equal to this * URI, false otherwise */ + @Override public boolean equals(Object p_test) { @@ -1363,15 +1365,29 @@ return false; } + @Override + public int hashCode() { + int hash = 7; + hash = 59 * hash + Objects.hashCode(this.m_scheme); + hash = 59 * hash + Objects.hashCode(this.m_userinfo); + hash = 59 * hash + Objects.hashCode(this.m_host); + hash = 59 * hash + this.m_port; + hash = 59 * hash + Objects.hashCode(this.m_path); + hash = 59 * hash + Objects.hashCode(this.m_queryString); + hash = 59 * hash + Objects.hashCode(this.m_fragment); + return hash; + } + /** * Get the URI as a string specification. See RFC 2396 Section 5.2. * * @return the URI string specification */ + @Override public String toString() { - StringBuffer uriSpecString = new StringBuffer(); + final StringBuilder uriSpecString = new StringBuilder(); if (m_scheme != null) {
--- a/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java Tue Sep 17 16:33:44 2013 +0200 @@ -136,7 +136,6 @@ try { reader.setFeature(NAMESPACES_FEATURE, true); reader.setFeature(NAMESPACE_PREFIXES_FEATURE, false); - reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); } catch (SAXException se) { // Try to carry on if we've got a parser that // doesn't know about namespace prefixes. @@ -157,6 +156,14 @@ } } + try { + //reader is cached, but this property might have been reset + reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } + return reader; }
--- a/src/com/sun/org/apache/xpath/internal/Arg.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/com/sun/org/apache/xpath/internal/Arg.java Tue Sep 17 16:33:44 2013 +0200 @@ -22,6 +22,7 @@ */ package com.sun.org.apache.xpath.internal; +import com.sun.org.apache.xalan.internal.utils.Objects; import com.sun.org.apache.xml.internal.utils.QName; import com.sun.org.apache.xpath.internal.objects.XObject; @@ -182,7 +183,7 @@ { m_qname = new QName(""); - ; // so that string compares can be done. + // so that string compares can be done. m_val = null; m_expression = null; m_isVisible = true; @@ -223,6 +224,11 @@ m_expression = null; } + @Override + public int hashCode() { + return Objects.hashCode(this.m_qname); + } + /** * Equality function specialized for the variable name. If the argument * is not a qname, it will deligate to the super class. @@ -231,6 +237,7 @@ * @return <code>true</code> if this object is the same as the obj * argument; <code>false</code> otherwise. */ + @Override public boolean equals(Object obj) { if(obj instanceof QName)
--- a/src/org/xml/sax/helpers/XMLReaderFactory.java Mon Jun 03 15:27:00 2013 +0200 +++ b/src/org/xml/sax/helpers/XMLReaderFactory.java Tue Sep 17 16:33:44 2013 +0200 @@ -85,6 +85,7 @@ private static final String property = "org.xml.sax.driver"; private static SecuritySupport ss = new SecuritySupport(); + private static String _clsFromJar = null; private static boolean _jarread = false; /** * Attempt to create an XMLReader from system defaults. @@ -163,14 +164,14 @@ } if (in != null) { - reader = new BufferedReader ( - new InputStreamReader (in, "UTF8")); - className = reader.readLine (); + reader = new BufferedReader (new InputStreamReader (in, "UTF8")); + _clsFromJar = reader.readLine (); in.close (); } } catch (Exception e) { } } + className = _clsFromJar; } // 3. Distro-specific fallback