blob: 397322603fc2e956dbc71ba42521965dea133ee0 [file] [log] [blame]
/* 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 org.apache.xmlbeans.*;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.util.HexBin;
import org.apache.xmlbeans.impl.util.LongUTFDataInputStream;
import org.apache.xmlbeans.soap.SOAPArrayType;
import javax.xml.namespace.QName;
import java.io.*;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
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 (String arg : args) {
dump(new File(arg), true);
}
}
private static void dump(File file, boolean force) {
if (file.isDirectory()) {
File[] files = file.listFiles(
file1 -> file1.isDirectory() || file1.isFile() && file1.getName().endsWith(".xsb")
);
if (files != null) {
for (File value : files) {
dump(value, 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<? extends ZipEntry> e = zipFile.entries();
while (e.hasMoreElements()) {
ZipEntry entry = 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 LongUTFDataInputStream(stream);
_indent = indent;
_out = ostream;
}
void flush() {
_out.flush();
}
void emit(String str) {
_out.println(_indent + str);
flush();
}
void error(Exception e) {
_out.println(e.toString());
flush();
throw new IllegalStateException(e.getMessage(), e);
}
void error(String str) {
_out.println(str);
flush();
throw new IllegalStateException(str);
}
private String _indent;
private final 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) {
StringBuilder result = new StringBuilder();
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) {
StringBuilder result = new StringBuilder();
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) {
StringBuilder result = new StringBuilder();
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 final List<String> intsToStrings = new ArrayList<>();
private final Map<String, Integer> stringsToInts = new HashMap<>();
StringPool() {
intsToStrings.add(null);
}
String stringForCode(int code) {
if (code == 0) {
return null;
}
return intsToStrings.get(code);
}
int codeForString(String str) {
if (str == null) {
return 0;
}
Integer result = stringsToInts.get(str);
if (result == null) {
result = intsToStrings.size();
intsToStrings.add(str);
stringsToInts.put(str, result);
}
return result;
}
void readFrom(LongUTFDataInputStream 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.readLongUTF();
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.
LongUTFDataInputStream _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("<empty>");
}
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()), StandardCharsets.ISO_8859_1);
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<String> uriSet = new HashSet<>();
int uriCount = readShort();
for (int i = 0; i < uriCount; i++) {
uriSet.add(readString());
}
Set<QName> qnameSet1 = new HashSet<>();
int qncount1 = readShort();
for (int i = 0; i < qncount1; i++) {
qnameSet1.add(readQName());
}
Set<QName> 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);
}
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);
}
}