All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.xmlbeans.impl.tool.XsbDumper Maven / Gradle / Ivy

Go to download

The Apache Commons Codec package contains simple encoder and decoders for various formats such as Base64 and Hexadecimal. In addition to these widely used encoders and decoders, the codec package also maintains a collection of phonetic encoding utilities.

The newest version!
/*   Copyright 2004 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 org.apache.xmlbeans.impl.tool;

import java.util.*;
import java.util.zip.ZipFile;
import java.util.zip.ZipEntry;
import java.io.*;
import java.math.BigInteger;


import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.util.HexBin;
import org.apache.xmlbeans.QNameSet;
import org.apache.xmlbeans.SchemaLocalAttribute;
import org.apache.xmlbeans.SchemaParticle;
import org.apache.xmlbeans.SchemaProperty;
import org.apache.xmlbeans.SchemaType;
import org.apache.xmlbeans.soap.SOAPArrayType;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import javax.xml.namespace.QName;

public class XsbDumper
{
    public static void printUsage()
    {
        System.out.println("Prints the contents of an XSB file in human-readable form.");
        System.out.println("An XSB file contains schema meta information needed to ");
        System.out.println("perform tasks such as binding and validation.");
        System.out.println("Usage: dumpxsb myfile.xsb");
        System.out.println("    myfile.xsb - Path to an XSB file.");
        System.out.println();
    }

    public static void main(String[] args)
    {
        if (args.length == 0) {
            printUsage();
            System.exit(0);
            return;
        }

        for (int i = 0; i < args.length; i++)
        {
            dump(new File(args[i]), true);
        }
    }

    private static void dump(File file, boolean force)
    {
        if (file.isDirectory())
        {
            File[] files = file.listFiles(
                new FileFilter()
                {
                    public boolean accept(File file)
                        { return file.isDirectory() || file.isFile() && file.getName().endsWith(".xsb"); }
                }
            );
            for (int i = 0; i < files.length; i++)
            {
                dump(files[i], false);
            }
        }
        else if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip"))
        {
            dumpZip(file);
        }
        else if (force || file.getName().endsWith(".xsb"))
        {
            try
            {
                System.out.println(file.toString());
                dump(new FileInputStream(file), "  ");
                System.out.println();
            }
            catch (FileNotFoundException e)
            {
                System.out.println(e.toString());
            }
        }
    }

    public static void dumpZip(File file)
    {
        try
        {
            ZipFile zipFile = new ZipFile(file);
            Enumeration e = zipFile.entries();
            while (e.hasMoreElements())
            {
                ZipEntry entry = (ZipEntry)e.nextElement();
                if (entry.getName().endsWith(".xsb"))
                {
                    System.out.println(entry.getName());
                    dump(zipFile.getInputStream(entry), "  ");
                    System.out.println();
                }
            }
        }
        catch (IOException e)
        {
            System.out.println(e.toString());
        }
    }

    public static void dump(InputStream input)
    {
        dump(input, "", System.out);
    }

    public static void dump(InputStream input, String indent)
    {
        dump(input, indent, System.out);
    }

    public static void dump(InputStream input, String indent, PrintStream output)
    {
        XsbDumper dumper = new XsbDumper(input, indent, output);
        dumper.dumpAll();
    }

    private XsbDumper(InputStream stream, String indent, PrintStream ostream)
    {
        _input = new DataInputStream(stream);
        _indent = indent;
        _out = ostream;
    }

    void flush() { _out.flush(); }
    void emit(String str) { _out.println(_indent + str); flush(); }
    void emit() { _out.println(); flush(); }
    void error(Exception e) { _out.println(e.toString()); flush(); IllegalStateException e2 = new IllegalStateException( e.getMessage() ); e2.initCause( e ); throw e2; }
    void error(String str) { _out.println(str); flush(); IllegalStateException e2 = new IllegalStateException( str ); throw e2; }
    private String _indent;
    private PrintStream _out;
    void indent() { _indent += "  "; }
    void outdent() { _indent = _indent.substring(0, _indent.length() - 2); }

    public static final int DATA_BABE = 0xDA7ABABE;
    public static final int MAJOR_VERSION = 2;
    public static final int MINOR_VERSION = 24;

    public static final int FILETYPE_SCHEMAINDEX = 1;
    public static final int FILETYPE_SCHEMATYPE = 2;
    public static final int FILETYPE_SCHEMAELEMENT = 3;
    public static final int FILETYPE_SCHEMAATTRIBUTE = 4;
    public static final int FILETYPE_SCHEMAPOINTER = 5;
    public static final int FILETYPE_SCHEMAMODELGROUP = 6;
    public static final int FILETYPE_SCHEMAATTRIBUTEGROUP = 7;

    static String filetypeString(int code)
    {
        switch (code)
        {
            case FILETYPE_SCHEMAINDEX: return "FILETYPE_SCHEMAINDEX";
            case FILETYPE_SCHEMATYPE: return "FILETYPE_SCHEMATYPE";
            case FILETYPE_SCHEMAELEMENT: return "FILETYPE_SCHEMAELEMENT";
            case FILETYPE_SCHEMAATTRIBUTE: return "FILETYPE_SCHEMAATTRIBUTE";
            case FILETYPE_SCHEMAPOINTER: return "FILETYPE_SCHEMAPOINTER";
            case FILETYPE_SCHEMAMODELGROUP: return "FILETYPE_SCHEMAMODELGROUP";
            case FILETYPE_SCHEMAATTRIBUTEGROUP: return "FILETYPE_SCHEMAATTRIBUTEGROUP";
            default:
                return "Unknown FILETYPE (" + code + ")";
        }
    }

    public static final int FLAG_PART_SKIPPABLE = 1;
    public static final int FLAG_PART_FIXED = 4;
    public static final int FLAG_PART_NILLABLE = 8;
    public static final int FLAG_PART_BLOCKEXT = 16;
    public static final int FLAG_PART_BLOCKREST = 32;
    public static final int FLAG_PART_BLOCKSUBST = 64;
    public static final int FLAG_PART_ABSTRACT = 128;
    public static final int FLAG_PART_FINALEXT = 256;
    public static final int FLAG_PART_FINALREST = 512;

    static String particleflagsString(int flags)
    {
        StringBuffer result = new StringBuffer();
        if ((flags & FLAG_PART_SKIPPABLE) != 0) result.append("FLAG_PART_SKIPPABLE | ");
        if ((flags & FLAG_PART_FIXED) != 0) result.append("FLAG_PART_FIXED | ");
        if ((flags & FLAG_PART_NILLABLE) != 0) result.append("FLAG_PART_NILLABLE | ");
        if ((flags & FLAG_PART_BLOCKEXT) != 0) result.append("FLAG_PART_BLOCKEXT | ");
        if ((flags & FLAG_PART_BLOCKREST) != 0) result.append("FLAG_PART_BLOCKREST | ");
        if ((flags & FLAG_PART_BLOCKSUBST) != 0) result.append("FLAG_PART_BLOCKSUBST | ");
        if ((flags & FLAG_PART_ABSTRACT) != 0) result.append("FLAG_PART_ABSTRACT | ");
        if ((flags & FLAG_PART_FINALEXT) != 0) result.append("FLAG_PART_FINALEXT | ");
        if ((flags & FLAG_PART_FINALREST) != 0) result.append("FLAG_PART_FINALREST | ");
        if (result.length() == 0) result.append("0 | ");
        return result.substring(0, result.length() - 3);
    }

    public static final int FLAG_PROP_ISATTR = 1;
    public static final int FLAG_PROP_JAVASINGLETON = 2;
    public static final int FLAG_PROP_JAVAOPTIONAL = 4;
    public static final int FLAG_PROP_JAVAARRAY = 8;

    static String propertyflagsString(int flags)
    {
        StringBuffer result = new StringBuffer();
        if ((flags & FLAG_PROP_ISATTR) != 0) result.append("FLAG_PROP_ISATTR | ");
        if ((flags & FLAG_PROP_JAVASINGLETON) != 0) result.append("FLAG_PROP_JAVASINGLETON | ");
        if ((flags & FLAG_PROP_JAVAOPTIONAL) != 0) result.append("FLAG_PROP_JAVAOPTIONAL | ");
        if ((flags & FLAG_PROP_JAVAARRAY) != 0) result.append("FLAG_PROP_JAVAARRAY | ");
        if (result.length() == 0) result.append("0 | ");
        return result.substring(0, result.length() - 3);
    }

    public static final int FIELD_NONE = 0;
    public static final int FIELD_GLOBAL = 1;
    public static final int FIELD_LOCALATTR = 2;
    public static final int FIELD_LOCALELT = 3;

    static String containerfieldTypeString(int code)
    {
        switch (code)
        {
            case FIELD_NONE: return "FIELD_NONE";
            case FIELD_GLOBAL: return "FIELD_GLOBAL";
            case FIELD_LOCALATTR: return "FIELD_LOCALATTR";
            case FIELD_LOCALELT: return "FIELD_LOCALELT";
            default:
                return "Unknown container field type (" + code + ")";
        }
    }

    // type flags
    static final int FLAG_SIMPLE_TYPE     = 0x1;
    static final int FLAG_DOCUMENT_TYPE   = 0x2;
    static final int FLAG_ORDERED         = 0x4;
    static final int FLAG_BOUNDED         = 0x8;
    static final int FLAG_FINITE          = 0x10;
    static final int FLAG_NUMERIC         = 0x20;
    static final int FLAG_STRINGENUM      = 0x40;
    static final int FLAG_UNION_OF_LISTS  = 0x80;
    static final int FLAG_HAS_PATTERN     = 0x100;
    static final int FLAG_ORDER_SENSITIVE = 0x200;
    static final int FLAG_TOTAL_ORDER     = 0x400;
    static final int FLAG_COMPILED        = 0x800;
    static final int FLAG_BLOCK_EXT       = 0x1000;
    static final int FLAG_BLOCK_REST      = 0x2000;
    static final int FLAG_FINAL_EXT       = 0x4000;
    static final int FLAG_FINAL_REST      = 0x8000;
    static final int FLAG_FINAL_UNION     = 0x10000;
    static final int FLAG_FINAL_LIST      = 0x20000;
    static final int FLAG_ABSTRACT        = 0x40000;
    static final int FLAG_ATTRIBUTE_TYPE  = 0x80000;

    static String typeflagsString(int flags)
    {
        StringBuffer result = new StringBuffer();
        if ((flags & FLAG_SIMPLE_TYPE) != 0) result.append("FLAG_SIMPLE_TYPE | ");
        if ((flags & FLAG_DOCUMENT_TYPE) != 0) result.append("FLAG_DOCUMENT_TYPE | ");
        if ((flags & FLAG_ATTRIBUTE_TYPE) != 0) result.append("FLAG_ATTRIBUTE_TYPE | ");
        if ((flags & FLAG_ORDERED) != 0) result.append("FLAG_ORDERED | ");
        if ((flags & FLAG_BOUNDED) != 0) result.append("FLAG_BOUNDED | ");
        if ((flags & FLAG_FINITE) != 0) result.append("FLAG_FINITE | ");
        if ((flags & FLAG_NUMERIC) != 0) result.append("FLAG_NUMERIC | ");
        if ((flags & FLAG_STRINGENUM) != 0) result.append("FLAG_STRINGENUM | ");
        if ((flags & FLAG_UNION_OF_LISTS) != 0) result.append("FLAG_UNION_OF_LISTS | ");
        if ((flags & FLAG_HAS_PATTERN) != 0) result.append("FLAG_HAS_PATTERN | ");
        if ((flags & FLAG_TOTAL_ORDER) != 0) result.append("FLAG_TOTAL_ORDER | ");
        if ((flags & FLAG_COMPILED) != 0) result.append("FLAG_COMPILED | ");
        if ((flags & FLAG_BLOCK_EXT) != 0) result.append("FLAG_BLOCK_EXT | ");
        if ((flags & FLAG_BLOCK_REST) != 0) result.append("FLAG_BLOCK_REST | ");
        if ((flags & FLAG_FINAL_EXT) != 0) result.append("FLAG_FINAL_EXT | ");
        if ((flags & FLAG_FINAL_REST) != 0) result.append("FLAG_FINAL_REST | ");
        if ((flags & FLAG_FINAL_UNION) != 0) result.append("FLAG_FINAL_UNION | ");
        if ((flags & FLAG_FINAL_LIST) != 0) result.append("FLAG_FINAL_LIST | ");
        if ((flags & FLAG_ABSTRACT) != 0) result.append("FLAG_ABSTRACT | ");
        if (result.length() == 0) result.append("0 | ");
        return result.substring(0, result.length() - 3);
    }

    void dumpAll()
    {
        int filetype = dumpHeader();
        switch (filetype)
        {
            case FILETYPE_SCHEMAINDEX:
                dumpIndexData();
                return;
            case FILETYPE_SCHEMATYPE:
                dumpTypeFileData();
                break;
            case FILETYPE_SCHEMAELEMENT:
                dumpParticleData(true);
                break;
            case FILETYPE_SCHEMAATTRIBUTE:
                dumpAttributeData(true);
                break;
            case FILETYPE_SCHEMAPOINTER:
                dumpPointerData();
                break;
            case FILETYPE_SCHEMAMODELGROUP:
                dumpModelGroupData();
                break;
            case FILETYPE_SCHEMAATTRIBUTEGROUP:
                dumpAttributeGroupData();
                break;
        }
        readEnd();
    }

    static String hex32String(int i)
    {
        return Integer.toHexString(i);
    }

    protected int dumpHeader()
    {
        int magic = readInt();
        emit("Magic cookie: " + hex32String(magic));

        if (magic != DATA_BABE)
        {
            emit("Wrong magic cookie.");
            return 0;
        }

        _majorver = readShort();
        _minorver = readShort();
        if (atLeast(2, 18, 0))
            _releaseno = readShort();

        emit("Major version: " + _majorver);
        emit("Minor version: " + _minorver);
        emit("Release number: " + _releaseno);

        if (_majorver != MAJOR_VERSION || _minorver > MINOR_VERSION)
        {
            emit("Incompatible version.");
            return 0;
        }

        int actualfiletype = readShort();
        emit("Filetype: " + filetypeString(actualfiletype));

        _stringPool = new StringPool();
        _stringPool.readFrom(_input);

        return actualfiletype;
    }

    void dumpPointerData()
    {
        emit("Type system: " + readString());
    }

    protected void dumpIndexData()
    {
        // has a handle pool (count, handle/type, handle/type...)
        int size = readShort();
        emit("Handle pool (" + size + "):");
        indent();
        for (int i = 0; i < size; i++)
        {
            String handle = readString();
            int code = readShort();
            emit(handle + " (" + filetypeString(code) + ")");
        }
        outdent();

        dumpQNameMap("Global elements");

        // qname map of global attributes
        dumpQNameMap("Global attributes");

        // attr groups and model groups
        dumpQNameMap("Model groups");
        dumpQNameMap("Attribute groups");

        dumpQNameMap("Identity constraints");

        // qname map of global types
        dumpQNameMap("Global types");

        // qname map of document types, by the qname of the contained element
        dumpQNameMap("Document types");

        // qname map of attribute types, by the qname of the contained attribute
        dumpQNameMap("Attribute types");

        // all the types indexed by classname
        dumpClassnameIndex("All types by classname");

        // all the namespaces
        dumpStringArray("Defined namespaces");

        // version 15 stuff for redefines
        if (atLeast(2, 15, 0))
        {
            dumpQNameMap("Redefined global types");
            dumpQNameMap("Redfined model groups");
            dumpQNameMap("Redfined attribute groups");
        }

        // version 19 annotations
        if (atLeast(2, 19, 0))
            dumpAnnotations();

        readEnd();
    }


    class StringPool
    {
        private List intsToStrings = new ArrayList();
        private Map stringsToInts = new HashMap();

        StringPool()
        {
            intsToStrings.add(null);
        }

        String stringForCode(int code)
        {
            if (code == 0)
                return null;
            return (String)intsToStrings.get(code);
        }

        int codeForString(String str)
        {
            if (str == null)
                return 0;
            Integer result = (Integer)stringsToInts.get(str);
            if (result == null)
            {
                result = new Integer(intsToStrings.size());
                intsToStrings.add(str);
                stringsToInts.put(str, result);
            }
            return result.intValue();
        }

        void readFrom(DataInputStream input)
        {
            if (intsToStrings.size() != 1 || stringsToInts.size() != 0)
                throw new IllegalStateException();

            try
            {
                int size = input.readShort();
                emit("String pool (" + size + "):");
                indent();
                for (int i = 1; i < size; i++)
                {
                    String str = input.readUTF();
                    int code = codeForString(str);
                    if (code != i)
                        throw new IllegalStateException();
                    emit(code + " = \"" + str + "\"");
                }
                outdent();
            }
            catch (IOException e)
            {
                emit(e.toString());
            }
        }
    }

    // active while loading one type.
    DataInputStream _input;
    StringPool _stringPool;

    int readShort()
    {
        try
        {
            return _input.readUnsignedShort();
        }
        catch (IOException e)
        {
            error(e);
            return 0;
        }
    }

    int readInt()
    {
        try
        {
            return _input.readInt();
        }
        catch (IOException e)
        {
            error(e);
            return 0;
        }
    }

    String readString()
    {
        return _stringPool.stringForCode(readShort());
    }

    QName readQName()
    {
        String namespace = readString();
        String localname = readString();
        if (localname == null)
            return null;
        return new QName(namespace, localname);
    }

    String readHandle()
    {
        return readString();
    }

    String readType()
    {
        return readHandle();
    }

    static String qnameString(QName qname)
    {
        if (qname == null)
            return "(null)";
        if (qname.getNamespaceURI() != null)
            return qname.getLocalPart() + "@" + qname.getNamespaceURI();
        else
            return qname.getLocalPart();
    }

    static String qnameSetString(QNameSet set)
    {
        return set.toString();
    }

    void dumpQNameMap(String fieldname)
    {
        int size = readShort();
        emit(fieldname + " (" + size + "):");
        indent();
        for (int i = 0; i < size; i++)
        {
            emit(qnameString(readQName()) + " = " + readHandle());
        }
        outdent();
    }

    void dumpTypeArray(String fieldname)
    {
        int size = readShort();
        emit(fieldname + " (" + size + "):");
        indent();
        for (int i = 0; i < size; i++)
        {
            emit(i + " = " + readType());
        }
        outdent();
    }

    void dumpClassnameIndex(String fieldname)
    {
        int size = readShort();
        emit(fieldname + " (" + size + "):");
        indent();
        for (int i = 0; i < size; i++)
        {
            emit(readString() + " = " + readType());
        }
        outdent();
    }

    void dumpStringArray(String fieldname)
    {
        int size = readShort();
        emit(fieldname + " (" + size + "):");
        indent();
        for (int i = 0; i < size; i++)
        {
            emit(readString());
        }
        outdent();
    }

    void readEnd()
    {
        try
        {
            _input.close();
        }
        catch (IOException e)
        {
            // oh, well.
        }
        _input = null;
        _stringPool = null;
    }

    static String particleTypeString(int spt)
    {
        switch (spt)
        {
            case SchemaParticle.ALL: return "ALL";
            case SchemaParticle.CHOICE: return "CHOICE";
            case SchemaParticle.ELEMENT: return "ELEMENT";
            case SchemaParticle.SEQUENCE: return "SEQUENCE";
            case SchemaParticle.WILDCARD: return "WILDCARD";
            default:
                return "Unknown particle type (" + spt + ")";
        }
    }

    static String bigIntegerString(BigInteger bigint)
    {
        if (bigint == null)
            return "(null)";
        return bigint.toString();
    }

    static String wcprocessString(int code)
    {
        switch (code)
        {
            case SchemaParticle.STRICT: return "STRICT";
            case SchemaParticle.SKIP: return "SKIP";
            case SchemaParticle.LAX: return "LAX";
            case 0: return "NOT_WILDCARD";
            default:
                return "Unknown process type (" + code + ")";
        }
    }

    void dumpAnnotation()
    {
        if (!atLeast(2, 19, 0))
            return; // no annotations in this version of the file

        int n = readInt();
        if (n == -1)
            return; // no annotation present
        emit("Annotation");
        boolean empty = true;
        indent();
        if (n > 0)
        {
            emit("Attributes (" + n + "):");
            indent();
            for (int i = 0; i < n; i++)
            {
                if (atLeast(2, 24, 0))
                    emit("Name: " + qnameString(readQName()) +
                        ", Value: " + readString() +
                        ", ValueURI: " + readString());
                else
                    emit("Name: " + qnameString(readQName()) +
                        ", Value: " + readString());
            }
            outdent();
            empty = false;
        }

        n = readInt();
        if (n > 0)
        {
            emit("Documentation elements (" + n + "):");
            indent();
            for (int i = 0; i < n; i++)
                emit(readString());
            outdent();
            empty = false;
        }

        n = readInt();
        if (n > 0)
        {
            emit("Appinfo elements (" + n + "):");
            indent();
            for (int i = 0; i < n; i++)
                emit(readString());
            outdent();
            empty = false;
        }
        if (empty)
            emit("");
        outdent();
    }

    void dumpAnnotations()
    {
        int n = readInt();
        if (n > 0)
        {
            emit("Top-level annotations (" + n + "):");
            indent();
            for (int i = 0; i < n; i++)
                dumpAnnotation();
            outdent();
        }
    }

    void dumpParticleData(boolean global)
    {
        int particleType = readShort();
        emit(particleTypeString(particleType) + ":");
        indent();
        int particleFlags = readShort();
        emit("Flags: " + particleflagsString(particleFlags));

        emit("MinOccurs: " + bigIntegerString(readBigInteger()));
        emit("MaxOccurs: " + bigIntegerString(readBigInteger()));

        emit("Transition: " + qnameSetString(readQNameSet()));

        switch (particleType)
        {
            case SchemaParticle.WILDCARD:
                emit("Wildcard set: " + qnameSetString(readQNameSet()));
                emit("Wildcard process: " + wcprocessString(readShort()));
                break;

            case SchemaParticle.ELEMENT:
                emit("Name: " + qnameString(readQName()));
                emit("Type: " + readType());
                emit("Default: " + readString());
                if (atLeast(2, 16, 0))
                    emit("Default value: " + readXmlValueObject());
                emit("WsdlArrayType: " + SOAPArrayTypeString(readSOAPArrayType()));
                dumpAnnotation();
                if (global)
                {
                    if (atLeast(2, 17, 0))
                        emit("Substitution group ref: " + readHandle());
                    int substGroupCount = readShort();
                    emit("Substitution group members (" + substGroupCount + ")");
                    indent();
                    for (int i = 0; i < substGroupCount; i++)
                    {
                        emit(qnameString(readQName()));
                    }
                    outdent();
                }
                int count = readShort();
                emit("Identity constraints (" + count + "):");
                indent();
                for (int i = 0; i < count; i++)
                {
                    emit(readHandle());
                }
                outdent();
                if (global)
                    emit("Filename: " + readString());
                break;

            case SchemaParticle.ALL:
            case SchemaParticle.SEQUENCE:
            case SchemaParticle.CHOICE:
                dumpParticleArray("Particle children");
                break;

            default:
                error("Unrecognized schema particle type");
        }
        outdent();
    }

    void dumpParticleArray(String fieldname)
    {
        int count = readShort();
        emit(fieldname + "(" + count + "):");
        indent();
        for (int i = 0; i < count; i++)
            dumpParticleData(false);
        outdent();
    }

    static String complexVarietyString(int code)
    {
        switch (code)
        {
            case SchemaType.EMPTY_CONTENT: return "EMPTY_CONTENT";
            case SchemaType.SIMPLE_CONTENT: return "SIMPLE_CONTENT";
            case SchemaType.ELEMENT_CONTENT: return "ELEMENT_CONTENT";
            case SchemaType.MIXED_CONTENT: return "MIXED_CONTENT";
            default:
                return "Unknown complex variety (" + code + ")";
        }
    }

    static String simpleVarietyString(int code)
    {
        switch (code)
        {
            case SchemaType.ATOMIC: return "ATOMIC";
            case SchemaType.LIST: return "LIST";
            case SchemaType.UNION: return "UNION";
            default:
                return "Unknown simple variety (" + code + ")";
        }
    }

    String facetCodeString(int code)
    {
        switch (code)
        {
            case SchemaType.FACET_LENGTH: return "FACET_LENGTH";
            case SchemaType.FACET_MIN_LENGTH: return "FACET_MIN_LENGTH";
            case SchemaType.FACET_MAX_LENGTH: return "FACET_MAX_LENGTH";
            case SchemaType.FACET_MIN_EXCLUSIVE: return "FACET_MIN_EXCLUSIVE";
            case SchemaType.FACET_MIN_INCLUSIVE: return "FACET_MIN_INCLUSIVE";
            case SchemaType.FACET_MAX_INCLUSIVE: return "FACET_MAX_INCLUSIVE";
            case SchemaType.FACET_MAX_EXCLUSIVE: return "FACET_MAX_EXCLUSIVE";
            case SchemaType.FACET_TOTAL_DIGITS: return "FACET_TOTAL_DIGITS";
            case SchemaType.FACET_FRACTION_DIGITS: return "FACET_FRACTION_DIGITS";
            default:
                return "Unknown facet code (" + code + ")";
        }
    }

    String whitespaceCodeString(int code)
    {
        switch (code)
        {
            case SchemaType.WS_COLLAPSE: return "WS_COLLAPSE";
            case SchemaType.WS_PRESERVE: return "WS_PRESERVE";
            case SchemaType.WS_REPLACE: return "WS_REPLACE";
            case SchemaType.WS_UNSPECIFIED: return "WS_UNSPECIFIED";
            default:
                return "Unknown whitespace code (" + code + ")";
        }
    }

    String derivationTypeString(int code)
    {
        switch (code)
        {
            case SchemaType.DT_NOT_DERIVED: return "DT_NOT_DERIVED";
            case SchemaType.DT_RESTRICTION: return "DT_RESTRICTION";
            case SchemaType.DT_EXTENSION: return "DT_EXTENSION";
            default:
                return "Unknown derivation code (" + code + ")";
        }
    }

    void dumpTypeFileData()
    {
        emit("Name: " + qnameString(readQName()));
        emit("Outer type: " + readType());
        emit("Depth: " + readShort());
        emit("Base type: " + readType());
        emit("Derivation type: " + derivationTypeString(readShort()));
        dumpAnnotation();

        emit("Container field:");
        indent();
        int containerfieldtype = readShort();
        emit("Reftype: " + containerfieldTypeString(containerfieldtype));
        switch (containerfieldtype)
        {
            case FIELD_GLOBAL:
                emit("Handle: " + readHandle());
                break;
            case FIELD_LOCALATTR:
                emit("Index: " + readShort());
                break;
            case FIELD_LOCALELT:
                emit("Index: " + readShort());
                break;
        }
        outdent();
        emit("Java class name: " + readString());
        emit("Java impl class name: " + readString());

        dumpTypeArray("Anonymous types");

        emit("Anonymous union member ordinal: " + readShort());

        int flags;
        flags = readInt();
        emit("Flags: " + typeflagsString(flags));
        boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0);

        int complexVariety = SchemaType.NOT_COMPLEX_TYPE;
        if (isComplexType)
        {
            complexVariety = readShort();
            emit("Complex variety: " + complexVarietyString(complexVariety));

            if (atLeast(2, 23, 0))
                emit("Content based on type: " + readType());

            int attrCount = readShort();
            emit("Attribute model (" + attrCount + "):");
            indent();
            for (int i = 0; i < attrCount; i++)
                dumpAttributeData(false);

            emit("Wildcard set: " + qnameSetString(readQNameSet()));
            emit("Wildcard process: " + wcprocessString(readShort()));
            outdent();

            // Attribute Property Table
            int attrPropCount = readShort();
            emit("Attribute properties (" + attrPropCount + "):");
            indent();
            for (int i = 0; i < attrPropCount; i++)
            {
                dumpPropertyData();
            }
            outdent();

            if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT)
            {
                emit("IsAll: " + readShort());

                // Content model tree
                dumpParticleArray("Content model");

                // Element Property Table
                int elemPropCount = readShort();
                emit("Element properties (" + elemPropCount + "):");
                indent();
                for (int i = 0; i < elemPropCount; i++)
                {
                    dumpPropertyData();
                }
                outdent();
            }
        }

        if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT)
        {
            int simpleVariety = readShort();
            emit("Simple type variety: " + simpleVarietyString(simpleVariety));

            boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0);

            int facetCount = readShort();
            emit("Facets (" + facetCount + "):");
            indent();
            for (int i = 0; i < facetCount; i++)
            {
                emit(facetCodeString(readShort()));
                emit("Value: " + readXmlValueObject());
                emit("Fixed: " + readShort());
            }
            outdent();

            emit("Whitespace rule: " + whitespaceCodeString(readShort()));

            int patternCount = readShort();
            emit("Patterns (" + patternCount + "):");
            indent();
            for (int i = 0; i < patternCount; i++)
            {
                emit(readString());
            }
            outdent();

            int enumCount = readShort();
            emit("Enumeration values (" + enumCount + "):");
            indent();
            for (int i = 0; i < enumCount; i++)
            {
                emit(readXmlValueObject());
            }
            outdent();

            emit("Base enum type: " + readType());
            if (isStringEnum)
            {
                int seCount = readShort();
                emit("String enum entries (" + seCount + "):");
                indent();
                for (int i = 0; i < seCount; i++)
                {
                    emit("\"" + readString() + "\" -> " + readShort() + " = " + readString());
                }
                outdent();
            }

            switch (simpleVariety)
            {
                case SchemaType.ATOMIC:
                    emit("Primitive type: " + readType());
                    emit("Decimal size: " + readInt());
                    break;

                case SchemaType.LIST:
                    emit("List item type: " + readType());
                    break;

                case SchemaType.UNION:
                    dumpTypeArray("Union members");
                    break;

                default:
                    error("Unknown simple type variety");
            }
        }

        emit("Filename: " + readString());
    }

    static String attruseCodeString(int code)
    {
        switch (code)
        {
            case SchemaLocalAttribute.OPTIONAL: return "OPTIONAL";
            case SchemaLocalAttribute.REQUIRED: return "REQUIRED";
            case SchemaLocalAttribute.PROHIBITED: return "PROHIBITED";
            default:
                return "Unknown use code (" + code + ")";
        }
    }

    void dumpAttributeData(boolean global)
    {
        emit("Name: " + qnameString(readQName()));
        emit("Type: " + readType());
        emit("Use: " + attruseCodeString(readShort()));
        emit("Default: " + readString());
        if (atLeast(2, 16, 0))
            emit("Default value: " + readXmlValueObject());
        emit("Fixed: " + readShort());
        emit("WsdlArrayType: " + SOAPArrayTypeString(readSOAPArrayType()));
        dumpAnnotation();
        if (global)
            emit("Filename: " + readString());
    }

    private static final XmlOptions prettyOptions =
        new XmlOptions().setSavePrettyPrint();

    void dumpXml()
    {
        String xml = readString();
        try
        {
            emit( XmlObject.Factory.parse( xml ).xmlText( prettyOptions ) );
        }
        catch ( XmlException x )
        {
            emit( "!!!!!! BAD XML !!!!!" );
            emit( xml );
        }
    }

    void dumpModelGroupData()
    {
        emit("Name: " + qnameString(readQName()));
        emit("Target namespace: " + readString());
        emit("Chameleon: " + readShort());
        if (atLeast(2, 22, 0))
            emit("Element form default: " + readString());
        if (atLeast(2, 22, 0))
            emit("Attribute form default: " + readString());
        if (atLeast(2, 15, 0))
            emit("Redefine: " + readShort());
        emit("Model Group Xml: ");
        dumpXml();
        dumpAnnotation();
        if (atLeast(2, 21, 0))
            emit("Filename: " + readString());
    }

    void dumpAttributeGroupData()
    {
        emit("Name: " + qnameString(readQName()));
        emit("Target namespace: " + readString());
        emit("Chameleon: " + readShort());
        if (atLeast(2, 22, 0))
            emit("Form default: " + readString());
        if (atLeast(2, 15, 0))
            emit("Redefine: " + readShort());
        emit("Attribute Group Xml: ");
        dumpXml();
        dumpAnnotation();
        if (atLeast(2, 21, 0))
            emit("Filename: " + readString());
    }

    static String alwaysString(int code)
    {
        switch (code)
        {
            case SchemaProperty.CONSISTENTLY: return "CONSISTENTLY";
            case SchemaProperty.NEVER: return "NEVER";
            case SchemaProperty.VARIABLE: return "VARIABLE";
            default:
                return "Unknown frequency code (" + code + ")";
        }
    }

    static String jtcString(int code)
    {
        switch (code)
        {
            case SchemaProperty.XML_OBJECT: return "XML_OBJECT";
            case SchemaProperty.JAVA_BOOLEAN: return "JAVA_BOOLEAN";
            case SchemaProperty.JAVA_FLOAT: return "JAVA_FLOAT";
            case SchemaProperty.JAVA_DOUBLE: return "JAVA_DOUBLE";
            case SchemaProperty.JAVA_BYTE: return "JAVA_BYTE";
            case SchemaProperty.JAVA_SHORT: return "JAVA_SHORT";
            case SchemaProperty.JAVA_INT: return "JAVA_INT";
            case SchemaProperty.JAVA_LONG: return "JAVA_LONG";

            case SchemaProperty.JAVA_BIG_DECIMAL: return "JAVA_BIG_DECIMAL";
            case SchemaProperty.JAVA_BIG_INTEGER: return "JAVA_BIG_INTEGER";
            case SchemaProperty.JAVA_STRING: return "JAVA_STRING";
            case SchemaProperty.JAVA_BYTE_ARRAY: return "JAVA_BYTE_ARRAY";
            case SchemaProperty.JAVA_GDATE: return "JAVA_GDATE";
            case SchemaProperty.JAVA_GDURATION: return "JAVA_GDURATION";
            case SchemaProperty.JAVA_DATE: return "JAVA_DATE";
            case SchemaProperty.JAVA_QNAME: return "JAVA_QNAME";
            case SchemaProperty.JAVA_CALENDAR: return "JAVA_CALENDAR";
            case SchemaProperty.JAVA_LIST: return "JAVA_LIST";

            case SchemaProperty.JAVA_ENUM: return "JAVA_ENUM";
            case SchemaProperty.JAVA_OBJECT: return "JAVA_OBJECT";

            default:
                return "Unknown java type code (" + code + ")";
        }
    }

    void dumpPropertyData()
    {
        emit("Property");
        indent();
        emit("Name: " + qnameString(readQName()));
        emit("Type: " + readType());
        int propflags = readShort();
        emit("Flags: " + propertyflagsString(propflags));
        emit("Container type: " + readType());
        emit("Min occurances: " + bigIntegerString(readBigInteger()));
        emit("Max occurances: " + bigIntegerString(readBigInteger()));
        emit("Nillable: " + alwaysString(readShort()));
        emit("Default: " + alwaysString(readShort()));
        emit("Fixed: " + alwaysString(readShort()));
        emit("Default text: " + readString());
        emit("Java prop name: " + readString());
        emit("Java type code: " + jtcString(readShort()));
        emit("Type for java signature: " + readType());
        if (atMost(2, 19, 0))
            emit("Java setter delimiter: " + qnameSetString(readQNameSet()));
        if (atLeast(2, 16, 0))
            emit("Default value: " + readXmlValueObject());
        if (((propflags & FLAG_PROP_ISATTR) == 0) && atLeast(2, 17, 0))
        {
            int size = readShort();
            emit("Accepted substitutions (" + size + "):");
            for (int i = 0 ; i < size ; i++)
                emit("  Accepted name " + readQName());
        }
        outdent();
    }

    String readXmlValueObject()
    {
        String type = readType();
        if (type == null)
            return "null";

        int btc = readShort();
        String value;
        switch (btc)
        {
            default:
                assert(false);
            case 0:
                value = "nil";
                break;

            case SchemaType.BTC_ANY_SIMPLE:
            case SchemaType.BTC_ANY_URI:
            case SchemaType.BTC_STRING:
            case SchemaType.BTC_DURATION:
            case SchemaType.BTC_DATE_TIME:
            case SchemaType.BTC_TIME:
            case SchemaType.BTC_DATE:
            case SchemaType.BTC_G_YEAR_MONTH:
            case SchemaType.BTC_G_YEAR:
            case SchemaType.BTC_G_MONTH_DAY:
            case SchemaType.BTC_G_DAY:
            case SchemaType.BTC_G_MONTH:
            case SchemaType.BTC_DECIMAL:
            case SchemaType.BTC_BOOLEAN:
                value = readString();
                break;

            case SchemaType.BTC_BASE_64_BINARY:
            case SchemaType.BTC_HEX_BINARY:
                {
                    value = new String(HexBin.encode(readByteArray()));
                    if (value.length() > 19)
                        value = value.subSequence(0, 16) + "...";
                    break;
                }

            case SchemaType.BTC_QNAME:
            case SchemaType.BTC_NOTATION:
                value = QNameHelper.pretty(readQName());
                break;

            case SchemaType.BTC_FLOAT:
            case SchemaType.BTC_DOUBLE:
                value = Double.toString(readDouble());
                break;
        }
        return value + " (" + type + ": " + btc +")";
    }

    double readDouble()
    {
        try
        {
            return _input.readDouble();
        }
        catch (IOException e)
        {
            error(e);
            return 0.0;
        }
    }

    String SOAPArrayTypeString(SOAPArrayType t)
    {
        if (t == null)
            return "null";
        return QNameHelper.pretty(t.getQName()) + t.soap11DimensionString();
    }

    SOAPArrayType readSOAPArrayType()
    {
        QName qName = readQName();
        String dimensions = readString();
        if (qName == null)
            return null;
        return new SOAPArrayType(qName, dimensions);
    }

    QNameSet readQNameSet()
    {
        int flag = readShort();

        Set uriSet = new HashSet();
        int uriCount = readShort();
        for (int i = 0; i < uriCount; i++)
            uriSet.add(readString());

        Set qnameSet1 = new HashSet();
        int qncount1 = readShort();
        for (int i = 0; i < qncount1; i++)
            qnameSet1.add(readQName());

        Set qnameSet2 = new HashSet();
        int qncount2 = readShort();
        for (int i = 0; i < qncount2; i++)
            qnameSet2.add(readQName());

        if (flag == 1)
            return QNameSet.forSets(uriSet, null, qnameSet1, qnameSet2);
        else
            return QNameSet.forSets(null, uriSet, qnameSet2, qnameSet1);
    }

    byte[] readByteArray()
    {
        try
        {
            int len = _input.readShort();
            byte[] result = new byte[len];
            _input.readFully(result);
            return result;
        }
        catch (IOException e)
        {
            error(e);
            return null;
        }
    }

    BigInteger readBigInteger()
    {
        byte[] result = readByteArray();
        if (result.length == 0)
            return null;
        if (result.length == 1 && result[0] == 0)
            return BigInteger.ZERO;
        if (result.length == 1 && result[0] == 1)
            return BigInteger.ONE;
        return new BigInteger(result);
    }

    static final byte[] SINGLE_ZERO_BYTE = new byte[] { (byte)0 };

    private int _majorver;
    private int _minorver;
    private int _releaseno;


    protected boolean atLeast(int majorver, int minorver, int releaseno)
    {
        if (_majorver > majorver)
            return true;
        if (_majorver < majorver)
            return false;
        if (_minorver > minorver)
            return true;
        if (_minorver < minorver)
            return false;
        return (_releaseno >= releaseno);
    }

    protected boolean atMost(int majorver, int minorver, int releaseno)
    {
        if (_majorver > majorver)
            return false;
        if (_majorver < majorver)
            return true;
        if (_minorver > minorver)
            return false;
        if (_minorver < minorver)
            return true;
        return (_releaseno <= releaseno);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy