0001: /* Copyright 2004 The Apache Software Foundation
0002: *
0003: * Licensed under the Apache License, Version 2.0 (the "License");
0004: * you may not use this file except in compliance with the License.
0005: * You may obtain a copy of the License at
0006: *
0007: * http://www.apache.org/licenses/LICENSE-2.0
0008: *
0009: * Unless required by applicable law or agreed to in writing, software
0010: * distributed under the License is distributed on an "AS IS" BASIS,
0011: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0012: * See the License for the specific language governing permissions and
0013: * limitations under the License.
0014: */
0015:
0016: package com.eviware.soapui.impl.wsdl.support.xsd;
0017:
0018: import java.math.BigDecimal;
0019: import java.math.BigInteger;
0020: import java.util.ArrayList;
0021: import java.util.Arrays;
0022: import java.util.Calendar;
0023: import java.util.Date;
0024: import java.util.HashSet;
0025: import java.util.Random;
0026: import java.util.Set;
0027:
0028: import javax.xml.namespace.QName;
0029:
0030: import org.apache.xmlbeans.GDate;
0031: import org.apache.xmlbeans.GDateBuilder;
0032: import org.apache.xmlbeans.GDuration;
0033: import org.apache.xmlbeans.GDurationBuilder;
0034: import org.apache.xmlbeans.SchemaLocalElement;
0035: import org.apache.xmlbeans.SchemaParticle;
0036: import org.apache.xmlbeans.SchemaProperty;
0037: import org.apache.xmlbeans.SchemaType;
0038: import org.apache.xmlbeans.SimpleValue;
0039: import org.apache.xmlbeans.XmlAnySimpleType;
0040: import org.apache.xmlbeans.XmlCursor;
0041: import org.apache.xmlbeans.XmlDate;
0042: import org.apache.xmlbeans.XmlDateTime;
0043: import org.apache.xmlbeans.XmlDecimal;
0044: import org.apache.xmlbeans.XmlDuration;
0045: import org.apache.xmlbeans.XmlGDay;
0046: import org.apache.xmlbeans.XmlGMonth;
0047: import org.apache.xmlbeans.XmlGMonthDay;
0048: import org.apache.xmlbeans.XmlGYear;
0049: import org.apache.xmlbeans.XmlGYearMonth;
0050: import org.apache.xmlbeans.XmlInteger;
0051: import org.apache.xmlbeans.XmlObject;
0052: import org.apache.xmlbeans.XmlOptions;
0053: import org.apache.xmlbeans.XmlTime;
0054: import org.apache.xmlbeans.impl.util.Base64;
0055: import org.apache.xmlbeans.impl.util.HexBin;
0056: import org.apache.xmlbeans.soap.SOAPArrayType;
0057: import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
0058:
0059: import com.eviware.soapui.SoapUI;
0060: import com.eviware.soapui.settings.WsdlSettings;
0061:
0062: /**
0063: * XmlBeans class for generating XML from XML Schemas
0064: */
0065:
0066: public class SampleXmlUtil {
0067: private boolean _soapEnc;
0068: private boolean _exampleContent = false;
0069: private boolean _typeComment = false;
0070: private Set<QName> excludedTypes = new HashSet<QName>();
0071:
0072: public SampleXmlUtil(boolean soapEnc) {
0073: _soapEnc = soapEnc;
0074: _exampleContent = SoapUI.getSettings().getBoolean(
0075: WsdlSettings.XML_GENERATION_TYPE_EXAMPLE_VALUE);
0076: _typeComment = SoapUI.getSettings().getBoolean(
0077: WsdlSettings.XML_GENERATION_TYPE_COMMENT_TYPE);
0078:
0079: excludedTypes.addAll(SoapUI.getExcludedTypes());
0080: }
0081:
0082: public boolean isSoapEnc() {
0083: return _soapEnc;
0084: }
0085:
0086: public boolean isExampleContent() {
0087: return _exampleContent;
0088: }
0089:
0090: public void setExampleContent(boolean content) {
0091: _exampleContent = content;
0092: }
0093:
0094: public boolean isTypeComment() {
0095: return _typeComment;
0096: }
0097:
0098: public void setTypeComment(boolean comment) {
0099: _typeComment = comment;
0100: }
0101:
0102: public String createSample(SchemaType sType) {
0103: XmlObject object = XmlObject.Factory.newInstance();
0104: XmlCursor cursor = object.newCursor();
0105: // Skip the document node
0106: cursor.toNextToken();
0107: // Using the type and the cursor, call the utility method to get a
0108: // sample XML payload for that Schema element
0109: createSampleForType(sType, cursor);
0110: // Cursor now contains the sample payload
0111: // Pretty print the result. Note that the cursor is positioned at the
0112: // end of the doc so we use the original xml object that the cursor was
0113: // created upon to do the xmlText() against.
0114:
0115: cursor.dispose();
0116:
0117: XmlOptions options = new XmlOptions();
0118: options.put(XmlOptions.SAVE_PRETTY_PRINT);
0119: options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 3);
0120: options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES);
0121: options.setSaveOuter();
0122: String result = object.xmlText(options);
0123:
0124: return result;
0125: }
0126:
0127: public static String createSampleForType(SchemaType sType) {
0128: XmlObject object = XmlObject.Factory.newInstance();
0129: XmlCursor cursor = object.newCursor();
0130: // Skip the document node
0131: cursor.toNextToken();
0132: // Using the type and the cursor, call the utility method to get a
0133: // sample XML payload for that Schema element
0134: new SampleXmlUtil(false).createSampleForType(sType, cursor);
0135: // Cursor now contains the sample payload
0136: // Pretty print the result. Note that the cursor is positioned at the
0137: // end of the doc so we use the original xml object that the cursor was
0138: // created upon to do the xmlText() against.
0139:
0140: cursor.dispose();
0141: XmlOptions options = new XmlOptions();
0142: options.put(XmlOptions.SAVE_PRETTY_PRINT);
0143: options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 3);
0144: options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES);
0145: options.setSaveOuter();
0146: String result = object.xmlText(options);
0147:
0148: return result;
0149: }
0150:
0151: Random _picker = new Random(1);
0152:
0153: private boolean ignoreOptional;
0154:
0155: /**
0156: * Cursor position
0157: * Before:
0158: * <theElement>^</theElement>
0159: * After:
0160: * <theElement><lots of stuff/>^</theElement>
0161: */
0162: @SuppressWarnings("unchecked")
0163: public void createSampleForType(SchemaType stype, XmlCursor xmlc) {
0164: QName nm = stype.getName();
0165: if (nm == null && stype.getContainerField() != null)
0166: nm = stype.getContainerField().getName();
0167:
0168: if (nm != null && excludedTypes.contains(nm)) {
0169: xmlc.insertComment("Ignoring type [" + nm + "]");
0170: return;
0171: }
0172:
0173: if (_typeStack.contains(stype))
0174: return;
0175:
0176: _typeStack.add(stype);
0177:
0178: try {
0179: if (stype.isSimpleType() || stype.isURType()) {
0180: processSimpleType(stype, xmlc);
0181: return;
0182: }
0183:
0184: // complex Type
0185: // <theElement>^</theElement>
0186: processAttributes(stype, xmlc);
0187:
0188: // <theElement attri1="string">^</theElement>
0189: switch (stype.getContentType()) {
0190: case SchemaType.NOT_COMPLEX_TYPE:
0191: case SchemaType.EMPTY_CONTENT:
0192: // noop
0193: break;
0194: case SchemaType.SIMPLE_CONTENT: {
0195: processSimpleType(stype, xmlc);
0196: }
0197: break;
0198: case SchemaType.MIXED_CONTENT:
0199: xmlc.insertChars(pick(WORDS) + " ");
0200: if (stype.getContentModel() != null) {
0201: processParticle(stype.getContentModel(), xmlc, true);
0202: }
0203: xmlc.insertChars(pick(WORDS));
0204: break;
0205: case SchemaType.ELEMENT_CONTENT:
0206: if (stype.getContentModel() != null) {
0207: processParticle(stype.getContentModel(), xmlc,
0208: false);
0209: }
0210: break;
0211: }
0212: } finally {
0213: _typeStack.remove(_typeStack.size() - 1);
0214: }
0215: }
0216:
0217: private void processSimpleType(SchemaType stype, XmlCursor xmlc) {
0218: if (_soapEnc) {
0219: QName typeName = stype.getName();
0220: if (typeName != null) {
0221: xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(
0222: xmlc, typeName));
0223: }
0224: }
0225:
0226: String sample = sampleDataForSimpleType(stype);
0227: xmlc.insertChars(sample);
0228: }
0229:
0230: private String sampleDataForSimpleType(SchemaType sType) {
0231: // swaRef
0232: if (sType.getName() != null) {
0233: if (sType.getName().equals(
0234: new QName("http://ws-i.org/profiles/basic/1.1/xsd",
0235: "swaRef")))
0236: return "cid:" + System.currentTimeMillis();
0237:
0238: // xmime base64
0239: if (sType.getName().equals(
0240: new QName("http://www.w3.org/2005/05/xmlmime",
0241: "base64Binary")))
0242: return "cid:" + System.currentTimeMillis();
0243:
0244: // xmime hexBinary
0245: if (sType.getName().equals(
0246: new QName("http://www.w3.org/2005/05/xmlmime",
0247: "hexBinary")))
0248: return "cid:" + System.currentTimeMillis();
0249: }
0250:
0251: // if( sType != null )
0252: if (!_exampleContent)
0253: return "?";
0254:
0255: if (XmlObject.type.equals(sType))
0256: return "anyType";
0257:
0258: if (XmlAnySimpleType.type.equals(sType))
0259: return "anySimpleType";
0260:
0261: if (sType.getSimpleVariety() == SchemaType.LIST) {
0262: SchemaType itemType = sType.getListItemType();
0263: StringBuffer sb = new StringBuffer();
0264: int length = pickLength(sType);
0265: if (length > 0)
0266: sb.append(sampleDataForSimpleType(itemType));
0267: for (int i = 1; i < length; i += 1) {
0268: sb.append(' ');
0269: sb.append(sampleDataForSimpleType(itemType));
0270: }
0271: return sb.toString();
0272: }
0273:
0274: if (sType.getSimpleVariety() == SchemaType.UNION) {
0275: SchemaType[] possibleTypes = sType
0276: .getUnionConstituentTypes();
0277: if (possibleTypes.length == 0)
0278: return "";
0279: return sampleDataForSimpleType(possibleTypes[pick(possibleTypes.length)]);
0280: }
0281:
0282: XmlAnySimpleType[] enumValues = sType.getEnumerationValues();
0283: if (enumValues != null && enumValues.length > 0) {
0284: return enumValues[pick(enumValues.length)].getStringValue();
0285: }
0286:
0287: switch (sType.getPrimitiveType().getBuiltinTypeCode()) {
0288: default:
0289: case SchemaType.BTC_NOT_BUILTIN:
0290: return "";
0291:
0292: case SchemaType.BTC_ANY_TYPE:
0293: case SchemaType.BTC_ANY_SIMPLE:
0294: return "anything";
0295:
0296: case SchemaType.BTC_BOOLEAN:
0297: return pick(2) == 0 ? "true" : "false";
0298:
0299: case SchemaType.BTC_BASE_64_BINARY: {
0300: String result = null;
0301: try {
0302: result = new String(Base64.encode(formatToLength(
0303: pick(WORDS), sType).getBytes("utf-8")));
0304: } catch (java.io.UnsupportedEncodingException e) {
0305: }
0306: return result;
0307: }
0308:
0309: case SchemaType.BTC_HEX_BINARY:
0310: return HexBin.encode(formatToLength(pick(WORDS), sType));
0311:
0312: case SchemaType.BTC_ANY_URI:
0313: return formatToLength("http://www." + pick(DNS1) + "."
0314: + pick(DNS2) + "/" + pick(WORDS) + "/"
0315: + pick(WORDS), sType);
0316:
0317: case SchemaType.BTC_QNAME:
0318: return formatToLength("qname", sType);
0319:
0320: case SchemaType.BTC_NOTATION:
0321: return formatToLength("notation", sType);
0322:
0323: case SchemaType.BTC_FLOAT:
0324: return "1.5E2";
0325: case SchemaType.BTC_DOUBLE:
0326: return "1.051732E7";
0327: case SchemaType.BTC_DECIMAL:
0328: switch (closestBuiltin(sType).getBuiltinTypeCode()) {
0329: case SchemaType.BTC_SHORT:
0330: return formatDecimal("1", sType);
0331: case SchemaType.BTC_UNSIGNED_SHORT:
0332: return formatDecimal("5", sType);
0333: case SchemaType.BTC_BYTE:
0334: return formatDecimal("2", sType);
0335: case SchemaType.BTC_UNSIGNED_BYTE:
0336: return formatDecimal("6", sType);
0337: case SchemaType.BTC_INT:
0338: return formatDecimal("3", sType);
0339: case SchemaType.BTC_UNSIGNED_INT:
0340: return formatDecimal("7", sType);
0341: case SchemaType.BTC_LONG:
0342: return formatDecimal("10", sType);
0343: case SchemaType.BTC_UNSIGNED_LONG:
0344: return formatDecimal("11", sType);
0345: case SchemaType.BTC_INTEGER:
0346: return formatDecimal("100", sType);
0347: case SchemaType.BTC_NON_POSITIVE_INTEGER:
0348: return formatDecimal("-200", sType);
0349: case SchemaType.BTC_NEGATIVE_INTEGER:
0350: return formatDecimal("-201", sType);
0351: case SchemaType.BTC_NON_NEGATIVE_INTEGER:
0352: return formatDecimal("200", sType);
0353: case SchemaType.BTC_POSITIVE_INTEGER:
0354: return formatDecimal("201", sType);
0355: default:
0356: case SchemaType.BTC_DECIMAL:
0357: return formatDecimal("1000.00", sType);
0358: }
0359:
0360: case SchemaType.BTC_STRING: {
0361: String result;
0362: switch (closestBuiltin(sType).getBuiltinTypeCode()) {
0363: case SchemaType.BTC_STRING:
0364: case SchemaType.BTC_NORMALIZED_STRING:
0365: result = pick(WORDS, _picker.nextInt(3));
0366: break;
0367:
0368: case SchemaType.BTC_TOKEN:
0369: result = pick(WORDS, _picker.nextInt(3));
0370: break;
0371:
0372: default:
0373: result = pick(WORDS, _picker.nextInt(3));
0374: break;
0375: }
0376:
0377: return formatToLength(result, sType);
0378: }
0379:
0380: case SchemaType.BTC_DURATION:
0381: return formatDuration(sType);
0382:
0383: case SchemaType.BTC_DATE_TIME:
0384: case SchemaType.BTC_TIME:
0385: case SchemaType.BTC_DATE:
0386: case SchemaType.BTC_G_YEAR_MONTH:
0387: case SchemaType.BTC_G_YEAR:
0388: case SchemaType.BTC_G_MONTH_DAY:
0389: case SchemaType.BTC_G_DAY:
0390: case SchemaType.BTC_G_MONTH:
0391: return formatDate(sType);
0392:
0393: }
0394: }
0395:
0396: // a bit from the Aenid
0397: public static final String[] WORDS = new String[] { "ipsa",
0398: "iovis", "rapidum", "iaculata", "e", "nubibus", "ignem",
0399: "disiecitque", "rates", "evertitque", "aequora", "ventis",
0400: "illum", "exspirantem", "transfixo", "pectore", "flammas",
0401: "turbine", "corripuit", "scopuloque", "infixit", "acuto",
0402: "ast", "ego", "quae", "divum", "incedo", "regina",
0403: "iovisque", "et", "soror", "et", "coniunx", "una", "cum",
0404: "gente", "tot", "annos", "bella", "gero", "et", "quisquam",
0405: "numen", "iunonis", "adorat", "praeterea", "aut",
0406: "supplex", "aris", "imponet", "honorem", "talia",
0407: "flammato", "secum", "dea", "corde", "volutans",
0408: "nimborum", "in", "patriam", "loca", "feta", "furentibus",
0409: "austris", "aeoliam", "venit", "hic", "vasto", "rex",
0410: "aeolus", "antro", "luctantis", "ventos", "tempestatesque",
0411: "sonoras", "imperio", "premit", "ac", "vinclis", "et",
0412: "carcere", "frenat", "illi", "indignantes", "magno", "cum",
0413: "murmure", "montis", "circum", "claustra", "fremunt",
0414: "celsa", "sedet", "aeolus", "arce", "sceptra", "tenens",
0415: "mollitque", "animos", "et", "temperat", "iras", "ni",
0416: "faciat", "maria", "ac", "terras", "caelumque",
0417: "profundum", "quippe", "ferant", "rapidi", "secum",
0418: "verrantque", "per", "auras", "sed", "pater", "omnipotens",
0419: "speluncis", "abdidit", "atris", "hoc", "metuens",
0420: "molemque", "et", "montis", "insuper", "altos", "imposuit",
0421: "regemque", "dedit", "qui", "foedere", "certo", "et",
0422: "premere", "et", "laxas", "sciret", "dare", "iussus",
0423: "habenas", };
0424:
0425: private static final String[] DNS1 = new String[] { "corp", "your",
0426: "my", "sample", "company", "test", "any" };
0427: private static final String[] DNS2 = new String[] { "com", "org",
0428: "com", "gov", "org", "com", "org", "com", "edu" };
0429:
0430: private int pick(int n) {
0431: return _picker.nextInt(n);
0432: }
0433:
0434: private String pick(String[] a) {
0435: return a[pick(a.length)];
0436: }
0437:
0438: private String pick(String[] a, int count) {
0439: if (count <= 0)
0440: count = 1;
0441: // return "";
0442:
0443: int i = pick(a.length);
0444: StringBuffer sb = new StringBuffer(a[i]);
0445: while (count-- > 0) {
0446: i += 1;
0447: if (i >= a.length)
0448: i = 0;
0449: sb.append(' ');
0450: sb.append(a[i]);
0451: }
0452: return sb.toString();
0453: }
0454:
0455: private String pickDigits(int digits) {
0456: StringBuffer sb = new StringBuffer();
0457: while (digits-- > 0)
0458: sb.append(Integer.toString(pick(10)));
0459: return sb.toString();
0460: }
0461:
0462: private int pickLength(SchemaType sType) {
0463: XmlInteger length = (XmlInteger) sType
0464: .getFacet(SchemaType.FACET_LENGTH);
0465: if (length != null)
0466: return length.getBigIntegerValue().intValue();
0467: XmlInteger min = (XmlInteger) sType
0468: .getFacet(SchemaType.FACET_MIN_LENGTH);
0469: XmlInteger max = (XmlInteger) sType
0470: .getFacet(SchemaType.FACET_MAX_LENGTH);
0471: int minInt, maxInt;
0472: if (min == null)
0473: minInt = 0;
0474: else
0475: minInt = min.getBigIntegerValue().intValue();
0476: if (max == null)
0477: maxInt = Integer.MAX_VALUE;
0478: else
0479: maxInt = max.getBigIntegerValue().intValue();
0480: // We try to keep the length of the array within reasonable limits,
0481: // at least 1 item and at most 3 if possible
0482: if (minInt == 0 && maxInt >= 1)
0483: minInt = 1;
0484: if (maxInt > minInt + 2)
0485: maxInt = minInt + 2;
0486: if (maxInt < minInt)
0487: maxInt = minInt;
0488: return minInt + pick(maxInt - minInt);
0489: }
0490:
0491: /**
0492: * Formats a given string to the required length, using the following operations:
0493: * - append the source string to itself as necessary to pass the minLength;
0494: * - truncate the result of previous step, if necessary, to keep it within minLength.
0495: */
0496: private String formatToLength(String s, SchemaType sType) {
0497: String result = s;
0498: try {
0499: SimpleValue min = (SimpleValue) sType
0500: .getFacet(SchemaType.FACET_LENGTH);
0501: if (min == null)
0502: min = (SimpleValue) sType
0503: .getFacet(SchemaType.FACET_MIN_LENGTH);
0504: if (min != null) {
0505: int len = min.getIntValue();
0506: while (result.length() < len)
0507: result = result + result;
0508: }
0509: SimpleValue max = (SimpleValue) sType
0510: .getFacet(SchemaType.FACET_LENGTH);
0511: if (max == null)
0512: max = (SimpleValue) sType
0513: .getFacet(SchemaType.FACET_MAX_LENGTH);
0514: if (max != null) {
0515: int len = max.getIntValue();
0516: if (result.length() > len)
0517: result = result.substring(0, len);
0518: }
0519: } catch (Exception e) // intValue can be out of range
0520: {
0521: }
0522: return result;
0523: }
0524:
0525: private String formatDecimal(String start, SchemaType sType) {
0526: BigDecimal result = new BigDecimal(start);
0527: XmlDecimal xmlD;
0528: xmlD = (XmlDecimal) sType
0529: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0530: BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue()
0531: : null;
0532: xmlD = (XmlDecimal) sType
0533: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0534: BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue()
0535: : null;
0536: boolean minInclusive = true, maxInclusive = true;
0537: xmlD = (XmlDecimal) sType
0538: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0539: if (xmlD != null) {
0540: BigDecimal minExcl = xmlD.getBigDecimalValue();
0541: if (min == null || min.compareTo(minExcl) < 0) {
0542: min = minExcl;
0543: minInclusive = false;
0544: }
0545: }
0546: xmlD = (XmlDecimal) sType
0547: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0548: if (xmlD != null) {
0549: BigDecimal maxExcl = xmlD.getBigDecimalValue();
0550: if (max == null || max.compareTo(maxExcl) > 0) {
0551: max = maxExcl;
0552: maxInclusive = false;
0553: }
0554: }
0555: xmlD = (XmlDecimal) sType
0556: .getFacet(SchemaType.FACET_TOTAL_DIGITS);
0557: int totalDigits = -1;
0558: if (xmlD != null) {
0559: totalDigits = xmlD.getBigDecimalValue().intValue();
0560:
0561: StringBuffer sb = new StringBuffer(totalDigits);
0562: for (int i = 0; i < totalDigits; i++)
0563: sb.append('9');
0564: BigDecimal digitsLimit = new BigDecimal(sb.toString());
0565: if (max != null && max.compareTo(digitsLimit) > 0) {
0566: max = digitsLimit;
0567: maxInclusive = true;
0568: }
0569: digitsLimit = digitsLimit.negate();
0570: if (min != null && min.compareTo(digitsLimit) < 0) {
0571: min = digitsLimit;
0572: minInclusive = true;
0573: }
0574: }
0575:
0576: int sigMin = min == null ? 1 : result.compareTo(min);
0577: int sigMax = max == null ? -1 : result.compareTo(max);
0578: boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive;
0579: boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive;
0580:
0581: // Compute the minimum increment
0582: xmlD = (XmlDecimal) sType
0583: .getFacet(SchemaType.FACET_FRACTION_DIGITS);
0584: int fractionDigits = -1;
0585: BigDecimal increment;
0586: if (xmlD == null)
0587: increment = new BigDecimal(1);
0588: else {
0589: fractionDigits = xmlD.getBigDecimalValue().intValue();
0590: if (fractionDigits > 0) {
0591: StringBuffer sb = new StringBuffer("0.");
0592: for (int i = 1; i < fractionDigits; i++)
0593: sb.append('0');
0594: sb.append('1');
0595: increment = new BigDecimal(sb.toString());
0596: } else
0597: increment = new BigDecimal(1);
0598: }
0599:
0600: if (minOk && maxOk) {
0601: // OK
0602: } else if (minOk && !maxOk) {
0603: // TOO BIG
0604: if (maxInclusive)
0605: result = max;
0606: else
0607: result = max.subtract(increment);
0608: } else if (!minOk && maxOk) {
0609: // TOO SMALL
0610: if (minInclusive)
0611: result = min;
0612: else
0613: result = min.add(increment);
0614: } else {
0615: // MIN > MAX!!
0616: }
0617:
0618: // We have the number
0619: // Adjust the scale according to the totalDigits and fractionDigits
0620: int digits = 0;
0621: BigDecimal ONE = new BigDecimal(BigInteger.ONE);
0622: for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++)
0623: n = n.movePointLeft(1);
0624:
0625: if (fractionDigits > 0)
0626: if (totalDigits >= 0)
0627: result.setScale(Math.max(fractionDigits, totalDigits
0628: - digits));
0629: else
0630: result.setScale(fractionDigits);
0631: else if (fractionDigits == 0)
0632: result.setScale(0);
0633:
0634: return result.toString();
0635: }
0636:
0637: private String formatDuration(SchemaType sType) {
0638: XmlDuration d = (XmlDuration) sType
0639: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0640: GDuration minInclusive = null;
0641: if (d != null)
0642: minInclusive = d.getGDurationValue();
0643:
0644: d = (XmlDuration) sType
0645: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0646: GDuration maxInclusive = null;
0647: if (d != null)
0648: maxInclusive = d.getGDurationValue();
0649:
0650: d = (XmlDuration) sType
0651: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0652: GDuration minExclusive = null;
0653: if (d != null)
0654: minExclusive = d.getGDurationValue();
0655:
0656: d = (XmlDuration) sType
0657: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0658: GDuration maxExclusive = null;
0659: if (d != null)
0660: maxExclusive = d.getGDurationValue();
0661:
0662: GDurationBuilder gdurb = new GDurationBuilder();
0663: BigInteger min, max;
0664:
0665: gdurb.setSecond(pick(800000));
0666: gdurb.setMonth(pick(20));
0667:
0668: // Years
0669: // Months
0670: // Days
0671: // Hours
0672: // Minutes
0673: // Seconds
0674: // Fractions
0675: if (minInclusive != null) {
0676: if (gdurb.getYear() < minInclusive.getYear())
0677: gdurb.setYear(minInclusive.getYear());
0678: if (gdurb.getMonth() < minInclusive.getMonth())
0679: gdurb.setMonth(minInclusive.getMonth());
0680: if (gdurb.getDay() < minInclusive.getDay())
0681: gdurb.setDay(minInclusive.getDay());
0682: if (gdurb.getHour() < minInclusive.getHour())
0683: gdurb.setHour(minInclusive.getHour());
0684: if (gdurb.getMinute() < minInclusive.getMinute())
0685: gdurb.setMinute(minInclusive.getMinute());
0686: if (gdurb.getSecond() < minInclusive.getSecond())
0687: gdurb.setSecond(minInclusive.getSecond());
0688: if (gdurb.getFraction().compareTo(
0689: minInclusive.getFraction()) < 0)
0690: gdurb.setFraction(minInclusive.getFraction());
0691: }
0692:
0693: if (maxInclusive != null) {
0694: if (gdurb.getYear() > maxInclusive.getYear())
0695: gdurb.setYear(maxInclusive.getYear());
0696: if (gdurb.getMonth() > maxInclusive.getMonth())
0697: gdurb.setMonth(maxInclusive.getMonth());
0698: if (gdurb.getDay() > maxInclusive.getDay())
0699: gdurb.setDay(maxInclusive.getDay());
0700: if (gdurb.getHour() > maxInclusive.getHour())
0701: gdurb.setHour(maxInclusive.getHour());
0702: if (gdurb.getMinute() > maxInclusive.getMinute())
0703: gdurb.setMinute(maxInclusive.getMinute());
0704: if (gdurb.getSecond() > maxInclusive.getSecond())
0705: gdurb.setSecond(maxInclusive.getSecond());
0706: if (gdurb.getFraction().compareTo(
0707: maxInclusive.getFraction()) > 0)
0708: gdurb.setFraction(maxInclusive.getFraction());
0709: }
0710:
0711: if (minExclusive != null) {
0712: if (gdurb.getYear() <= minExclusive.getYear())
0713: gdurb.setYear(minExclusive.getYear() + 1);
0714: if (gdurb.getMonth() <= minExclusive.getMonth())
0715: gdurb.setMonth(minExclusive.getMonth() + 1);
0716: if (gdurb.getDay() <= minExclusive.getDay())
0717: gdurb.setDay(minExclusive.getDay() + 1);
0718: if (gdurb.getHour() <= minExclusive.getHour())
0719: gdurb.setHour(minExclusive.getHour() + 1);
0720: if (gdurb.getMinute() <= minExclusive.getMinute())
0721: gdurb.setMinute(minExclusive.getMinute() + 1);
0722: if (gdurb.getSecond() <= minExclusive.getSecond())
0723: gdurb.setSecond(minExclusive.getSecond() + 1);
0724: if (gdurb.getFraction().compareTo(
0725: minExclusive.getFraction()) <= 0)
0726: gdurb.setFraction(minExclusive.getFraction().add(
0727: new BigDecimal(0.001)));
0728: }
0729:
0730: if (maxExclusive != null) {
0731: if (gdurb.getYear() > maxExclusive.getYear())
0732: gdurb.setYear(maxExclusive.getYear());
0733: if (gdurb.getMonth() > maxExclusive.getMonth())
0734: gdurb.setMonth(maxExclusive.getMonth());
0735: if (gdurb.getDay() > maxExclusive.getDay())
0736: gdurb.setDay(maxExclusive.getDay());
0737: if (gdurb.getHour() > maxExclusive.getHour())
0738: gdurb.setHour(maxExclusive.getHour());
0739: if (gdurb.getMinute() > maxExclusive.getMinute())
0740: gdurb.setMinute(maxExclusive.getMinute());
0741: if (gdurb.getSecond() > maxExclusive.getSecond())
0742: gdurb.setSecond(maxExclusive.getSecond());
0743: if (gdurb.getFraction().compareTo(
0744: maxExclusive.getFraction()) > 0)
0745: gdurb.setFraction(maxExclusive.getFraction());
0746: }
0747:
0748: gdurb.normalize();
0749: return gdurb.toString();
0750: }
0751:
0752: private String formatDate(SchemaType sType) {
0753: GDateBuilder gdateb = new GDateBuilder(new Date(1000L
0754: * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365
0755: * 24 * 60 * 60 * 1000));
0756: GDate min = null, max = null;
0757: GDate temp;
0758:
0759: // Find the min and the max according to the type
0760: switch (sType.getPrimitiveType().getBuiltinTypeCode()) {
0761: case SchemaType.BTC_DATE_TIME: {
0762: XmlDateTime x = (XmlDateTime) sType
0763: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0764: if (x != null)
0765: min = x.getGDateValue();
0766: x = (XmlDateTime) sType
0767: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0768: if (x != null)
0769: if (min == null
0770: || min.compareToGDate(x.getGDateValue()) <= 0)
0771: min = x.getGDateValue();
0772:
0773: x = (XmlDateTime) sType
0774: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0775: if (x != null)
0776: max = x.getGDateValue();
0777: x = (XmlDateTime) sType
0778: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0779: if (x != null)
0780: if (max == null
0781: || max.compareToGDate(x.getGDateValue()) >= 0)
0782: max = x.getGDateValue();
0783: break;
0784: }
0785: case SchemaType.BTC_TIME: {
0786: XmlTime x = (XmlTime) sType
0787: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0788: if (x != null)
0789: min = x.getGDateValue();
0790: x = (XmlTime) sType
0791: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0792: if (x != null)
0793: if (min == null
0794: || min.compareToGDate(x.getGDateValue()) <= 0)
0795: min = x.getGDateValue();
0796:
0797: x = (XmlTime) sType
0798: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0799: if (x != null)
0800: max = x.getGDateValue();
0801: x = (XmlTime) sType
0802: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0803: if (x != null)
0804: if (max == null
0805: || max.compareToGDate(x.getGDateValue()) >= 0)
0806: max = x.getGDateValue();
0807: break;
0808: }
0809: case SchemaType.BTC_DATE: {
0810: XmlDate x = (XmlDate) sType
0811: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0812: if (x != null)
0813: min = x.getGDateValue();
0814: x = (XmlDate) sType
0815: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0816: if (x != null)
0817: if (min == null
0818: || min.compareToGDate(x.getGDateValue()) <= 0)
0819: min = x.getGDateValue();
0820:
0821: x = (XmlDate) sType
0822: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0823: if (x != null)
0824: max = x.getGDateValue();
0825: x = (XmlDate) sType
0826: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0827: if (x != null)
0828: if (max == null
0829: || max.compareToGDate(x.getGDateValue()) >= 0)
0830: max = x.getGDateValue();
0831: break;
0832: }
0833: case SchemaType.BTC_G_YEAR_MONTH: {
0834: XmlGYearMonth x = (XmlGYearMonth) sType
0835: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0836: if (x != null)
0837: min = x.getGDateValue();
0838: x = (XmlGYearMonth) sType
0839: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0840: if (x != null)
0841: if (min == null
0842: || min.compareToGDate(x.getGDateValue()) <= 0)
0843: min = x.getGDateValue();
0844:
0845: x = (XmlGYearMonth) sType
0846: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0847: if (x != null)
0848: max = x.getGDateValue();
0849: x = (XmlGYearMonth) sType
0850: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0851: if (x != null)
0852: if (max == null
0853: || max.compareToGDate(x.getGDateValue()) >= 0)
0854: max = x.getGDateValue();
0855: break;
0856: }
0857: case SchemaType.BTC_G_YEAR: {
0858: XmlGYear x = (XmlGYear) sType
0859: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0860: if (x != null)
0861: min = x.getGDateValue();
0862: x = (XmlGYear) sType
0863: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0864: if (x != null)
0865: if (min == null
0866: || min.compareToGDate(x.getGDateValue()) <= 0)
0867: min = x.getGDateValue();
0868:
0869: x = (XmlGYear) sType
0870: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0871: if (x != null)
0872: max = x.getGDateValue();
0873: x = (XmlGYear) sType
0874: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0875: if (x != null)
0876: if (max == null
0877: || max.compareToGDate(x.getGDateValue()) >= 0)
0878: max = x.getGDateValue();
0879: break;
0880: }
0881: case SchemaType.BTC_G_MONTH_DAY: {
0882: XmlGMonthDay x = (XmlGMonthDay) sType
0883: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0884: if (x != null)
0885: min = x.getGDateValue();
0886: x = (XmlGMonthDay) sType
0887: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0888: if (x != null)
0889: if (min == null
0890: || min.compareToGDate(x.getGDateValue()) <= 0)
0891: min = x.getGDateValue();
0892:
0893: x = (XmlGMonthDay) sType
0894: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0895: if (x != null)
0896: max = x.getGDateValue();
0897: x = (XmlGMonthDay) sType
0898: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0899: if (x != null)
0900: if (max == null
0901: || max.compareToGDate(x.getGDateValue()) >= 0)
0902: max = x.getGDateValue();
0903: break;
0904: }
0905: case SchemaType.BTC_G_DAY: {
0906: XmlGDay x = (XmlGDay) sType
0907: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0908: if (x != null)
0909: min = x.getGDateValue();
0910: x = (XmlGDay) sType
0911: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0912: if (x != null)
0913: if (min == null
0914: || min.compareToGDate(x.getGDateValue()) <= 0)
0915: min = x.getGDateValue();
0916:
0917: x = (XmlGDay) sType
0918: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0919: if (x != null)
0920: max = x.getGDateValue();
0921: x = (XmlGDay) sType
0922: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0923: if (x != null)
0924: if (max == null
0925: || max.compareToGDate(x.getGDateValue()) >= 0)
0926: max = x.getGDateValue();
0927: break;
0928: }
0929: case SchemaType.BTC_G_MONTH: {
0930: XmlGMonth x = (XmlGMonth) sType
0931: .getFacet(SchemaType.FACET_MIN_INCLUSIVE);
0932: if (x != null)
0933: min = x.getGDateValue();
0934: x = (XmlGMonth) sType
0935: .getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
0936: if (x != null)
0937: if (min == null
0938: || min.compareToGDate(x.getGDateValue()) <= 0)
0939: min = x.getGDateValue();
0940:
0941: x = (XmlGMonth) sType
0942: .getFacet(SchemaType.FACET_MAX_INCLUSIVE);
0943: if (x != null)
0944: max = x.getGDateValue();
0945: x = (XmlGMonth) sType
0946: .getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
0947: if (x != null)
0948: if (max == null
0949: || max.compareToGDate(x.getGDateValue()) >= 0)
0950: max = x.getGDateValue();
0951: break;
0952: }
0953: }
0954:
0955: if (min != null && max == null) {
0956: if (min.compareToGDate(gdateb) >= 0) {
0957: // Reset the date to min + (1-8) hours
0958: Calendar c = gdateb.getCalendar();
0959: c.add(Calendar.HOUR_OF_DAY, pick(8));
0960: gdateb = new GDateBuilder(c);
0961: }
0962: } else if (min == null && max != null) {
0963: if (max.compareToGDate(gdateb) <= 0) {
0964: // Reset the date to max - (1-8) hours
0965: Calendar c = gdateb.getCalendar();
0966: c.add(Calendar.HOUR_OF_DAY, 0 - pick(8));
0967: gdateb = new GDateBuilder(c);
0968: }
0969: } else if (min != null && max != null) {
0970: if (min.compareToGDate(gdateb) >= 0
0971: || max.compareToGDate(gdateb) <= 0) {
0972: // Find a date between the two
0973: Calendar c = min.getCalendar();
0974: Calendar cmax = max.getCalendar();
0975: c.add(Calendar.HOUR_OF_DAY, 1);
0976: if (c.after(cmax)) {
0977: c.add(Calendar.HOUR_OF_DAY, -1);
0978: c.add(Calendar.MINUTE, 1);
0979: if (c.after(cmax)) {
0980: c.add(Calendar.MINUTE, -1);
0981: c.add(Calendar.SECOND, 1);
0982: if (c.after(cmax)) {
0983: c.add(Calendar.SECOND, -1);
0984: c.add(Calendar.MILLISECOND, 1);
0985: if (c.after(cmax))
0986: c.add(Calendar.MILLISECOND, -1);
0987: }
0988: }
0989: }
0990: gdateb = new GDateBuilder(c);
0991: }
0992: }
0993:
0994: gdateb.setBuiltinTypeCode(sType.getPrimitiveType()
0995: .getBuiltinTypeCode());
0996: if (pick(2) == 0)
0997: gdateb.clearTimeZone();
0998: return gdateb.toString();
0999: }
1000:
1001: private SchemaType closestBuiltin(SchemaType sType) {
1002: while (!sType.isBuiltinType())
1003: sType = sType.getBaseType();
1004: return sType;
1005: }
1006:
1007: /**
1008: * Cracks a combined QName of the form URL:localname
1009: */
1010: public static QName crackQName(String qName) {
1011: String ns;
1012: String name;
1013:
1014: int index = qName.lastIndexOf(':');
1015: if (index >= 0) {
1016: ns = qName.substring(0, index);
1017: name = qName.substring(index + 1);
1018: } else {
1019: ns = "";
1020: name = qName;
1021: }
1022:
1023: return new QName(ns, name);
1024: }
1025:
1026: /**
1027: * Cursor position:
1028: * Before this call:
1029: * <outer><foo/>^</outer> (cursor at the ^)
1030: * After this call:
1031: * <<outer><foo/><bar/>som text<etc/>^</outer>
1032: */
1033: private void processParticle(SchemaParticle sp, XmlCursor xmlc,
1034: boolean mixed) {
1035: int loop = determineMinMaxForSample(sp, xmlc);
1036:
1037: while (loop-- > 0) {
1038: switch (sp.getParticleType()) {
1039: case (SchemaParticle.ELEMENT):
1040: processElement(sp, xmlc, mixed);
1041: break;
1042: case (SchemaParticle.SEQUENCE):
1043: processSequence(sp, xmlc, mixed);
1044: break;
1045: case (SchemaParticle.CHOICE):
1046: processChoice(sp, xmlc, mixed);
1047: break;
1048: case (SchemaParticle.ALL):
1049: processAll(sp, xmlc, mixed);
1050: break;
1051: case (SchemaParticle.WILDCARD):
1052: processWildCard(sp, xmlc, mixed);
1053: break;
1054: default:
1055: // throw new Exception("No Match on Schema Particle Type: " + String.valueOf(sp.getParticleType()));
1056: }
1057: }
1058: }
1059:
1060: private int determineMinMaxForSample(SchemaParticle sp,
1061: XmlCursor xmlc) {
1062: int minOccurs = sp.getIntMinOccurs();
1063: int maxOccurs = sp.getIntMaxOccurs();
1064:
1065: if (minOccurs == maxOccurs)
1066: return minOccurs;
1067:
1068: if (minOccurs == 0 && ignoreOptional)
1069: return 0;
1070:
1071: int result = minOccurs;
1072: if (result == 0)
1073: result = 1;
1074:
1075: if (sp.getParticleType() != SchemaParticle.ELEMENT)
1076: return result;
1077:
1078: // it probably only makes sense to put comments in front of individual elements that repeat
1079:
1080: if (sp.getMaxOccurs() == null) {
1081: // xmlc.insertComment("The next " + getItemNameOrType(sp, xmlc) + " may be repeated " + minOccurs + " or more times");
1082: if (minOccurs == 0)
1083: xmlc.insertComment("Zero or more repetitions:");
1084: else
1085: xmlc.insertComment(minOccurs + " or more repetitions:");
1086: } else if (sp.getIntMaxOccurs() > 1) {
1087: xmlc.insertComment(minOccurs + " to "
1088: + String.valueOf(sp.getMaxOccurs())
1089: + " repetitions:");
1090: } else {
1091: xmlc.insertComment("Optional:");
1092: }
1093: return result;
1094: }
1095:
1096: /*
1097: Return a name for the element or the particle type to use in the comment for minoccurs, max occurs
1098: */
1099: private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc) {
1100: String elementOrTypeName = null;
1101: if (sp.getParticleType() == SchemaParticle.ELEMENT) {
1102: elementOrTypeName = "Element ("
1103: + sp.getName().getLocalPart() + ")";
1104: } else {
1105: elementOrTypeName = printParticleType(sp.getParticleType());
1106: }
1107: return elementOrTypeName;
1108: }
1109:
1110: private void processElement(SchemaParticle sp, XmlCursor xmlc,
1111: boolean mixed) {
1112: // cast as schema local element
1113: SchemaLocalElement element = (SchemaLocalElement) sp;
1114:
1115: // Add comment about type
1116: addElementTypeAndRestricionsComment(element, xmlc);
1117:
1118: /// ^ -> <elemenname></elem>^
1119: if (_soapEnc)
1120: xmlc.insertElement(element.getName().getLocalPart()); // soap encoded? drop namespaces.
1121: else
1122: xmlc.insertElement(element.getName().getLocalPart(),
1123: element.getName().getNamespaceURI());
1124: /// -> <elem>^</elem>
1125: // processAttributes( sp.getType(), xmlc );
1126:
1127: xmlc.toPrevToken();
1128: // -> <elem>stuff^</elem>
1129:
1130: createSampleForType(element.getType(), xmlc);
1131: // -> <elem>stuff</elem>^
1132: xmlc.toNextToken();
1133:
1134: }
1135:
1136: private void moveToken(int numToMove, XmlCursor xmlc) {
1137: for (int i = 0; i < Math.abs(numToMove); i++) {
1138: if (numToMove < 0) {
1139: xmlc.toPrevToken();
1140: } else {
1141: xmlc.toNextToken();
1142: }
1143: }
1144: }
1145:
1146: private static final String formatQName(XmlCursor xmlc, QName qName) {
1147: XmlCursor parent = xmlc.newCursor();
1148: parent.toParent();
1149: String prefix = parent.prefixForNamespace(qName
1150: .getNamespaceURI());
1151: parent.dispose();
1152: String name;
1153: if (prefix == null || prefix.length() == 0)
1154: name = qName.getLocalPart();
1155: else
1156: name = prefix + ":" + qName.getLocalPart();
1157: return name;
1158: }
1159:
1160: private static final QName HREF = new QName("href");
1161: private static final QName ID = new QName("id");
1162: public static final QName XSI_TYPE = new QName(
1163: "http://www.w3.org/2001/XMLSchema-instance", "type");
1164: private static final QName ENC_ARRAYTYPE = new QName(
1165: "http://schemas.xmlsoap.org/soap/encoding/", "arrayType");
1166: private static final QName ENC_OFFSET = new QName(
1167: "http://schemas.xmlsoap.org/soap/encoding/", "offset");
1168:
1169: private static final Set<QName> SKIPPED_SOAP_ATTRS = new HashSet<QName>(
1170: Arrays.asList(new QName[] { HREF, ID, ENC_OFFSET }));
1171:
1172: private void processAttributes(SchemaType stype, XmlCursor xmlc) {
1173: if (_soapEnc) {
1174: QName typeName = stype.getName();
1175: if (typeName != null) {
1176: xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(
1177: xmlc, typeName));
1178: }
1179: }
1180:
1181: SchemaProperty[] attrProps = stype.getAttributeProperties();
1182: for (int i = 0; i < attrProps.length; i++) {
1183: SchemaProperty attr = attrProps[i];
1184:
1185: if (attr.getName().equals(
1186: new QName("http://www.w3.org/2005/05/xmlmime",
1187: "contentType"))) {
1188: xmlc.insertAttributeWithValue(attr.getName(),
1189: "application/?");
1190: continue;
1191: }
1192:
1193: if (_soapEnc) {
1194: if (SKIPPED_SOAP_ATTRS.contains(attr.getName()))
1195: continue;
1196: if (ENC_ARRAYTYPE.equals(attr.getName())) {
1197: SOAPArrayType arrayType = ((SchemaWSDLArrayType) stype
1198: .getAttributeModel().getAttribute(
1199: attr.getName())).getWSDLArrayType();
1200: if (arrayType != null)
1201: xmlc
1202: .insertAttributeWithValue(
1203: attr.getName(),
1204: formatQName(xmlc, arrayType
1205: .getQName())
1206: + arrayType
1207: .soap11DimensionString());
1208: continue;
1209: }
1210: }
1211: String defaultValue = attr.getDefaultText();
1212: xmlc.insertAttributeWithValue(attr.getName(),
1213: defaultValue == null ? sampleDataForSimpleType(attr
1214: .getType()) : defaultValue);
1215: }
1216: }
1217:
1218: private void processSequence(SchemaParticle sp, XmlCursor xmlc,
1219: boolean mixed) {
1220: SchemaParticle[] spc = sp.getParticleChildren();
1221: for (int i = 0; i < spc.length; i++) {
1222: /// <parent>maybestuff^</parent>
1223: processParticle(spc[i], xmlc, mixed);
1224: //<parent>maybestuff...morestuff^</parent>
1225: if (mixed && i < spc.length - 1)
1226: xmlc.insertChars(pick(WORDS));
1227: }
1228: }
1229:
1230: private void processChoice(SchemaParticle sp, XmlCursor xmlc,
1231: boolean mixed) {
1232: SchemaParticle[] spc = sp.getParticleChildren();
1233: xmlc.insertComment("You have a CHOICE of the next "
1234: + String.valueOf(spc.length) + " items at this level");
1235: for (int i = 0; i < spc.length; i++) {
1236: processParticle(spc[i], xmlc, mixed);
1237: }
1238: }
1239:
1240: private void processAll(SchemaParticle sp, XmlCursor xmlc,
1241: boolean mixed) {
1242: SchemaParticle[] spc = sp.getParticleChildren();
1243: // xmlc.insertComment("You may enter the following " + String.valueOf(spc.length) + " items in any order");
1244: for (int i = 0; i < spc.length; i++) {
1245: processParticle(spc[i], xmlc, mixed);
1246: if (mixed && i < spc.length - 1)
1247: xmlc.insertChars(pick(WORDS));
1248: }
1249: }
1250:
1251: private void processWildCard(SchemaParticle sp, XmlCursor xmlc,
1252: boolean mixed) {
1253: xmlc.insertComment("You may enter ANY elements at this point");
1254: //xmlc.insertElement("AnyElement");
1255: }
1256:
1257: /**
1258: * This method will get the base type for the schema type
1259: */
1260:
1261: private static QName getClosestName(SchemaType sType) {
1262: while (sType.getName() == null)
1263: sType = sType.getBaseType();
1264:
1265: return sType.getName();
1266: }
1267:
1268: private String printParticleType(int particleType) {
1269: StringBuffer returnParticleType = new StringBuffer();
1270: returnParticleType.append("Schema Particle Type: ");
1271:
1272: switch (particleType) {
1273: case SchemaParticle.ALL:
1274: returnParticleType.append("ALL\n");
1275: break;
1276: case SchemaParticle.CHOICE:
1277: returnParticleType.append("CHOICE\n");
1278: break;
1279: case SchemaParticle.ELEMENT:
1280: returnParticleType.append("ELEMENT\n");
1281: break;
1282: case SchemaParticle.SEQUENCE:
1283: returnParticleType.append("SEQUENCE\n");
1284: break;
1285: case SchemaParticle.WILDCARD:
1286: returnParticleType.append("WILDCARD\n");
1287: break;
1288: default:
1289: returnParticleType.append("Schema Particle Type Unknown");
1290: break;
1291: }
1292:
1293: return returnParticleType.toString();
1294: }
1295:
1296: private ArrayList _typeStack = new ArrayList();
1297:
1298: public boolean isIgnoreOptional() {
1299: return ignoreOptional;
1300: }
1301:
1302: public void setIgnoreOptional(boolean ignoreOptional) {
1303: this .ignoreOptional = ignoreOptional;
1304: }
1305:
1306: private void addElementTypeAndRestricionsComment(
1307: SchemaLocalElement element, XmlCursor xmlc) {
1308:
1309: SchemaType type = element.getType();
1310: if (_typeComment && (type != null && type.isSimpleType())) {
1311: String info = "";
1312:
1313: XmlAnySimpleType[] values = type.getEnumerationValues();
1314: if (values != null && values.length > 0) {
1315: info = " - enumeration: [";
1316: for (int c = 0; c < values.length; c++) {
1317: if (c > 0)
1318: info += ",";
1319:
1320: info += values[c].getStringValue();
1321: }
1322:
1323: info += "]";
1324: }
1325:
1326: if (type.isAnonymousType())
1327: xmlc.insertComment("anonymous type" + info);
1328: else
1329: xmlc.insertComment("type: "
1330: + type.getName().getLocalPart() + info);
1331: }
1332: }
1333:
1334: }
|