aoqi@0: /* aoqi@0: * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. aoqi@0: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. aoqi@0: * aoqi@0: * This code is free software; you can redistribute it and/or modify it aoqi@0: * under the terms of the GNU General Public License version 2 only, as aoqi@0: * published by the Free Software Foundation. Oracle designates this aoqi@0: * particular file as subject to the "Classpath" exception as provided aoqi@0: * by Oracle in the LICENSE file that accompanied this code. aoqi@0: * aoqi@0: * This code is distributed in the hope that it will be useful, but WITHOUT aoqi@0: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or aoqi@0: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License aoqi@0: * version 2 for more details (a copy is included in the LICENSE file that aoqi@0: * accompanied this code). aoqi@0: * aoqi@0: * You should have received a copy of the GNU General Public License version aoqi@0: * 2 along with this work; if not, write to the Free Software Foundation, aoqi@0: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. aoqi@0: * aoqi@0: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA aoqi@0: * or visit www.oracle.com if you need additional information or have any aoqi@0: * questions. aoqi@0: */ aoqi@0: aoqi@0: package com.sun.xml.internal.bind.v2.runtime.output; aoqi@0: aoqi@0: import java.io.IOException; aoqi@0: import java.io.OutputStream; aoqi@0: import java.util.Arrays; aoqi@0: import java.util.Collections; aoqi@0: aoqi@0: import com.sun.xml.internal.bind.api.JAXBRIContext; aoqi@0: import com.sun.xml.internal.bind.v2.runtime.Name; aoqi@0: import com.sun.istack.internal.FinalArrayList; aoqi@0: import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler; aoqi@0: aoqi@0: /** aoqi@0: * {@link XmlOutput} that generates canonical XML. aoqi@0: * aoqi@0: * @see com.sun.xml.internal.bind.api.C14nSupport_ArchitectureDocument aoqi@0: * @author Kohsuke Kawaguchi aoqi@0: */ aoqi@0: public class C14nXmlOutput extends UTF8XmlOutput { aoqi@0: public C14nXmlOutput(OutputStream out, Encoded[] localNames, boolean namedAttributesAreOrdered, CharacterEscapeHandler escapeHandler) { aoqi@0: super(out, localNames, escapeHandler); aoqi@0: this.namedAttributesAreOrdered = namedAttributesAreOrdered; aoqi@0: aoqi@0: for( int i=0; i otherAttributes = new FinalArrayList(); aoqi@0: aoqi@0: /** aoqi@0: * True if {@link JAXBRIContext} is created with c14n support on, aoqi@0: * in which case all named attributes are sorted by the marshaller aoqi@0: * and we won't have to do it here. aoqi@0: */ aoqi@0: private final boolean namedAttributesAreOrdered; aoqi@0: aoqi@0: final class StaticAttribute implements Comparable { aoqi@0: Name name; aoqi@0: String value; aoqi@0: aoqi@0: public void set(Name name, String value) { aoqi@0: this.name = name; aoqi@0: this.value = value; aoqi@0: } aoqi@0: aoqi@0: void write() throws IOException { aoqi@0: C14nXmlOutput.super.attribute(name,value); aoqi@0: } aoqi@0: aoqi@0: DynamicAttribute toDynamicAttribute() { aoqi@0: int nsUriIndex = name.nsUriIndex; aoqi@0: int prefix; aoqi@0: if(nsUriIndex==-1) aoqi@0: prefix = -1; aoqi@0: else aoqi@0: prefix = nsUriIndex2prefixIndex[nsUriIndex]; aoqi@0: return new DynamicAttribute( aoqi@0: prefix, name.localName, value ); aoqi@0: } aoqi@0: aoqi@0: public int compareTo(StaticAttribute that) { aoqi@0: return this.name.compareTo(that.name); aoqi@0: } aoqi@0: aoqi@0: } aoqi@0: aoqi@0: final class DynamicAttribute implements Comparable { aoqi@0: final int prefix; aoqi@0: final String localName; aoqi@0: final String value; aoqi@0: aoqi@0: public DynamicAttribute(int prefix, String localName, String value) { aoqi@0: this.prefix = prefix; aoqi@0: this.localName = localName; aoqi@0: this.value = value; aoqi@0: } aoqi@0: aoqi@0: private String getURI() { aoqi@0: if(prefix==-1) return ""; aoqi@0: else return nsContext.getNamespaceURI(prefix); aoqi@0: } aoqi@0: aoqi@0: public int compareTo(DynamicAttribute that) { aoqi@0: int r = this.getURI().compareTo(that.getURI()); aoqi@0: if(r!=0) return r; aoqi@0: return this.localName.compareTo(that.localName); aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: @Override aoqi@0: public void attribute(Name name, String value) throws IOException { aoqi@0: if(staticAttributes.length==len) { aoqi@0: // reallocate aoqi@0: int newLen = len*2; aoqi@0: StaticAttribute[] newbuf = new StaticAttribute[newLen]; aoqi@0: System.arraycopy(staticAttributes,0,newbuf,0,len); aoqi@0: for(int i=len;insBuf.length) aoqi@0: nsBuf = new int[count]; aoqi@0: aoqi@0: for( int i=count-1; i>=0; i-- ) aoqi@0: nsBuf[i] = base+i; aoqi@0: aoqi@0: // do a bubble sort. Hopefully # of ns decls are small enough to justify bubble sort. aoqi@0: // faster algorithm is more compliated to implement aoqi@0: for( int i=0; i 0 ) { aoqi@0: // swap aoqi@0: int t = nsBuf[j]; aoqi@0: nsBuf[j] = nsBuf[i]; aoqi@0: nsBuf[i] = t; aoqi@0: } aoqi@0: } aoqi@0: } aoqi@0: aoqi@0: // write them out aoqi@0: for( int i=0; i