diff options
Diffstat (limited to 'sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java')
-rw-r--r-- | sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java | 1097 |
1 files changed, 1097 insertions, 0 deletions
diff --git a/sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java b/sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java new file mode 100644 index 0000000000..98de8fc0a7 --- /dev/null +++ b/sandbox/old/contrib/implementation-javascript/container/src/main/java/org/apache/tuscany/container/javascript/utils/xmlfromxsd/TuscanySampleXmlUtil.java @@ -0,0 +1,1097 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.tuscany.container.javascript.utils.xmlfromxsd; + +import org.apache.xmlbeans.SchemaType; +import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.SchemaParticle; +import org.apache.xmlbeans.SchemaLocalElement; +import org.apache.xmlbeans.SchemaProperty; +import org.apache.xmlbeans.GDuration; +import org.apache.xmlbeans.GDurationBuilder; +import org.apache.xmlbeans.GDate; +import org.apache.xmlbeans.GDateBuilder; +import org.apache.xmlbeans.XmlAnySimpleType; +import org.apache.xmlbeans.SimpleValue; +import org.apache.xmlbeans.XmlOptions; +import org.apache.xmlbeans.XmlObject; +import org.apache.xmlbeans.XmlInteger; +import org.apache.xmlbeans.XmlDate; +import org.apache.xmlbeans.XmlDateTime; +import org.apache.xmlbeans.XmlTime; +import org.apache.xmlbeans.XmlGYear; +import org.apache.xmlbeans.XmlGYearMonth; +import org.apache.xmlbeans.XmlGMonth; +import org.apache.xmlbeans.XmlGMonthDay; +import org.apache.xmlbeans.XmlGDay; +import org.apache.xmlbeans.XmlDecimal; +import org.apache.xmlbeans.XmlDuration; +import org.apache.xmlbeans.soap.SchemaWSDLArrayType; +import org.apache.xmlbeans.soap.SOAPArrayType; +import org.apache.xmlbeans.impl.util.Base64; +import org.apache.xmlbeans.impl.util.HexBin; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.Random; +import java.util.Set; +import java.util.HashSet; +import java.util.Arrays; + +import javax.xml.namespace.QName; + +/** + * This class is a replication of the XMLBeans SampleXMLutil class. This replication + * is required to overide the XMLBeans behaviour of this class in certain places. Since + * most methods of the XMLBeans implementation of this class is private, no overiding + * has been possible using inheritance. Hence this replication. + * + */ +public class TuscanySampleXmlUtil { + private static final String BLANK_STRING = " "; + + private boolean generate_sample_data = false; + + private boolean _soapEnc; + + private static final int MAX_ELEMENTS = 1000; + + private int _nElements; + + boolean flag = true; + + private TuscanySampleXmlUtil(boolean soapEnc) { + _soapEnc = soapEnc; + } + + public TuscanySampleXmlUtil() { + this(false); + } + + public String createSampleForType(SchemaType sType) { + XmlObject object = XmlObject.Factory.newInstance(); + XmlCursor cursor = object.newCursor(); + // Skip the document node + cursor.toNextToken(); + // Using the type and the cursor, call the utility method to get a + // sample XML payload for that Schema element + createSampleForType(sType, cursor); + // Cursor now contains the sample payload + // Pretty print the result. Note that the cursor is positioned at the + // end of the doc so we use the original xml object that the cursor was + // created upon to do the xmlText() against. + XmlOptions options = new XmlOptions(); + options.put(XmlOptions.SAVE_PRETTY_PRINT); + options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 2); + options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES); + String result = object.xmlText(options); + return result; + } + + Random _picker = new Random(1); + + /** + * Cursor position + * Before: + * <theElement>^</theElement> + * After: + * <theElement><lots of stuff/>^</theElement> + */ + private void createSampleForType(SchemaType stype, XmlCursor xmlc) { + if (_typeStack.contains(stype)) + //if ( !flag ) + return; + //else + // flag = false; + + _typeStack.add(stype); + + try { + if (stype.isSimpleType() || stype.isURType()) { + processSimpleType(stype, xmlc); + return; + } + + // complex Type + // <theElement>^</theElement> + processAttributes(stype, xmlc); + + // <theElement attri1="string">^</theElement> + switch (stype.getContentType()) { + case SchemaType.NOT_COMPLEX_TYPE: + case SchemaType.EMPTY_CONTENT: + // noop + break; + case SchemaType.SIMPLE_CONTENT: { + processSimpleType(stype, xmlc); + } + break; + case SchemaType.MIXED_CONTENT: + if (isGenerate_sample_data()) + xmlc.insertChars(pick(WORDS) + " "); + if (stype.getContentModel() != null) { + processParticle(stype.getContentModel(), xmlc, true); + } + if (isGenerate_sample_data()) + xmlc.insertChars(pick(WORDS)); + + break; + case SchemaType.ELEMENT_CONTENT: + if (stype.getContentModel() != null) { + processParticle(stype.getContentModel(), xmlc, false); + } + break; + } + } finally { + _typeStack.remove(_typeStack.size() - 1); + } + } + + private void processSimpleType(SchemaType stype, XmlCursor xmlc) { + String sample = sampleDataForSimpleType(stype); + xmlc.insertChars(sample); + + } + + private String sampleDataForSimpleType(SchemaType sType) { + if (isGenerate_sample_data()) { + return generateSampleDataForSimpleType(sType); + } else { + return BLANK_STRING; + } + } + + private String generateSampleDataForSimpleType(SchemaType sType) { + if (XmlObject.type.equals(sType)) + return "anyType"; + + if (XmlAnySimpleType.type.equals(sType)) + return "anySimpleType"; + + if (sType.getSimpleVariety() == SchemaType.LIST) { + SchemaType itemType = sType.getListItemType(); + StringBuffer sb = new StringBuffer(); + int length = pickLength(sType); + if (length > 0) + sb.append(sampleDataForSimpleType(itemType)); + for (int i = 1; i < length; i += 1) { + sb.append(' '); + sb.append(sampleDataForSimpleType(itemType)); + } + return sb.toString(); + } + + if (sType.getSimpleVariety() == SchemaType.UNION) { + SchemaType[] possibleTypes = sType.getUnionConstituentTypes(); + if (possibleTypes.length == 0) + return ""; + return sampleDataForSimpleType(possibleTypes[pick(possibleTypes.length)]); + } + + XmlAnySimpleType[] enumValues = sType.getEnumerationValues(); + if (enumValues != null && enumValues.length > 0) { + return enumValues[pick(enumValues.length)].getStringValue(); + } + + switch (sType.getPrimitiveType().getBuiltinTypeCode()) { + default: + case SchemaType.BTC_NOT_BUILTIN: + return ""; + + case SchemaType.BTC_ANY_TYPE: + case SchemaType.BTC_ANY_SIMPLE: + return "anything"; + + case SchemaType.BTC_BOOLEAN: + return pick(2) == 0 ? "true" : "false"; + + case SchemaType.BTC_BASE_64_BINARY: { + String result = null; + try { + result = new String(Base64.encode(formatToLength(pick(WORDS), sType).getBytes("utf-8"))); + } catch (java.io.UnsupportedEncodingException e) { /* Can't possibly happen */ + } + return result; + } + + case SchemaType.BTC_HEX_BINARY: + return HexBin.encode(formatToLength(pick(WORDS), sType)); + + case SchemaType.BTC_ANY_URI: + return formatToLength("http://www." + pick(DNS1) + "." + pick(DNS2) + "/" + pick(WORDS) + "/" + pick(WORDS), sType); + + case SchemaType.BTC_QNAME: + return formatToLength("qname", sType); + + case SchemaType.BTC_NOTATION: + return formatToLength("notation", sType); + + case SchemaType.BTC_FLOAT: + return "1.5E2"; + case SchemaType.BTC_DOUBLE: + return "1.051732E7"; + case SchemaType.BTC_DECIMAL: + switch (closestBuiltin(sType).getBuiltinTypeCode()) { + case SchemaType.BTC_SHORT: + return formatDecimal("1", sType); + case SchemaType.BTC_UNSIGNED_SHORT: + return formatDecimal("5", sType); + case SchemaType.BTC_BYTE: + return formatDecimal("2", sType); + case SchemaType.BTC_UNSIGNED_BYTE: + return formatDecimal("6", sType); + case SchemaType.BTC_INT: + return formatDecimal("3", sType); + case SchemaType.BTC_UNSIGNED_INT: + return formatDecimal("7", sType); + case SchemaType.BTC_LONG: + return formatDecimal("10", sType); + case SchemaType.BTC_UNSIGNED_LONG: + return formatDecimal("11", sType); + case SchemaType.BTC_INTEGER: + return formatDecimal("100", sType); + case SchemaType.BTC_NON_POSITIVE_INTEGER: + return formatDecimal("-200", sType); + case SchemaType.BTC_NEGATIVE_INTEGER: + return formatDecimal("-201", sType); + case SchemaType.BTC_NON_NEGATIVE_INTEGER: + return formatDecimal("200", sType); + case SchemaType.BTC_POSITIVE_INTEGER: + return formatDecimal("201", sType); + default: + case SchemaType.BTC_DECIMAL: + return formatDecimal("1000.00", sType); + } + + case SchemaType.BTC_STRING: { + String result; + switch (closestBuiltin(sType).getBuiltinTypeCode()) { + case SchemaType.BTC_STRING: + case SchemaType.BTC_NORMALIZED_STRING: + result = "string"; + break; + + case SchemaType.BTC_TOKEN: + result = "token"; + break; + + default: + result = "string"; + break; + } + + return formatToLength(result, sType); + } + + case SchemaType.BTC_DURATION: + return formatDuration(sType); + + 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: + return formatDate(sType); + } + } + + // a bit from the Aenid + public static final String[] WORDS = new String[] { "ipsa", "iovis", "rapidum", "iaculata", "e", "nubibus", "ignem", "disiecitque", "rates", + "evertitque", "aequora", "ventis", "illum", "exspirantem", "transfixo", "pectore", "flammas", "turbine", "corripuit", "scopuloque", + "infixit", "acuto", "ast", "ego", "quae", "divum", "incedo", "regina", "iovisque", "et", "soror", "et", "coniunx", "una", "cum", "gente", + "tot", "annos", "bella", "gero", "et", "quisquam", "numen", "iunonis", "adorat", "praeterea", "aut", "supplex", "aris", "imponet", + "honorem", "talia", "flammato", "secum", "dea", "corde", "volutans", "nimborum", "in", "patriam", "loca", "feta", "furentibus", + "austris", "aeoliam", "venit", "hic", "vasto", "rex", "aeolus", "antro", "luctantis", "ventos", "tempestatesque", "sonoras", "imperio", + "premit", "ac", "vinclis", "et", "carcere", "frenat", "illi", "indignantes", "magno", "cum", "murmure", "montis", "circum", "claustra", + "fremunt", "celsa", "sedet", "aeolus", "arce", "sceptra", "tenens", "mollitque", "animos", "et", "temperat", "iras", "ni", "faciat", + "maria", "ac", "terras", "caelumque", "profundum", "quippe", "ferant", "rapidi", "secum", "verrantque", "per", "auras", "sed", "pater", + "omnipotens", "speluncis", "abdidit", "atris", "hoc", "metuens", "molemque", "et", "montis", "insuper", "altos", "imposuit", "regemque", + "dedit", "qui", "foedere", "certo", "et", "premere", "et", "laxas", "sciret", "dare", "iussus", "habenas", }; + + private static final String[] DNS1 = new String[] { "corp", "your", "my", "sample", "company", "test", "any" }; + + private static final String[] DNS2 = new String[] { "com", "org", "com", "gov", "org", "com", "org", "com", "edu" }; + + private int pick(int n) { + return _picker.nextInt(n); + } + + private String pick(String[] a) { + return a[pick(a.length)]; + } + + private String pick(String[] a, int count) { + if (count <= 0) + return ""; + + int i = pick(a.length); + StringBuffer sb = new StringBuffer(a[i]); + while (count-- > 0) { + i += 1; + if (i >= a.length) + i = 0; + sb.append(' '); + sb.append(a[i]); + } + return sb.toString(); + } + + private String pickDigits(int digits) { + StringBuffer sb = new StringBuffer(); + while (digits-- > 0) + sb.append(Integer.toString(pick(10))); + return sb.toString(); + } + + private int pickLength(SchemaType sType) { + XmlInteger length = (XmlInteger) sType.getFacet(SchemaType.FACET_LENGTH); + if (length != null) + return length.getBigIntegerValue().intValue(); + XmlInteger min = (XmlInteger) sType.getFacet(SchemaType.FACET_MIN_LENGTH); + XmlInteger max = (XmlInteger) sType.getFacet(SchemaType.FACET_MAX_LENGTH); + int minInt, maxInt; + if (min == null) + minInt = 0; + else + minInt = min.getBigIntegerValue().intValue(); + if (max == null) + maxInt = Integer.MAX_VALUE; + else + maxInt = max.getBigIntegerValue().intValue(); + // We try to keep the length of the array within reasonable limits, + // at least 1 item and at most 3 if possible + if (minInt == 0 && maxInt >= 1) + minInt = 1; + if (maxInt > minInt + 2) + maxInt = minInt + 2; + if (maxInt < minInt) + maxInt = minInt; + return minInt + pick(maxInt - minInt); + } + + /** + * Formats a given string to the required length, using the following operations: + * - append the source string to itself as necessary to pass the minLength; + * - truncate the result of previous step, if necessary, to keep it within minLength. + */ + private String formatToLength(String s, SchemaType sType) { + String result = s; + try { + SimpleValue min = (SimpleValue) sType.getFacet(SchemaType.FACET_LENGTH); + if (min == null) + min = (SimpleValue) sType.getFacet(SchemaType.FACET_MIN_LENGTH); + if (min != null) { + int len = min.getIntValue(); + while (result.length() < len) + result = result + result; + } + SimpleValue max = (SimpleValue) sType.getFacet(SchemaType.FACET_LENGTH); + if (max == null) + max = (SimpleValue) sType.getFacet(SchemaType.FACET_MAX_LENGTH); + if (max != null) { + int len = max.getIntValue(); + if (result.length() > len) + result = result.substring(0, len); + } + } catch (Exception e) // intValue can be out of range + { + } + return result; + } + + private String formatDecimal(String start, SchemaType sType) { + BigDecimal result = new BigDecimal(start); + XmlDecimal xmlD; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null; + boolean minInclusive = true, maxInclusive = true; + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (xmlD != null) { + BigDecimal minExcl = xmlD.getBigDecimalValue(); + if (min == null || min.compareTo(minExcl) < 0) { + min = minExcl; + minInclusive = false; + } + } + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (xmlD != null) { + BigDecimal maxExcl = xmlD.getBigDecimalValue(); + if (max == null || max.compareTo(maxExcl) > 0) { + max = maxExcl; + maxInclusive = false; + } + } + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS); + int totalDigits = -1; + if (xmlD != null) { + totalDigits = xmlD.getBigDecimalValue().intValue(); + + StringBuffer sb = new StringBuffer(totalDigits); + for (int i = 0; i < totalDigits; i++) + sb.append('9'); + BigDecimal digitsLimit = new BigDecimal(sb.toString()); + if (max != null && max.compareTo(digitsLimit) > 0) { + max = digitsLimit; + maxInclusive = true; + } + digitsLimit = digitsLimit.negate(); + if (min != null && min.compareTo(digitsLimit) < 0) { + min = digitsLimit; + minInclusive = true; + } + } + + int sigMin = min == null ? 1 : result.compareTo(min); + int sigMax = max == null ? -1 : result.compareTo(max); + boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive; + boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive; + + // Compute the minimum increment + xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS); + int fractionDigits = -1; + BigDecimal increment; + if (xmlD == null) + increment = new BigDecimal(1); + else { + fractionDigits = xmlD.getBigDecimalValue().intValue(); + if (fractionDigits > 0) { + StringBuffer sb = new StringBuffer("0."); + for (int i = 1; i < fractionDigits; i++) + sb.append('0'); + sb.append('1'); + increment = new BigDecimal(sb.toString()); + } else + increment = new BigDecimal(1.0); + } + + if (minOk && maxOk) { + // OK + } else if (minOk && !maxOk) { + // TOO BIG + if (maxInclusive) + result = max; + else + result = max.subtract(increment); + } else if (!minOk && maxOk) { + // TOO SMALL + if (minInclusive) + result = min; + else + result = min.add(increment); + } else { + // MIN > MAX!! + } + + // We have the number + // Adjust the scale according to the totalDigits and fractionDigits + int digits = 0; + BigDecimal ONE = new BigDecimal(BigInteger.ONE); + for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++) + n = n.movePointLeft(1); + + if (fractionDigits > 0) + if (totalDigits >= 0) + result.setScale(Math.max(fractionDigits, totalDigits - digits)); + else + result.setScale(fractionDigits); + else if (fractionDigits == 0) + result.setScale(0); + + return result.toString(); + } + + private String formatDuration(SchemaType sType) { + XmlDuration d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + GDuration minInclusive = null; + if (d != null) + minInclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + GDuration maxInclusive = null; + if (d != null) + maxInclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + GDuration minExclusive = null; + if (d != null) + minExclusive = d.getGDurationValue(); + + d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + GDuration maxExclusive = null; + if (d != null) + maxExclusive = d.getGDurationValue(); + + GDurationBuilder gdurb = new GDurationBuilder(); + BigInteger min, max; + + gdurb.setSecond(pick(800000)); + gdurb.setMonth(pick(20)); + + // Years + // Months + // Days + // Hours + // Minutes + // Seconds + // Fractions + if (minInclusive != null) { + if (gdurb.getYear() < minInclusive.getYear()) + gdurb.setYear(minInclusive.getYear()); + if (gdurb.getMonth() < minInclusive.getMonth()) + gdurb.setMonth(minInclusive.getMonth()); + if (gdurb.getDay() < minInclusive.getDay()) + gdurb.setDay(minInclusive.getDay()); + if (gdurb.getHour() < minInclusive.getHour()) + gdurb.setHour(minInclusive.getHour()); + if (gdurb.getMinute() < minInclusive.getMinute()) + gdurb.setMinute(minInclusive.getMinute()); + if (gdurb.getSecond() < minInclusive.getSecond()) + gdurb.setSecond(minInclusive.getSecond()); + if (gdurb.getFraction().compareTo(minInclusive.getFraction()) < 0) + gdurb.setFraction(minInclusive.getFraction()); + } + + if (maxInclusive != null) { + if (gdurb.getYear() > maxInclusive.getYear()) + gdurb.setYear(maxInclusive.getYear()); + if (gdurb.getMonth() > maxInclusive.getMonth()) + gdurb.setMonth(maxInclusive.getMonth()); + if (gdurb.getDay() > maxInclusive.getDay()) + gdurb.setDay(maxInclusive.getDay()); + if (gdurb.getHour() > maxInclusive.getHour()) + gdurb.setHour(maxInclusive.getHour()); + if (gdurb.getMinute() > maxInclusive.getMinute()) + gdurb.setMinute(maxInclusive.getMinute()); + if (gdurb.getSecond() > maxInclusive.getSecond()) + gdurb.setSecond(maxInclusive.getSecond()); + if (gdurb.getFraction().compareTo(maxInclusive.getFraction()) > 0) + gdurb.setFraction(maxInclusive.getFraction()); + } + + if (minExclusive != null) { + if (gdurb.getYear() <= minExclusive.getYear()) + gdurb.setYear(minExclusive.getYear() + 1); + if (gdurb.getMonth() <= minExclusive.getMonth()) + gdurb.setMonth(minExclusive.getMonth() + 1); + if (gdurb.getDay() <= minExclusive.getDay()) + gdurb.setDay(minExclusive.getDay() + 1); + if (gdurb.getHour() <= minExclusive.getHour()) + gdurb.setHour(minExclusive.getHour() + 1); + if (gdurb.getMinute() <= minExclusive.getMinute()) + gdurb.setMinute(minExclusive.getMinute() + 1); + if (gdurb.getSecond() <= minExclusive.getSecond()) + gdurb.setSecond(minExclusive.getSecond() + 1); + if (gdurb.getFraction().compareTo(minExclusive.getFraction()) <= 0) + gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal(0.001))); + } + + if (maxExclusive != null) { + if (gdurb.getYear() > maxExclusive.getYear()) + gdurb.setYear(maxExclusive.getYear()); + if (gdurb.getMonth() > maxExclusive.getMonth()) + gdurb.setMonth(maxExclusive.getMonth()); + if (gdurb.getDay() > maxExclusive.getDay()) + gdurb.setDay(maxExclusive.getDay()); + if (gdurb.getHour() > maxExclusive.getHour()) + gdurb.setHour(maxExclusive.getHour()); + if (gdurb.getMinute() > maxExclusive.getMinute()) + gdurb.setMinute(maxExclusive.getMinute()); + if (gdurb.getSecond() > maxExclusive.getSecond()) + gdurb.setSecond(maxExclusive.getSecond()); + if (gdurb.getFraction().compareTo(maxExclusive.getFraction()) > 0) + gdurb.setFraction(maxExclusive.getFraction()); + } + + gdurb.normalize(); + return gdurb.toString(); + } + + private String formatDate(SchemaType sType) { + GDateBuilder gdateb = new GDateBuilder(new Date(1000L * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365 * 24 * 60 * 60 * 1000)); + GDate min = null, max = null; + GDate temp; + + // Find the min and the max according to the type + switch (sType.getPrimitiveType().getBuiltinTypeCode()) { + case SchemaType.BTC_DATE_TIME: { + XmlDateTime x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_TIME: { + XmlTime x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_DATE: { + XmlDate x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_YEAR_MONTH: { + XmlGYearMonth x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_YEAR: { + XmlGYear x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_MONTH_DAY: { + XmlGMonthDay x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_DAY: { + XmlGDay x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + case SchemaType.BTC_G_MONTH: { + XmlGMonth x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE); + if (x != null) + min = x.getGDateValue(); + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE); + if (x != null) + if (min == null || min.compareToGDate(x.getGDateValue()) <= 0) + min = x.getGDateValue(); + + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE); + if (x != null) + max = x.getGDateValue(); + x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE); + if (x != null) + if (max == null || max.compareToGDate(x.getGDateValue()) >= 0) + max = x.getGDateValue(); + break; + } + } + + if (min != null && max == null) { + if (min.compareToGDate(gdateb) >= 0) { + // Reset the date to min + (1-8) hours + Calendar c = gdateb.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, pick(8)); + gdateb = new GDateBuilder(c); + } + } else if (min == null && max != null) { + if (max.compareToGDate(gdateb) <= 0) { + // Reset the date to max - (1-8) hours + Calendar c = gdateb.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, 0 - pick(8)); + gdateb = new GDateBuilder(c); + } + } else if (min != null && max != null) { + if (min.compareToGDate(gdateb) >= 0 || max.compareToGDate(gdateb) <= 0) { + // Find a date between the two + Calendar c = min.getCalendar(); + Calendar cmax = max.getCalendar(); + c.add(Calendar.HOUR_OF_DAY, 1); + if (c.after(cmax)) { + c.add(Calendar.HOUR_OF_DAY, -1); + c.add(Calendar.MINUTE, 1); + if (c.after(cmax)) { + c.add(Calendar.MINUTE, -1); + c.add(Calendar.SECOND, 1); + if (c.after(cmax)) { + c.add(Calendar.SECOND, -1); + c.add(Calendar.MILLISECOND, 1); + if (c.after(cmax)) + c.add(Calendar.MILLISECOND, -1); + } + } + } + gdateb = new GDateBuilder(c); + } + } + + gdateb.setBuiltinTypeCode(sType.getPrimitiveType().getBuiltinTypeCode()); + if (pick(2) == 0) + gdateb.clearTimeZone(); + return gdateb.toString(); + } + + private SchemaType closestBuiltin(SchemaType sType) { + while (!sType.isBuiltinType()) + sType = sType.getBaseType(); + return sType; + } + + /** + * Cracks a combined QName of the form URL:localname + */ + public static QName crackQName(String qName) { + String ns; + String name; + + int index = qName.lastIndexOf(':'); + if (index >= 0) { + ns = qName.substring(0, index); + name = qName.substring(index + 1); + } else { + ns = ""; + name = qName; + } + + return new QName(ns, name); + } + + /** + * Cursor position: + * Before this call: + * <outer><foo/>^</outer> (cursor at the ^) + * After this call: + * <<outer><foo/><bar/>som text<etc/>^</outer> + */ + private void processParticle(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + int loop = determineMinMaxForSample(sp, xmlc); + + while (loop-- > 0) { + switch (sp.getParticleType()) { + case (SchemaParticle.ELEMENT): + processElement(sp, xmlc, mixed); + break; + case (SchemaParticle.SEQUENCE): + processSequence(sp, xmlc, mixed); + break; + case (SchemaParticle.CHOICE): + processChoice(sp, xmlc, mixed); + break; + case (SchemaParticle.ALL): + processAll(sp, xmlc, mixed); + break; + case (SchemaParticle.WILDCARD): + processWildCard(sp, xmlc, mixed); + break; + default: + // throw new Exception("No Match on Schema Particle Type: " + String.valueOf(sp.getParticleType())); + } + } + } + + private int determineMinMaxForSample(SchemaParticle sp, XmlCursor xmlc) { + int minOccurs = sp.getIntMinOccurs(); + int maxOccurs = sp.getIntMaxOccurs(); + + if (minOccurs == maxOccurs) + return minOccurs; + + int result = minOccurs; + if (result == 0 && _nElements < MAX_ELEMENTS) + result = 1; + + if (sp.getParticleType() != SchemaParticle.ELEMENT) + return result; + + // it probably only makes sense to put comments in front of individual elements that repeat + + if (sp.getMaxOccurs() == null) { + // xmlc.insertComment("The next " + getItemNameOrType(sp, xmlc) + " may be repeated " + minOccurs + " or more times"); + if (minOccurs == 0) + xmlc.insertComment("Zero or more repetitions:"); + else + xmlc.insertComment(minOccurs + " or more repetitions:"); + } else if (sp.getIntMaxOccurs() > 1) { + xmlc.insertComment(minOccurs + " to " + String.valueOf(sp.getMaxOccurs()) + " repetitions:"); + } else { + xmlc.insertComment("Optional:"); + } + return result; + } + + /* + Return a name for the element or the particle type to use in the comment for minoccurs, max occurs + */ + private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc) { + String elementOrTypeName = null; + if (sp.getParticleType() == SchemaParticle.ELEMENT) { + elementOrTypeName = "Element (" + sp.getName().getLocalPart() + ")"; + } else { + elementOrTypeName = printParticleType(sp.getParticleType()); + } + return elementOrTypeName; + } + + private void processElement(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + // cast as schema local element + SchemaLocalElement element = (SchemaLocalElement) sp; + /// ^ -> <elemenname></elem>^ + if (_soapEnc) + xmlc.insertElement(element.getName().getLocalPart()); // soap encoded? drop namespaces. + else + xmlc.insertElement(element.getName().getLocalPart(), element.getName().getNamespaceURI()); + _nElements++; + /// -> <elem>^</elem> + xmlc.toPrevToken(); + // -> <elem>stuff^</elem> + createSampleForType(element.getType(), xmlc); + // -> <elem>stuff</elem>^ + xmlc.toNextToken(); + + } + + private void moveToken(int numToMove, XmlCursor xmlc) { + for (int i = 0; i < Math.abs(numToMove); i++) { + if (numToMove < 0) { + xmlc.toPrevToken(); + } else { + xmlc.toNextToken(); + } + } + } + + private static final String formatQName(XmlCursor xmlc, QName qName) { + XmlCursor parent = xmlc.newCursor(); + parent.toParent(); + String prefix = parent.prefixForNamespace(qName.getNamespaceURI()); + parent.dispose(); + String name; + if (prefix == null || prefix.length() == 0) + name = qName.getLocalPart(); + else + name = prefix + ":" + qName.getLocalPart(); + return name; + } + + private static final QName HREF = new QName("href"); + + private static final QName ID = new QName("id"); + + private static final QName XSI_TYPE = new QName("http://www.w3.org/2001/XMLSchema-instance", "type"); + + private static final QName ENC_ARRAYTYPE = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType"); + + private static final QName ENC_OFFSET = new QName("http://schemas.xmlsoap.org/soap/encoding/", "offset"); + + private static final Set SKIPPED_SOAP_ATTRS = new HashSet(Arrays.asList(new QName[] { HREF, ID, ENC_OFFSET })); + + private void processAttributes(SchemaType stype, XmlCursor xmlc) { + if (_soapEnc) { + QName typeName = stype.getName(); + if (typeName != null) { + xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(xmlc, typeName)); + } + } + + SchemaProperty[] attrProps = stype.getAttributeProperties(); + for (int i = 0; i < attrProps.length; i++) { + SchemaProperty attr = attrProps[i]; + if (_soapEnc) { + if (SKIPPED_SOAP_ATTRS.contains(attr.getName())) + continue; + if (ENC_ARRAYTYPE.equals(attr.getName())) { + SOAPArrayType arrayType = ((SchemaWSDLArrayType) stype.getAttributeModel().getAttribute(attr.getName())).getWSDLArrayType(); + if (arrayType != null) + xmlc.insertAttributeWithValue(attr.getName(), formatQName(xmlc, arrayType.getQName()) + arrayType.soap11DimensionString()); + continue; + } + } + String defaultValue = attr.getDefaultText(); + xmlc.insertAttributeWithValue(attr.getName(), defaultValue == null ? sampleDataForSimpleType(attr.getType()) : defaultValue); + } + } + + private void processSequence(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + SchemaParticle[] spc = sp.getParticleChildren(); + for (int i = 0; i < spc.length; i++) { + /// <parent>maybestuff^</parent> + processParticle(spc[i], xmlc, mixed); + //<parent>maybestuff...morestuff^</parent> + if (mixed && i < spc.length - 1) { + if (isGenerate_sample_data()) { + xmlc.insertChars(pick(WORDS)); + } else { + xmlc.insertChars(""); + } + } + } + } + + private void processChoice(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + SchemaParticle[] spc = sp.getParticleChildren(); + xmlc.insertComment("You have a CHOICE of the next " + String.valueOf(spc.length) + " items at this level"); + for (int i = 0; i < spc.length; i++) { + processParticle(spc[i], xmlc, mixed); + } + } + + private void processAll(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + SchemaParticle[] spc = sp.getParticleChildren(); + // xmlc.insertComment("You may enter the following " + String.valueOf(spc.length) + " items in any order"); + for (int i = 0; i < spc.length; i++) { + processParticle(spc[i], xmlc, mixed); + if (mixed && i < spc.length - 1) + xmlc.insertChars(pick(WORDS)); + } + } + + private void processWildCard(SchemaParticle sp, XmlCursor xmlc, boolean mixed) { + xmlc.insertComment("You may enter ANY elements at this point"); + xmlc.insertElement("AnyElement"); + } + + /** + * This method will get the base type for the schema type + */ + + private static QName getClosestName(SchemaType sType) { + while (sType.getName() == null) + sType = sType.getBaseType(); + + return sType.getName(); + } + + private String printParticleType(int particleType) { + StringBuffer returnParticleType = new StringBuffer(); + returnParticleType.append("Schema Particle Type: "); + + switch (particleType) { + case SchemaParticle.ALL: + returnParticleType.append("ALL\n"); + break; + case SchemaParticle.CHOICE: + returnParticleType.append("CHOICE\n"); + break; + case SchemaParticle.ELEMENT: + returnParticleType.append("ELEMENT\n"); + break; + case SchemaParticle.SEQUENCE: + returnParticleType.append("SEQUENCE\n"); + break; + case SchemaParticle.WILDCARD: + returnParticleType.append("WILDCARD\n"); + break; + default: + returnParticleType.append("Schema Particle Type Unknown"); + break; + } + + return returnParticleType.toString(); + } + + private ArrayList _typeStack = new ArrayList(); + + public boolean isGenerate_sample_data() { + return generate_sample_data; + } + + public void setGenerate_sample_data(boolean generate_sample_data) { + this.generate_sample_data = generate_sample_data; + } +} |