com.sun.xml.wss.impl.c14n.BaseCanonicalizer Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of webservices-rt Show documentation
Show all versions of webservices-rt Show documentation
This module contains the Metro runtime code.
/*
* Copyright (c) 1997, 2018 Oracle and/or its affiliates. All rights reserved.
* Copyright 1995-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.xml.wss.impl.c14n;
import com.sun.xml.wss.impl.misc.UnsyncByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Stack;
import javax.xml.XMLConstants;
import org.xml.sax.Attributes;
/**
*
* @author Apache
* @author [email protected]
* //TODO:
* Refactor code ..
*/
public abstract class BaseCanonicalizer {
//extends DefaultHandler2 {
static final byte[] _END_PI = {'?','>'};
static final byte[] _BEGIN_PI = {'<','?'};
static final byte[] _END_COMM = {'-','-','>'};
static final byte[] _BEGIN_COMM = {'<','!','-','-'};
static final byte[] __XA_ = {'&','#','x','A',';'};
static final byte[] __X9_ = {'&','#','x','9',';'};
static final byte[] _QUOT_ = {'&','q','u','o','t',';'};
static final byte[] __XD_ = {'&','#','x','D',';'};
static final byte[] _GT_ = {'&','g','t',';'};
static final byte[] _LT_ = {'&','l','t',';'};
static final byte[] _END_TAG = {'<','/'};
static final byte[] _AMP_ = {'&','a','m','p',';'};
final static String XML="xml";
final static String XMLNS="xmlns";
final static byte[] equalsStr= {'=','\"'};
static final int NODE_BEFORE_DOCUMENT_ELEMENT = -1;
static final int NODE_NOT_BEFORE_OR_AFTER_DOCUMENT_ELEMENT = 0;
static final int NODE_AFTER_DOCUMENT_ELEMENT = 1;
protected ArrayList _attrs = new ArrayList();
protected ArrayList _nsAttrs = new ArrayList();
int _attrPos = 0;
int _attrNSPos = 0;
protected List _attrResult = null;
//protected SortedSet _nsResult = new TreeSet(new AttrSorter(true));
protected List _nsResult = new ArrayList();
String _defURI = null;
OutputStream _stream = null;
boolean [] _ncContextState = new boolean [20];
StringBuffer _attrName = new StringBuffer();
int _depth = 0;
protected static final int initalCacheSize = 4;
boolean _parentNamespacesAdded = false;
//List _parentNamespaces = null;
String _elementPrefix = "";
private static boolean debug = false;
/** Creates a new instance of BaseCanonicalizer */
public BaseCanonicalizer() {
}
public void reset(){
_nsResult.clear();
_attrResult.clear();
_attrPos =0;
_depth =0;
_parentNamespacesAdded = false;
}
public void setStream(OutputStream os){
this._stream = os;
}
public OutputStream getOutputStream(){
return this._stream;
}
protected final void resize(){
if(_depth >= _ncContextState.length ){
boolean []tmp = new boolean[_ncContextState.length+20];
System.arraycopy(_ncContextState,0,tmp,0,_ncContextState.length);
_ncContextState = tmp;
}
}
@SuppressWarnings("unchecked")
public void addParentNamespaces(List nsDecls){
if(!_parentNamespacesAdded){
//_parentNamespaces = nsDecls;
_nsResult.addAll(nsDecls);
_parentNamespacesAdded = true;
}
}
@SuppressWarnings("unchecked")
protected AttributeNS getAttributeNS(){
if(_attrNSPos < _nsAttrs.size() ){
return (AttributeNS)_nsAttrs.get(_attrNSPos++);
}else{
for(int i=0;i' :
if(Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
toWrite=_GT_;
//writer.write(_GT_);
break;
case 0xD :
if(Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
toWrite=__XD_;
//writer.write(__XD_);
break;
case 0xA :
toWrite = null;
writeCharToUtf8(c,writer);
break;
default :
if(Arrays.equals(toWrite, __XD_)){
writer.write(toWrite);
toWrite = null;
}
writeCharToUtf8(c,writer);
continue;
}
if(toWrite != null && !Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
}
}
final static void outputAttrToWriter(final String name, final String value, final OutputStream writer) throws IOException {
writer.write(' ');
writeStringToUtf8(name,writer);
writer.write(equalsStr);
byte []toWrite;
final int length = value.length();
for (int i=0;i < length; i++) {
char c = value.charAt(i);
switch (c) {
case '&' :
toWrite=_AMP_;
//writer.write(_AMP_);
break;
case '<' :
toWrite=_LT_;
//writer.write(_LT_);
break;
case '"' :
toWrite=_QUOT_;
//writer.write(_QUOT_);
break;
case 0x09 : // '\t'
toWrite=__X9_;
//writer.write(__X9_);
break;
case 0x0A : // '\n'
toWrite=__XA_;
//writer.write(__XA_);
break;
case 0x0D : // '\r'
toWrite=__XD_;
//writer.write(__XD_);
break;
default :
writeCharToUtf8(c,writer);
//this._writer.write(c);
continue;
}
writer.write(toWrite);
}
writer.write('\"');
}
final static void outputAttrToWriter( String prefix,final String localName, final String value, final OutputStream writer) throws IOException {
writer.write(' ');
if(localName.length() != 0){
writeStringToUtf8(prefix,writer);
writeStringToUtf8(":",writer);
writeStringToUtf8(localName,writer);
}else{
writeStringToUtf8(prefix,writer);
}
writer.write(equalsStr);
byte []toWrite;
final int length = value.length();
for (int i=0;i < length; i++) {
char c = value.charAt(i);
switch (c) {
case '&' :
toWrite=_AMP_;
//writer.write(_AMP_);
break;
case '<' :
toWrite=_LT_;
//writer.write(_LT_);
break;
case '"' :
toWrite=_QUOT_;
//writer.write(_QUOT_);
break;
case 0x09 : // '\t'
toWrite=__X9_;
//writer.write(__X9_);
break;
case 0x0A : // '\n'
toWrite=__XA_;
//writer.write(__XA_);
break;
case 0x0D : // '\r'
toWrite=__XD_;
//writer.write(__XD_);
break;
default :
writeCharToUtf8(c,writer);
//this._writer.write(c);
continue;
}
writer.write(toWrite);
}
writer.write('\"');
}
final static void writeCharToUtf8(final char c,final OutputStream out) throws IOException{
char ch;
if (/*(c >= 0x0001) &&*/ (c <= 0x007F)) {
out.write(c);
return;
}
int bias;
int write;
if (c > 0x07FF) {
ch=(char)(c>>>12);
write=0xE0;
if (ch>0) {
write |= ( ch & 0x0F);
}
out.write(write);
write=0x80;
bias=0x3F;
} else {
write=0xC0;
bias=0x1F;
}
ch=(char)(c>>>6);
if (ch>0) {
write|= (ch & bias);
}
out.write(write);
out.write(0x80 | ((c) & 0x3F));
}
final static void writeStringToUtf8(final String str,final OutputStream out) throws IOException{
final int length=str.length();
int i=0;
char c;
while (i= 0x0001) &&*/ (c <= 0x007F)) {
out.write(c);
continue;
}
char ch;
int bias;
int write;
if (c > 0x07FF) {
ch=(char)(c>>>12);
write=0xE0;
if (ch>0) {
write |= ( ch & 0x0F);
}
out.write(write);
write=0x80;
bias=0x3F;
} else {
write=0xC0;
bias=0x1F;
}
ch=(char)(c>>>6);
if (ch>0) {
write|= (ch & bias);
}
out.write(write);
out.write(0x80 | ((c) & 0x3F));
continue;
}
}
/**
* Outputs a PI to the internal Writer.
*
* @param currentPI
* @param writer where to write the things
* @throws IOException
*/
static final void outputPItoWriter(String target, String data,OutputStream writer) throws IOException {
//Assume comments after document element only.
//as this will be used to canonicalize body.
writer.write('\n');
writer.write(_BEGIN_PI);
int length = target.length();
for (int i = 0; i < length; i++) {
char c=target.charAt(i);
if (c==0x0D) {
writer.write(__XD_);
} else {
writeCharToUtf8(c,writer);
}
}
length = data.length();
if (length > 0) {
writer.write(' ');
for (int i = 0; i < length; i++) {
char c=data.charAt(i);
if (c==0x0D) {
writer.write(__XD_);
} else {
writeCharToUtf8(c,writer);
}
}
}
writer.write(_END_PI);
}
/**
* Method outputCommentToWriter
*
* @param currentComment
* @param writer writer where to write the things
* @throws IOException
*/
static final void outputCommentToWriter(String data, OutputStream writer) throws IOException {
//Assume comments after document element only.
//as this will be used to canonicalize body.
writer.write('\n');
writer.write(_BEGIN_COMM);
final int length = data.length();
for (int i = 0; i < length; i++) {
char c=data.charAt(i);
if (c==0x0D) {
writer.write(__XD_);
} else {
writeCharToUtf8(c,writer);
}
}
writer.write(_END_COMM);
}
void outputTextToWriter(String text, OutputStream writer) throws IOException{
byte []toWrite = null;
for (int i = 0; i < text.length(); i++) {
char c = text.charAt(i);
switch (c) {
case '&' :
if(Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
toWrite=_AMP_;
//writer.write(_AMP_);
break;
case '<' :
if(Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
toWrite=_LT_;
//writer.write(_LT_);
break;
case '>' :
if(Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
toWrite=_GT_;
//writer.write(_GT_);
break;
case 0xD :
if(Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
toWrite=__XD_;
//writer.write(__XD_);
break;
case 0xA :
toWrite = null;
writeCharToUtf8(c,writer);
break;
default :
if(Arrays.equals(toWrite, __XD_)){
writer.write(toWrite);
toWrite = null;
}
writeCharToUtf8(c,writer);
continue;
}
if(toWrite != null && !Arrays.equals(toWrite, __XD_))
writer.write(toWrite);
}
}
/**
* Method namespaceIsRelative
*
* @param namespaceValue
* @return true if the given namespace is relative.
*/
public static boolean namespaceIsRelative(String namespaceValue) {
return !namespaceIsAbsolute(namespaceValue);
}
/**
* Method namespaceIsAbsolute
*
* @param namespaceValue
* @return true if the given namespace is absolute.
*/
public static boolean namespaceIsAbsolute(String namespaceValue) {
// assume empty namespaces are absolute
if (namespaceValue.length() == 0) {
return true;
}
return namespaceValue.indexOf(':')>0;
}
/*
*
* NamespaceContext implementation.
*
*/
@SuppressWarnings("unchecked")
public static class NamespaceContextImpl implements javax.xml.namespace.NamespaceContext{
AttributeNS nsDecl = new AttributeNS();
HashMap prefixMappings = new HashMap();
ArrayList clearDepth = new ArrayList(10);
int nsDepth;
int resizeBy = 10;
public NamespaceContextImpl(){
//change this
for(int i=0;i<10;i++){
clearDepth.add(null);
}
}
@SuppressWarnings("unchecked")
public AttributeNS getNamespaceDeclaration(String prefix){
Stack stack = (Stack)prefixMappings.get(prefix);
if(stack == null || stack.empty() ){
return null;
}
AttributeNS attrNS = (AttributeNS)stack.peek();
if(attrNS.isWritten()){
if(debug){
System.out.println("depth "+nsDepth +" did not return prefix "+prefix);
}
return null;
}
if (attrNS != null && !attrNS.isWritten() && !isPrefixRedefined(stack, attrNS)) {
//now check if at output parents it was written
int tmp = nsDepth -1;
while (tmp >=0) {
UsedNSList uList = (UsedNSList)clearDepth.get(tmp);
if (uList != null && uList.getUsedPrefixList() != null &&
uList.getUsedPrefixList().contains(prefix)) {
attrNS = null;
break;
}
tmp--;
}
}
UsedNSList uList = null;
uList = (UsedNSList)clearDepth.get(nsDepth);
if(uList == null){
uList = new UsedNSList();
clearDepth.set(nsDepth,uList);
}
if(debug){
System.out.println("depth "+nsDepth +" return prefix "+prefix);
}
uList.getUsedPrefixList().add(prefix);
return attrNS;
}
@SuppressWarnings("unchecked")
public void declareNamespace(String prefix, String uri){
Stack nsDecls = (Stack)prefixMappings.get(prefix);
nsDecl.setPrefix(prefix);
nsDecl.setUri(uri);
if(nsDecls == null){
nsDecls = new Stack();
try {
nsDecls.add(nsDecl.clone());
prefixMappings.put(prefix,nsDecls);
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
}else if(!nsDecls.contains(nsDecl)){
try {
nsDecls.add(nsDecl.clone());
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
} else if (nsDecls.contains(nsDecl) && "".equals(prefix)) {
AttributeNS top = (AttributeNS)nsDecls.peek();
if (!nsDecl.equals(top)) {
try {
nsDecls.add(nsDecl.clone());
} catch (CloneNotSupportedException ex) {
throw new RuntimeException(ex);
}
}
}else{
return;
}
UsedNSList uList = null;
uList = (UsedNSList)clearDepth.get(nsDepth);
if(uList == null){
uList = new UsedNSList();
clearDepth.set(nsDepth,uList);
}
ArrayList prefixList = uList.getPopList();
prefixList.add(prefix);
}
@SuppressWarnings("unchecked")
public void push(){
nsDepth++;
if(debug){
System.out.println("--------------------Push depth----------------"+nsDepth);
}
if(nsDepth >=clearDepth.size()){
clearDepth.ensureCapacity(clearDepth.size()+resizeBy);
int len = clearDepth.size();
for(int i=len;i< len+resizeBy;i++){
clearDepth.add(null);
}
}
}
public void pop(){
if(nsDepth <=0){
return;
}
UsedNSList ul = (UsedNSList)clearDepth.get(nsDepth);
if(debug){
System.out.println("---------------------pop depth----------------------"+nsDepth);
}
nsDepth--;
if(ul == null ){
return;
}
ArrayList pList = ul.getPopList();
for(int i=0;i keys = prefixMappings.keySet();
Iterator itr = keys.iterator();
while(itr.hasNext()){
String key = itr.next();
Stack stack = (Stack)prefixMappings.get(key);
if(stack == null || stack.empty() ){
continue;
}
AttributeNS attrNS = (AttributeNS)stack.peek();
if(namespaceURI.equals(attrNS.getUri())){
return key;
}
}
return null;
}
@SuppressWarnings("unchecked")
public Iterator getPrefixes(String namespaceURI) {
Set keys = prefixMappings.keySet();
ArrayList list = new ArrayList();
Iterator itr = keys.iterator();
while(itr.hasNext()){
String key = itr.next();
Stack stack = (Stack)prefixMappings.get(key);
if(stack == null || stack.empty() ){
continue;
}
AttributeNS attrNS = (AttributeNS)stack.peek();
if(namespaceURI.equals(attrNS.getUri())){
list.add(key);
}
}
return list.iterator();
}
private boolean isPrefixRedefined(Stack stack, AttributeNS attrNS) {
Iterator it = stack.iterator();
while (it.hasNext()) {
AttributeNS aNS = (AttributeNS)it.next();
if (!attrNS.getUri().equals(aNS.getUri())) {
return true;
}
}
return false;
}
}
static class UsedNSList {
ArrayList usedPrefixList = new ArrayList();
ArrayList popPrefixList = new ArrayList();
public ArrayList getPopList(){
return popPrefixList;
}
public ArrayList getUsedPrefixList(){
return usedPrefixList;
}
public void clear(){
usedPrefixList.clear();
popPrefixList.clear();
}
}
static class ElementName {
//byte [] utf8Data = new UnsyncBufferedOutputStream(20);
private UnsyncByteArrayOutputStream utf8Data = new UnsyncByteArrayOutputStream(20);
public UnsyncByteArrayOutputStream getUtf8Data() {
return utf8Data;
}
public void setUtf8Data(UnsyncByteArrayOutputStream utf8Data) {
this.utf8Data = utf8Data;
}
}
/*public static void sort(List list) {
Object[] a = list.toArray();
int size = a.length;
for ( int iterator=0; iterator i = list.listIterator();
ListIterator i = list.listIterator();
for (int j=0; j=0 ) {
swap(list, iterator1, iterator);
}
}
}
}
/*private static void swap(Object[] x, int a, int b) {
Object t = x[a];
x[a] = x[b];
x[b] = t;
}*/
@SuppressWarnings("unchecked")
private static void swap(List x, int a, int b) {
Object t = x.get(a);
x.set(a, x.get(b));
x.set(b, t);
}
}