alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (C14nXmlOutput.java)

This example Java source code file (C14nXmlOutput.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

c14nxmloutput, characterescapehandler, comparable, dynamicattribute, encoded, finalarraylist, ioexception, name, override, staticattribute, string, utf8xmloutput, util

The C14nXmlOutput.java Java example source code

/*
 * Copyright (c) 1997, 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
 * 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.xml.internal.bind.v2.runtime.output;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.Collections;

import com.sun.xml.internal.bind.api.JAXBRIContext;
import com.sun.xml.internal.bind.v2.runtime.Name;
import com.sun.istack.internal.FinalArrayList;
import com.sun.xml.internal.bind.marshaller.CharacterEscapeHandler;

/**
 * {@link XmlOutput} that generates canonical XML.
 *
 * @see com.sun.xml.internal.bind.api.C14nSupport_ArchitectureDocument
 * @author Kohsuke Kawaguchi
 */
public class C14nXmlOutput extends UTF8XmlOutput {
    public C14nXmlOutput(OutputStream out, Encoded[] localNames, boolean namedAttributesAreOrdered, CharacterEscapeHandler escapeHandler) {
        super(out, localNames, escapeHandler);
        this.namedAttributesAreOrdered = namedAttributesAreOrdered;

        for( int i=0; i<staticAttributes.length; i++ )
            staticAttributes[i] = new StaticAttribute();
    }

    /**
     * Hosts statically known attributes.
     *
     * {@link StaticAttribute} instances are reused.
     */
    private StaticAttribute[] staticAttributes = new StaticAttribute[8];
    private int len = 0;

    /**
     * Used to sort namespace declarations. Reused.
     */
    private int[] nsBuf = new int[8];

    /**
     * Hosts other attributes whose name are not statically known
     * (AKA attribute wildcard.)
     *
     * As long as this map is empty, there's no need for sorting.
     * see {@link com.sun.xml.internal.bind.api.C14nSupport_ArchitectureDocument} for more details.
     */
    private final FinalArrayList<DynamicAttribute> otherAttributes = new FinalArrayList();

    /**
     * True if {@link JAXBRIContext} is created with c14n support on,
     * in which case all named attributes are sorted by the marshaller
     * and we won't have to do it here.
     */
    private final boolean namedAttributesAreOrdered;

    final class StaticAttribute implements Comparable<StaticAttribute> {
        Name name;
        String value;

        public void set(Name name, String value) {
            this.name = name;
            this.value = value;
        }

        void write() throws IOException {
            C14nXmlOutput.super.attribute(name,value);
        }

        DynamicAttribute toDynamicAttribute() {
            int nsUriIndex = name.nsUriIndex;
            int prefix;
            if(nsUriIndex==-1)
                prefix = -1;
            else
                prefix = nsUriIndex2prefixIndex[nsUriIndex];
            return new DynamicAttribute(
                prefix, name.localName, value );
        }

        public int compareTo(StaticAttribute that) {
            return this.name.compareTo(that.name);
        }

    }

    final class DynamicAttribute implements Comparable<DynamicAttribute> {
        final int prefix;
        final String localName;
        final String value;

        public DynamicAttribute(int prefix, String localName, String value) {
            this.prefix = prefix;
            this.localName = localName;
            this.value = value;
        }

        private String getURI() {
            if(prefix==-1)  return "";
            else            return nsContext.getNamespaceURI(prefix);
        }

        public int compareTo(DynamicAttribute that) {
            int r = this.getURI().compareTo(that.getURI());
            if(r!=0)    return r;
            return this.localName.compareTo(that.localName);
        }
    }

    @Override
    public void attribute(Name name, String value) throws IOException {
        if(staticAttributes.length==len) {
            // reallocate
            int newLen = len*2;
            StaticAttribute[] newbuf = new StaticAttribute[newLen];
            System.arraycopy(staticAttributes,0,newbuf,0,len);
            for(int i=len;i<newLen;i++)
                staticAttributes[i] = new StaticAttribute();
            staticAttributes = newbuf;
        }

        staticAttributes[len++].set(name,value);
    }

    @Override
    public void attribute(int prefix, String localName, String value) throws IOException {
        otherAttributes.add(new DynamicAttribute(prefix,localName,value));
    }

    @Override
    public void endStartTag() throws IOException {
        if(otherAttributes.isEmpty()) {
            if(len!=0) {
                // sort is expensive even for size 0 array,
                // so it's worth checking len==0
                if(!namedAttributesAreOrdered)
                    Arrays.sort(staticAttributes,0,len);
                // this is the common case
                for( int i=0; i<len; i++ )
                    staticAttributes[i].write();
                len = 0;
            }
        } else {
            // this is the exceptional case

            // sort all the attributes, not just the other attributes
            for( int i=0; i<len; i++ )
                otherAttributes.add(staticAttributes[i].toDynamicAttribute());
            len = 0;
            Collections.sort(otherAttributes);

            // write them all
            int size = otherAttributes.size();
            for( int i=0; i<size; i++ ) {
                DynamicAttribute a = otherAttributes.get(i);
                super.attribute(a.prefix,a.localName,a.value);
            }
            otherAttributes.clear();
        }
        super.endStartTag();
    }

    /**
     * Write namespace declarations after sorting them.
     */
    @Override
    protected void writeNsDecls(int base) throws IOException {
        int count = nsContext.getCurrent().count();

        if(count==0)
            return; // quickly reject the most common case

        if(count>nsBuf.length)
            nsBuf = new int[count];

        for( int i=count-1; i>=0; i-- )
            nsBuf[i] = base+i;

        // do a bubble sort. Hopefully # of ns decls are small enough to justify bubble sort.
        // faster algorithm is more compliated to implement
        for( int i=0; i<count; i++ ) {
            for( int j=i+1; j<count; j++ ) {
                String p = nsContext.getPrefix(nsBuf[i]);
                String q = nsContext.getPrefix(nsBuf[j]);
                if( p.compareTo(q) > 0 ) {
                    // swap
                    int t = nsBuf[j];
                    nsBuf[j] = nsBuf[i];
                    nsBuf[i] = t;
                }
            }
        }

        // write them out
        for( int i=0; i<count; i++ )
            writeNsDecl(nsBuf[i]);
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java C14nXmlOutput.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.