View Javadoc

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
    10   *   distributed under the License is distributed on an "AS IS" BASIS,
    11   *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12   *   See the License for the specific language governing permissions and
    13   *  limitations under the License.
    14   */
    15
    16  package com.eviware.soapui.impl.wsdl.support.xsd;
    17
    18  import java.math.BigDecimal;
    19  import java.math.BigInteger;
    20  import java.util.ArrayList;
    21  import java.util.Arrays;
    22  import java.util.Calendar;
    23  import java.util.Date;
    24  import java.util.HashSet;
    25  import java.util.Random;
    26  import java.util.Set;
    27
    28  import javax.xml.namespace.QName;
    29
    30  import org.apache.xmlbeans.GDate;
    31  import org.apache.xmlbeans.GDateBuilder;
    32  import org.apache.xmlbeans.GDuration;
    33  import org.apache.xmlbeans.GDurationBuilder;
    34  import org.apache.xmlbeans.SchemaLocalElement;
    35  import org.apache.xmlbeans.SchemaParticle;
    36  import org.apache.xmlbeans.SchemaProperty;
    37  import org.apache.xmlbeans.SchemaType;
    38  import org.apache.xmlbeans.SimpleValue;
    39  import org.apache.xmlbeans.XmlAnySimpleType;
    40  import org.apache.xmlbeans.XmlCursor;
    41  import org.apache.xmlbeans.XmlDate;
    42  import org.apache.xmlbeans.XmlDateTime;
    43  import org.apache.xmlbeans.XmlDecimal;
    44  import org.apache.xmlbeans.XmlDuration;
    45  import org.apache.xmlbeans.XmlGDay;
    46  import org.apache.xmlbeans.XmlGMonth;
    47  import org.apache.xmlbeans.XmlGMonthDay;
    48  import org.apache.xmlbeans.XmlGYear;
    49  import org.apache.xmlbeans.XmlGYearMonth;
    50  import org.apache.xmlbeans.XmlInteger;
    51  import org.apache.xmlbeans.XmlObject;
    52  import org.apache.xmlbeans.XmlOptions;
    53  import org.apache.xmlbeans.XmlTime;
    54  import org.apache.xmlbeans.impl.util.Base64;
    55  import org.apache.xmlbeans.impl.util.HexBin;
    56  import org.apache.xmlbeans.soap.SOAPArrayType;
    57  import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
    58
    59  import com.eviware.soapui.SoapUI;
    60  import com.eviware.soapui.settings.WsdlSettings;
    61
    62  /***
    63   * XmlBeans class for generating XML from XML Schemas
    64   */
    65
    66  public class SampleXmlUtil
    67  {
    68      private boolean _soapEnc;
    69      private boolean _exampleContent = false;
    70      private boolean _typeComment = false;
    71      private Set<QName> excludedTypes = new HashSet<QName>();
    72
    73      public SampleXmlUtil(boolean soapEnc)
    74      {
    75          _soapEnc = soapEnc;
    76          _exampleContent = SoapUI.getSettings().getBoolean(WsdlSettings.XML_GENERATION_TYPE_EXAMPLE_VALUE);
    77          _typeComment = SoapUI.getSettings().getBoolean(WsdlSettings.XML_GENERATION_TYPE_COMMENT_TYPE);
    78
    79          excludedTypes.addAll( SchemaUtils.getExcludedTypes() );
    80      }
    81
    82      public boolean isSoapEnc()
    83      {
    84         return _soapEnc;
    85      }
    86
    87      public boolean isExampleContent()
    88  	{
    89  		return _exampleContent;
    90  	}
    91
    92  	public void setExampleContent( boolean content )
    93  	{
    94  		_exampleContent = content;
    95  	}
    96
    97  	public boolean isTypeComment()
    98  	{
    99  		return _typeComment;
    100 	}
    101
    102 	public void setTypeComment( boolean comment )
    103 	{
    104 		_typeComment = comment;
    105 	}
    106
    107 	public String createSample(SchemaType sType)
    108    {
    109        XmlObject object = XmlObject.Factory.newInstance();
    110        XmlCursor cursor = object.newCursor();
    111        // Skip the document node
    112        cursor.toNextToken();
    113        // Using the type and the cursor, call the utility method to get a
    114        // sample XML payload for that Schema element
    115        createSampleForType(sType, cursor);
    116        // Cursor now contains the sample payload
    117        // Pretty print the result.  Note that the cursor is positioned at the
    118        // end of the doc so we use the original xml object that the cursor was
    119        // created upon to do the xmlText() against.
    120
    121        cursor.dispose();
    122
    123        XmlOptions options = new XmlOptions();
    124        options.put(XmlOptions.SAVE_PRETTY_PRINT);
    125        options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 3);
    126        options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES);
    127        options.setSaveOuter();
    128        String result = object.xmlText(options);
    129
    130        return result;
    131    }
    132
    133 	public static String createSampleForType(SchemaType sType)
    134     {
    135         XmlObject object = XmlObject.Factory.newInstance();
    136         XmlCursor cursor = object.newCursor();
    137         // Skip the document node
    138         cursor.toNextToken();
    139         // Using the type and the cursor, call the utility method to get a
    140         // sample XML payload for that Schema element
    141         new SampleXmlUtil(false).createSampleForType(sType, cursor);
    142         // Cursor now contains the sample payload
    143         // Pretty print the result.  Note that the cursor is positioned at the
    144         // end of the doc so we use the original xml object that the cursor was
    145         // created upon to do the xmlText() against.
    146
    147         cursor.dispose();
    148         XmlOptions options = new XmlOptions();
    149         options.put(XmlOptions.SAVE_PRETTY_PRINT);
    150         options.put(XmlOptions.SAVE_PRETTY_PRINT_INDENT, 3);
    151         options.put(XmlOptions.SAVE_AGGRESSIVE_NAMESPACES);
    152         options.setSaveOuter();
    153         String result = object.xmlText(options);
    154
    155         return result;
    156     }
    157
    158     Random _picker = new Random(1);
    159
    160
    161
    162 	private boolean ignoreOptional;
    163
    164     /***
    165      * Cursor position
    166      * Before:
    167      * <theElement>^</theElement>
    168      * After:
    169      * <theElement><lots of stuff/>^</theElement>
    170      */
    171 	 public void createSampleForType(SchemaType stype, XmlCursor xmlc)
    172     {
    173    	 QName nm = stype.getName();
    174    	 if( nm == null && stype.getContainerField() != null )
    175    		 nm = stype.getContainerField().getName();
    176
    177    	 if( nm != null && excludedTypes.contains( nm ))
    178    	 {
    179    		 xmlc.insertComment( "Ignoring type [" + nm + "]" );
    180    		 return;
    181    	 }
    182
    183         if (_typeStack.contains( stype ))
    184             return;
    185
    186         _typeStack.add( stype );
    187
    188         try
    189         {
    190             if (stype.isSimpleType() || stype.isURType())
    191             {
    192                 processSimpleType(stype, xmlc);
    193                 return;
    194             }
    195
    196             // complex Type
    197             // <theElement>^</theElement>
    198             processAttributes(stype, xmlc);
    199
    200             // <theElement attri1="string">^</theElement>
    201             switch (stype.getContentType())
    202             {
    203                 case SchemaType.NOT_COMPLEX_TYPE :
    204                 case SchemaType.EMPTY_CONTENT :
    205                     // noop
    206                     break;
    207                 case SchemaType.SIMPLE_CONTENT :
    208                     {
    209                         processSimpleType(stype, xmlc);
    210                     }
    211                     break;
    212                 case SchemaType.MIXED_CONTENT :
    213                     xmlc.insertChars(pick(WORDS) + " ");
    214                     if (stype.getContentModel() != null)
    215                     {
    216                         processParticle(stype.getContentModel(), xmlc, true);
    217                     }
    218                     xmlc.insertChars(pick(WORDS));
    219                     break;
    220                 case SchemaType.ELEMENT_CONTENT :
    221                     if (stype.getContentModel() != null)
    222                     {
    223                         processParticle(stype.getContentModel(), xmlc, false);
    224                     }
    225                     break;
    226             }
    227         }
    228         finally
    229         {
    230             _typeStack.remove( _typeStack.size() - 1 );
    231         }
    232     }
    233
    234     private void processSimpleType(SchemaType stype, XmlCursor xmlc)
    235     {
    236        if (_soapEnc)
    237        {
    238            QName typeName = stype.getName();
    239            if (typeName != null)
    240            {
    241                xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(xmlc, typeName));
    242            }
    243        }
    244
    245
    246         String sample = sampleDataForSimpleType(stype);
    247         xmlc.insertChars(sample);
    248     }
    249
    250     private String sampleDataForSimpleType(SchemaType sType)
    251     {
    252    	 // swaRef
    253    	 if( sType.getName() != null )
    254    	 {
    255 	    	if( sType.getName().equals( new QName( "http://ws-i.org/profiles/basic/1.1/xsd", "swaRef" )))
    256 	    		return "cid:" + (long)(System.currentTimeMillis() * Math.random());
    257
    258 	  	 // xmime base64
    259 	    	if( sType.getName().equals( new QName( "http://www.w3.org/2005/05/xmlmime", "base64Binary" )))
    260 	    		return "cid:" + (long)(System.currentTimeMillis() * Math.random());
    261
    262 	  	 // xmime hexBinary
    263 	    	if( sType.getName().equals( new QName( "http://www.w3.org/2005/05/xmlmime", "hexBinary" )))
    264 	    		return "cid:" + (long)(System.currentTimeMillis() * Math.random());
    265    	 }
    266
    267    	SchemaType primitiveType = sType.getPrimitiveType();
    268 		if( primitiveType != null && (primitiveType.getBuiltinTypeCode() == SchemaType.BTC_BASE_64_BINARY ||
    269    		  primitiveType.getBuiltinTypeCode() == SchemaType.BTC_HEX_BINARY ))
    270    		 return "cid:" +(long)(System.currentTimeMillis() * Math.random());
    271
    272    	// if( sType != null )
    273     	if (!_exampleContent)
    274    		 return "?";
    275
    276         if (XmlObject.type.equals(sType))
    277             return "anyType";
    278
    279         if (XmlAnySimpleType.type.equals(sType))
    280             return "anySimpleType";
    281
    282         if (sType.getSimpleVariety() == SchemaType.LIST)
    283         {
    284             SchemaType itemType = sType.getListItemType();
    285             StringBuffer sb = new StringBuffer();
    286             int length = pickLength(sType);
    287             if (length > 0)
    288                 sb.append(sampleDataForSimpleType(itemType));
    289             for (int i = 1; i < length; i += 1)
    290             {
    291                 sb.append(' ');
    292                 sb.append(sampleDataForSimpleType(itemType));
    293             }
    294             return sb.toString();
    295         }
    296
    297         if (sType.getSimpleVariety() == SchemaType.UNION)
    298         {
    299             SchemaType[] possibleTypes = sType.getUnionConstituentTypes();
    300             if (possibleTypes.length == 0)
    301                 return "";
    302             return sampleDataForSimpleType(possibleTypes[pick(possibleTypes.length)]);
    303         }
    304
    305         XmlAnySimpleType[] enumValues = sType.getEnumerationValues();
    306         if (enumValues != null && enumValues.length > 0)
    307         {
    308             return enumValues[pick(enumValues.length)].getStringValue();
    309         }
    310
    311         switch (primitiveType.getBuiltinTypeCode())
    312         {
    313             default:
    314             case SchemaType.BTC_NOT_BUILTIN:
    315                 return "";
    316
    317             case SchemaType.BTC_ANY_TYPE:
    318             case SchemaType.BTC_ANY_SIMPLE:
    319                 return "anything";
    320
    321             case SchemaType.BTC_BOOLEAN:
    322                 return pick(2) == 0 ? "true" : "false";
    323
    324             case SchemaType.BTC_BASE_64_BINARY:
    325             {
    326                 String result = null;
    327                 try
    328                 {   result = new String(Base64.encode(formatToLength(pick(WORDS), sType).getBytes("utf-8"))); }
    329                 catch (java.io.UnsupportedEncodingException e) {}
    330                 return result;
    331             }
    332
    333             case SchemaType.BTC_HEX_BINARY:
    334                 return HexBin.encode(formatToLength(pick(WORDS), sType));
    335
    336             case SchemaType.BTC_ANY_URI:
    337                 return formatToLength("http://www." + pick(DNS1) + "." + pick(DNS2) + "/" + pick(WORDS) + "/" + pick(WORDS), sType);
    338
    339             case SchemaType.BTC_QNAME:
    340                 return formatToLength("qname", sType);
    341
    342             case SchemaType.BTC_NOTATION:
    343                 return formatToLength("notation", sType);
    344
    345             case SchemaType.BTC_FLOAT:
    346                 return "1.5E2";
    347             case SchemaType.BTC_DOUBLE:
    348                 return "1.051732E7";
    349             case SchemaType.BTC_DECIMAL:
    350                 switch (closestBuiltin(sType).getBuiltinTypeCode())
    351                 {
    352                     case SchemaType.BTC_SHORT:
    353                         return formatDecimal("1", sType);
    354                     case SchemaType.BTC_UNSIGNED_SHORT:
    355                         return formatDecimal("5", sType);
    356                     case SchemaType.BTC_BYTE:
    357                         return formatDecimal("2", sType);
    358                     case SchemaType.BTC_UNSIGNED_BYTE:
    359                         return formatDecimal("6", sType);
    360                     case SchemaType.BTC_INT:
    361                         return formatDecimal("3", sType);
    362                     case SchemaType.BTC_UNSIGNED_INT:
    363                         return formatDecimal("7", sType);
    364                     case SchemaType.BTC_LONG:
    365                         return formatDecimal("10", sType);
    366                     case SchemaType.BTC_UNSIGNED_LONG:
    367                         return formatDecimal("11", sType);
    368                     case SchemaType.BTC_INTEGER:
    369                         return formatDecimal("100", sType);
    370                     case SchemaType.BTC_NON_POSITIVE_INTEGER:
    371                         return formatDecimal("-200", sType);
    372                     case SchemaType.BTC_NEGATIVE_INTEGER:
    373                         return formatDecimal("-201", sType);
    374                     case SchemaType.BTC_NON_NEGATIVE_INTEGER:
    375                         return formatDecimal("200", sType);
    376                     case SchemaType.BTC_POSITIVE_INTEGER:
    377                         return formatDecimal("201", sType);
    378                     default:
    379                     case SchemaType.BTC_DECIMAL:
    380                         return formatDecimal("1000.00", sType);
    381                 }
    382
    383             case SchemaType.BTC_STRING:
    384                 {
    385                     String result;
    386                     switch (closestBuiltin(sType).getBuiltinTypeCode())
    387                     {
    388                         case SchemaType.BTC_STRING:
    389                         case SchemaType.BTC_NORMALIZED_STRING:
    390                             result = pick(WORDS, _picker.nextInt(3));
    391                             break;
    392
    393                         case SchemaType.BTC_TOKEN:
    394                             result = pick(WORDS, _picker.nextInt(3));
    395                             break;
    396
    397                         default:
    398                             result = pick(WORDS, _picker.nextInt(3));
    399                             break;
    400                     }
    401
    402                     return formatToLength(result, sType);
    403                 }
    404
    405             case SchemaType.BTC_DURATION:
    406                 return formatDuration(sType);
    407
    408             case SchemaType.BTC_DATE_TIME:
    409             case SchemaType.BTC_TIME:
    410             case SchemaType.BTC_DATE:
    411             case SchemaType.BTC_G_YEAR_MONTH:
    412             case SchemaType.BTC_G_YEAR:
    413             case SchemaType.BTC_G_MONTH_DAY:
    414             case SchemaType.BTC_G_DAY:
    415             case SchemaType.BTC_G_MONTH:
    416                 return formatDate(sType);
    417
    418         }
    419     }
    420
    421     // a bit from the Aenid
    422     public static final String[] WORDS = new String[]
    423     {
    424     "ipsa", "iovis", "rapidum", "iaculata", "e", "nubibus", "ignem",
    425     "disiecitque", "rates", "evertitque", "aequora", "ventis",
    426     "illum", "exspirantem", "transfixo", "pectore", "flammas",
    427     "turbine", "corripuit", "scopuloque", "infixit", "acuto",
    428     "ast", "ego", "quae", "divum", "incedo", "regina", "iovisque",
    429     "et", "soror", "et", "coniunx", "una", "cum", "gente", "tot", "annos",
    430     "bella", "gero", "et", "quisquam", "numen", "iunonis", "adorat",
    431     "praeterea", "aut", "supplex", "aris", "imponet", "honorem",
    432     "talia", "flammato", "secum", "dea", "corde", "volutans",
    433     "nimborum", "in", "patriam", "loca", "feta", "furentibus", "austris",
    434     "aeoliam", "venit", "hic", "vasto", "rex", "aeolus", "antro",
    435     "luctantis", "ventos", "tempestatesque", "sonoras",
    436     "imperio", "premit", "ac", "vinclis", "et", "carcere", "frenat",
    437     "illi", "indignantes", "magno", "cum", "murmure", "montis",
    438     "circum", "claustra", "fremunt", "celsa", "sedet", "aeolus", "arce",
    439     "sceptra", "tenens", "mollitque", "animos", "et", "temperat", "iras",
    440     "ni", "faciat", "maria", "ac", "terras", "caelumque", "profundum",
    441     "quippe", "ferant", "rapidi", "secum", "verrantque", "per", "auras",
    442     "sed", "pater", "omnipotens", "speluncis", "abdidit", "atris",
    443     "hoc", "metuens", "molemque", "et", "montis", "insuper", "altos",
    444     "imposuit", "regemque", "dedit", "qui", "foedere", "certo",
    445     "et", "premere", "et", "laxas", "sciret", "dare", "iussus", "habenas",
    446     };
    447
    448
    449
    450     private static final String[] DNS1 = new String[] { "corp", "your", "my", "sample", "company", "test", "any" };
    451     private static final String[] DNS2 = new String[] { "com", "org", "com", "gov", "org", "com", "org", "com", "edu" };
    452
    453     private int pick(int n)
    454     {
    455         return _picker.nextInt(n);
    456     }
    457
    458     private String pick(String[] a)
    459     {
    460         return a[pick(a.length)];
    461     }
    462
    463     private String pick(String[] a, int count)
    464     {
    465         if (count <= 0)
    466         	count = 1;
    467 //            return "";
    468
    469         int i = pick(a.length);
    470         StringBuffer sb = new StringBuffer(a[i]);
    471         while (count-- > 0)
    472         {
    473             i += 1;
    474             if (i >= a.length)
    475                 i = 0;
    476             sb.append(' ');
    477             sb.append(a[i]);
    478         }
    479         return sb.toString();
    480     }
    481
    482     private String pickDigits(int digits)
    483     {
    484         StringBuffer sb = new StringBuffer();
    485         while (digits-- > 0)
    486             sb.append(Integer.toString(pick(10)));
    487         return sb.toString();
    488     }
    489
    490     private int pickLength(SchemaType sType)
    491     {
    492         XmlInteger length = (XmlInteger) sType.getFacet(SchemaType.FACET_LENGTH);
    493         if (length != null)
    494             return length.getBigIntegerValue().intValue();
    495         XmlInteger min    = (XmlInteger) sType.getFacet(SchemaType.FACET_MIN_LENGTH);
    496         XmlInteger max    = (XmlInteger) sType.getFacet(SchemaType.FACET_MAX_LENGTH);
    497         int minInt, maxInt;
    498         if (min == null)
    499             minInt = 0;
    500         else
    501             minInt = min.getBigIntegerValue().intValue();
    502         if (max == null)
    503             maxInt = Integer.MAX_VALUE;
    504         else
    505             maxInt = max.getBigIntegerValue().intValue();
    506         // We try to keep the length of the array within reasonable limits,
    507         // at least 1 item and at most 3 if possible
    508         if (minInt == 0 && maxInt >= 1)
    509             minInt = 1;
    510         if (maxInt > minInt + 2)
    511             maxInt = minInt + 2;
    512         if (maxInt < minInt)
    513             maxInt = minInt;
    514         return minInt + pick(maxInt-minInt);
    515     }
    516
    517     /***
    518      * Formats a given string to the required length, using the following operations:
    519      * - append the source string to itself as necessary to pass the minLength;
    520      * - truncate the result of previous step, if necessary, to keep it within minLength.
    521      */
    522     private String formatToLength(String s, SchemaType sType)
    523     {
    524         String result = s;
    525         try
    526         {
    527             SimpleValue min = (SimpleValue)sType.getFacet(SchemaType.FACET_LENGTH);
    528             if (min == null)
    529                 min = (SimpleValue)sType.getFacet(SchemaType.FACET_MIN_LENGTH);
    530             if (min != null)
    531             {
    532                 int len = min.getIntValue();
    533                 while (result.length() < len)
    534                     result = result + result;
    535             }
    536             SimpleValue max = (SimpleValue)sType.getFacet(SchemaType.FACET_LENGTH);
    537             if (max == null)
    538                 max = (SimpleValue)sType.getFacet(SchemaType.FACET_MAX_LENGTH);
    539             if (max != null)
    540             {
    541                 int len = max.getIntValue();
    542                 if (result.length() > len)
    543                     result = result.substring(0, len);
    544             }
    545         }
    546         catch (Exception e) // intValue can be out of range
    547         {
    548         }
    549         return result;
    550     }
    551
    552     private String formatDecimal(String start, SchemaType sType)
    553     {
    554         BigDecimal result = new BigDecimal(start);
    555         XmlDecimal xmlD;
    556         xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    557         BigDecimal min = xmlD != null ? xmlD.getBigDecimalValue() : null;
    558         xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    559         BigDecimal max = xmlD != null ? xmlD.getBigDecimalValue() : null;
    560         boolean minInclusive = true, maxInclusive = true;
    561         xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    562         if (xmlD != null)
    563         {
    564             BigDecimal minExcl = xmlD.getBigDecimalValue();
    565             if (min == null || min.compareTo(minExcl) < 0)
    566             {
    567                 min = minExcl;
    568                 minInclusive = false;
    569             }
    570         }
    571         xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    572         if (xmlD != null)
    573         {
    574             BigDecimal maxExcl = xmlD.getBigDecimalValue();
    575             if (max == null || max.compareTo(maxExcl) > 0)
    576             {
    577                 max = maxExcl;
    578                 maxInclusive = false;
    579             }
    580         }
    581         xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_TOTAL_DIGITS);
    582         int totalDigits = -1;
    583         if (xmlD != null)
    584         {
    585             totalDigits = xmlD.getBigDecimalValue().intValue();
    586
    587             StringBuffer sb = new StringBuffer(totalDigits);
    588             for (int i = 0; i < totalDigits; i++)
    589                 sb.append('9');
    590             BigDecimal digitsLimit = new BigDecimal(sb.toString());
    591             if (max != null && max.compareTo(digitsLimit) > 0)
    592             {
    593                 max = digitsLimit;
    594                 maxInclusive = true;
    595             }
    596             digitsLimit = digitsLimit.negate();
    597             if (min != null && min.compareTo(digitsLimit) < 0)
    598             {
    599                 min = digitsLimit;
    600                 minInclusive = true;
    601             }
    602         }
    603
    604         int sigMin = min == null ? 1 : result.compareTo(min);
    605         int sigMax = max == null ? -1 : result.compareTo(max);
    606         boolean minOk = sigMin > 0 || sigMin == 0 && minInclusive;
    607         boolean maxOk = sigMax < 0 || sigMax == 0 && maxInclusive;
    608
    609         // Compute the minimum increment
    610         xmlD = (XmlDecimal) sType.getFacet(SchemaType.FACET_FRACTION_DIGITS);
    611         int fractionDigits = -1;
    612         BigDecimal increment;
    613         if (xmlD == null)
    614             increment = new BigDecimal(1);
    615         else
    616         {
    617             fractionDigits = xmlD.getBigDecimalValue().intValue();
    618             if (fractionDigits > 0)
    619             {
    620                 StringBuffer sb = new StringBuffer("0.");
    621                 for (int i = 1; i < fractionDigits; i++)
    622                     sb.append('0');
    623                 sb.append('1');
    624                 increment = new BigDecimal(sb.toString());
    625             }
    626             else
    627                 increment = new BigDecimal(1);
    628         }
    629
    630         if (minOk && maxOk)
    631         {
    632             // OK
    633         }
    634         else if (minOk && !maxOk)
    635         {
    636             // TOO BIG
    637             if (maxInclusive)
    638                 result = max;
    639             else
    640                 result = max.subtract(increment);
    641         }
    642         else if (!minOk && maxOk)
    643         {
    644             // TOO SMALL
    645             if (minInclusive)
    646                 result = min;
    647             else
    648                 result = min.add(increment);
    649         }
    650         else
    651         {
    652             // MIN > MAX!!
    653         }
    654
    655         // We have the number
    656         // Adjust the scale according to the totalDigits and fractionDigits
    657         int digits = 0;
    658         BigDecimal ONE = new BigDecimal(BigInteger.ONE);
    659         for (BigDecimal n = result; n.abs().compareTo(ONE) >= 0; digits++)
    660             n = n.movePointLeft(1);
    661
    662         if (fractionDigits > 0)
    663             if (totalDigits >= 0)
    664                 result.setScale(Math.max(fractionDigits, totalDigits - digits));
    665             else
    666                 result.setScale(fractionDigits);
    667         else if (fractionDigits == 0)
    668             result.setScale(0);
    669
    670         return result.toString();
    671     }
    672
    673     private String formatDuration(SchemaType sType)
    674     {
    675         XmlDuration d =
    676             (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    677         GDuration minInclusive = null;
    678         if (d != null)
    679             minInclusive = d.getGDurationValue();
    680
    681         d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    682         GDuration maxInclusive = null;
    683         if (d != null)
    684             maxInclusive = d.getGDurationValue();
    685
    686         d = (XmlDuration) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    687         GDuration minExclusive = null;
    688         if (d != null)
    689             minExclusive = d.getGDurationValue();
    690
    691         d = (XmlDuration) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    692         GDuration maxExclusive = null;
    693         if (d != null)
    694             maxExclusive = d.getGDurationValue();
    695
    696         GDurationBuilder gdurb = new GDurationBuilder();
    697         BigInteger min, max;
    698
    699         gdurb.setSecond(pick(800000));
    700         gdurb.setMonth(pick(20));
    701
    702         // Years
    703         // Months
    704         // Days
    705         // Hours
    706         // Minutes
    707         // Seconds
    708         // Fractions
    709         if (minInclusive != null)
    710         {
    711             if (gdurb.getYear() < minInclusive.getYear())
    712                 gdurb.setYear(minInclusive.getYear());
    713             if (gdurb.getMonth() < minInclusive.getMonth())
    714                 gdurb.setMonth(minInclusive.getMonth());
    715             if (gdurb.getDay() < minInclusive.getDay())
    716                 gdurb.setDay(minInclusive.getDay());
    717             if (gdurb.getHour() < minInclusive.getHour())
    718                 gdurb.setHour(minInclusive.getHour());
    719             if (gdurb.getMinute() < minInclusive.getMinute())
    720                 gdurb.setMinute(minInclusive.getMinute());
    721             if (gdurb.getSecond() < minInclusive.getSecond())
    722                 gdurb.setSecond(minInclusive.getSecond());
    723             if (gdurb.getFraction().compareTo(minInclusive.getFraction()) < 0)
    724                 gdurb.setFraction(minInclusive.getFraction());
    725         }
    726
    727         if (maxInclusive != null)
    728         {
    729             if (gdurb.getYear() > maxInclusive.getYear())
    730                 gdurb.setYear(maxInclusive.getYear());
    731             if (gdurb.getMonth() > maxInclusive.getMonth())
    732                 gdurb.setMonth(maxInclusive.getMonth());
    733             if (gdurb.getDay() > maxInclusive.getDay())
    734                 gdurb.setDay(maxInclusive.getDay());
    735             if (gdurb.getHour() > maxInclusive.getHour())
    736                 gdurb.setHour(maxInclusive.getHour());
    737             if (gdurb.getMinute() > maxInclusive.getMinute())
    738                 gdurb.setMinute(maxInclusive.getMinute());
    739             if (gdurb.getSecond() > maxInclusive.getSecond())
    740                 gdurb.setSecond(maxInclusive.getSecond());
    741             if (gdurb.getFraction().compareTo(maxInclusive.getFraction()) > 0)
    742                 gdurb.setFraction(maxInclusive.getFraction());
    743         }
    744
    745         if (minExclusive != null)
    746         {
    747             if (gdurb.getYear() <= minExclusive.getYear())
    748                 gdurb.setYear(minExclusive.getYear()+1);
    749             if (gdurb.getMonth() <= minExclusive.getMonth())
    750                 gdurb.setMonth(minExclusive.getMonth()+1);
    751             if (gdurb.getDay() <= minExclusive.getDay())
    752                 gdurb.setDay(minExclusive.getDay()+1);
    753             if (gdurb.getHour() <= minExclusive.getHour())
    754                 gdurb.setHour(minExclusive.getHour()+1);
    755             if (gdurb.getMinute() <= minExclusive.getMinute())
    756                 gdurb.setMinute(minExclusive.getMinute()+1);
    757             if (gdurb.getSecond() <= minExclusive.getSecond())
    758                 gdurb.setSecond(minExclusive.getSecond()+1);
    759             if (gdurb.getFraction().compareTo(minExclusive.getFraction()) <= 0)
    760                 gdurb.setFraction(minExclusive.getFraction().add(new BigDecimal(0.001)));
    761         }
    762
    763         if (maxExclusive != null)
    764         {
    765             if (gdurb.getYear() > maxExclusive.getYear())
    766                 gdurb.setYear(maxExclusive.getYear());
    767             if (gdurb.getMonth() > maxExclusive.getMonth())
    768                 gdurb.setMonth(maxExclusive.getMonth());
    769             if (gdurb.getDay() > maxExclusive.getDay())
    770                 gdurb.setDay(maxExclusive.getDay());
    771             if (gdurb.getHour() > maxExclusive.getHour())
    772                 gdurb.setHour(maxExclusive.getHour());
    773             if (gdurb.getMinute() > maxExclusive.getMinute())
    774                 gdurb.setMinute(maxExclusive.getMinute());
    775             if (gdurb.getSecond() > maxExclusive.getSecond())
    776                 gdurb.setSecond(maxExclusive.getSecond());
    777             if (gdurb.getFraction().compareTo(maxExclusive.getFraction()) > 0)
    778                 gdurb.setFraction(maxExclusive.getFraction());
    779         }
    780
    781         gdurb.normalize();
    782         return gdurb.toString();
    783     }
    784
    785     private String formatDate(SchemaType sType)
    786     {
    787         GDateBuilder gdateb = new GDateBuilder(new Date(1000L * pick(365 * 24 * 60 * 60) + (30L + pick(20)) * 365 * 24 * 60 * 60 * 1000));
    788         GDate min = null, max = null;
    789         GDate temp;
    790
    791         // Find the min and the max according to the type
    792         switch (sType.getPrimitiveType().getBuiltinTypeCode())
    793         {
    794             case SchemaType.BTC_DATE_TIME:
    795             {
    796                 XmlDateTime x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    797                 if (x != null)
    798                     min = x.getGDateValue();
    799                 x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    800                 if (x != null)
    801                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    802                         min = x.getGDateValue();
    803
    804                 x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    805                 if (x != null)
    806                     max = x.getGDateValue();
    807                 x = (XmlDateTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    808                 if (x != null)
    809                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    810                         max = x.getGDateValue();
    811                 break;
    812             }
    813             case SchemaType.BTC_TIME:
    814             {
    815                 XmlTime x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    816                 if (x != null)
    817                     min = x.getGDateValue();
    818                 x = (XmlTime) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    819                 if (x != null)
    820                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    821                         min = x.getGDateValue();
    822
    823                 x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    824                 if (x != null)
    825                     max = x.getGDateValue();
    826                 x = (XmlTime) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    827                 if (x != null)
    828                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    829                         max = x.getGDateValue();
    830                 break;
    831             }
    832             case SchemaType.BTC_DATE:
    833             {
    834                 XmlDate x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    835                 if (x != null)
    836                     min = x.getGDateValue();
    837                 x = (XmlDate) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    838                 if (x != null)
    839                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    840                         min = x.getGDateValue();
    841
    842                 x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    843                 if (x != null)
    844                     max = x.getGDateValue();
    845                 x = (XmlDate) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    846                 if (x != null)
    847                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    848                         max = x.getGDateValue();
    849                 break;
    850             }
    851             case SchemaType.BTC_G_YEAR_MONTH:
    852             {
    853                 XmlGYearMonth x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    854                 if (x != null)
    855                     min = x.getGDateValue();
    856                 x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    857                 if (x != null)
    858                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    859                         min = x.getGDateValue();
    860
    861                 x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    862                 if (x != null)
    863                     max = x.getGDateValue();
    864                 x = (XmlGYearMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    865                 if (x != null)
    866                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    867                         max = x.getGDateValue();
    868                 break;
    869             }
    870             case SchemaType.BTC_G_YEAR:
    871             {
    872                 XmlGYear x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    873                 if (x != null)
    874                     min = x.getGDateValue();
    875                 x = (XmlGYear) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    876                 if (x != null)
    877                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    878                         min = x.getGDateValue();
    879
    880                 x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    881                 if (x != null)
    882                     max = x.getGDateValue();
    883                 x = (XmlGYear) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    884                 if (x != null)
    885                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    886                         max = x.getGDateValue();
    887                 break;
    888             }
    889             case SchemaType.BTC_G_MONTH_DAY:
    890             {
    891                 XmlGMonthDay x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    892                 if (x != null)
    893                     min = x.getGDateValue();
    894                 x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    895                 if (x != null)
    896                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    897                         min = x.getGDateValue();
    898
    899                 x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    900                 if (x != null)
    901                     max = x.getGDateValue();
    902                 x = (XmlGMonthDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    903                 if (x != null)
    904                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    905                         max = x.getGDateValue();
    906                 break;
    907             }
    908             case SchemaType.BTC_G_DAY:
    909             {
    910                 XmlGDay x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    911                 if (x != null)
    912                     min = x.getGDateValue();
    913                 x = (XmlGDay) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    914                 if (x != null)
    915                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    916                         min = x.getGDateValue();
    917
    918                 x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    919                 if (x != null)
    920                     max = x.getGDateValue();
    921                 x = (XmlGDay) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    922                 if (x != null)
    923                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    924                         max = x.getGDateValue();
    925                 break;
    926             }
    927             case SchemaType.BTC_G_MONTH:
    928             {
    929                 XmlGMonth x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_INCLUSIVE);
    930                 if (x != null)
    931                     min = x.getGDateValue();
    932                 x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MIN_EXCLUSIVE);
    933                 if (x != null)
    934                     if (min == null || min.compareToGDate(x.getGDateValue()) <= 0)
    935                         min = x.getGDateValue();
    936
    937                 x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_INCLUSIVE);
    938                 if (x != null)
    939                     max = x.getGDateValue();
    940                 x = (XmlGMonth) sType.getFacet(SchemaType.FACET_MAX_EXCLUSIVE);
    941                 if (x != null)
    942                     if (max == null || max.compareToGDate(x.getGDateValue()) >= 0)
    943                         max = x.getGDateValue();
    944                 break;
    945             }
    946         }
    947
    948         if (min != null && max == null)
    949         {
    950             if (min.compareToGDate(gdateb) >= 0)
    951             {
    952                 // Reset the date to min + (1-8) hours
    953                 Calendar c = gdateb.getCalendar();
    954                 c.add(Calendar.HOUR_OF_DAY, pick(8));
    955                 gdateb = new GDateBuilder(c);
    956             }
    957         }
    958         else if (min == null && max != null)
    959         {
    960             if (max.compareToGDate(gdateb) <= 0)
    961             {
    962                 // Reset the date to max - (1-8) hours
    963                 Calendar c = gdateb.getCalendar();
    964                 c.add(Calendar.HOUR_OF_DAY, 0-pick(8));
    965                 gdateb = new GDateBuilder(c);
    966             }
    967         }
    968         else if (min != null && max != null)
    969         {
    970             if (min.compareToGDate(gdateb) >= 0 || max.compareToGDate(gdateb) <= 0)
    971             {
    972                 // Find a date between the two
    973                 Calendar c = min.getCalendar();
    974                 Calendar cmax = max.getCalendar();
    975                 c.add(Calendar.HOUR_OF_DAY, 1);
    976                 if (c.after(cmax))
    977                 {
    978                     c.add(Calendar.HOUR_OF_DAY, -1);
    979                     c.add(Calendar.MINUTE, 1);
    980                     if (c.after(cmax))
    981                     {
    982                         c.add(Calendar.MINUTE, -1);
    983                         c.add(Calendar.SECOND, 1);
    984                         if (c.after(cmax))
    985                         {
    986                             c.add(Calendar.SECOND, -1);
    987                             c.add(Calendar.MILLISECOND, 1);
    988                             if (c.after(cmax))
    989                                 c.add(Calendar.MILLISECOND, -1);
    990                         }
    991                     }
    992                 }
    993                 gdateb = new GDateBuilder(c);
    994             }
    995         }
    996
    997         gdateb.setBuiltinTypeCode(sType.getPrimitiveType().getBuiltinTypeCode());
    998         if (pick(2) == 0)
    999             gdateb.clearTimeZone();
    1000         return gdateb.toString();
    1001     }
    1002
    1003     private SchemaType closestBuiltin(SchemaType sType)
    1004     {
    1005         while (!sType.isBuiltinType())
    1006             sType = sType.getBaseType();
    1007         return sType;
    1008     }
    1009
    1010
    1011     /***
    1012      * Cracks a combined QName of the form URL:localname
    1013      */
    1014     public static QName crackQName(String qName)
    1015     {
    1016         String ns;
    1017         String name;
    1018
    1019         int index = qName.lastIndexOf( ':' );
    1020         if (index >= 0)
    1021         {
    1022             ns   = qName.substring( 0, index );
    1023             name = qName.substring( index + 1);
    1024         }
    1025         else
    1026         {
    1027             ns   = "";
    1028             name = qName;
    1029         }
    1030
    1031         return new QName(ns, name);
    1032     }
    1033
    1034
    1035     /***
    1036      * Cursor position:
    1037      * Before this call:
    1038      * <outer><foo/>^</outer>  (cursor at the ^)
    1039      * After this call:
    1040      * <<outer><foo/><bar/>som text<etc/>^</outer>
    1041      */
    1042     private void processParticle(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    1043     {
    1044         int loop = determineMinMaxForSample(sp, xmlc);
    1045
    1046         while (loop-- > 0)
    1047         {
    1048             switch (sp.getParticleType())
    1049             {
    1050                 case (SchemaParticle.ELEMENT) :
    1051                     processElement(sp, xmlc, mixed);
    1052                     break;
    1053                 case (SchemaParticle.SEQUENCE) :
    1054                     processSequence(sp, xmlc, mixed);
    1055                     break;
    1056                 case (SchemaParticle.CHOICE) :
    1057                     processChoice(sp, xmlc, mixed);
    1058                     break;
    1059                 case (SchemaParticle.ALL) :
    1060                     processAll(sp, xmlc, mixed);
    1061                     break;
    1062                 case (SchemaParticle.WILDCARD) :
    1063                     processWildCard(sp, xmlc, mixed);
    1064                     break;
    1065                 default :
    1066                     // throw new Exception("No Match on Schema Particle Type: " + String.valueOf(sp.getParticleType()));
    1067             }
    1068         }
    1069     }
    1070
    1071     private int determineMinMaxForSample(SchemaParticle sp, XmlCursor xmlc)
    1072     {
    1073         int minOccurs = sp.getIntMinOccurs();
    1074         int maxOccurs = sp.getIntMaxOccurs();
    1075
    1076         if (minOccurs == maxOccurs)
    1077             return minOccurs;
    1078
    1079         if( minOccurs == 0 && ignoreOptional )
    1080       	  return 0;
    1081
    1082         int result = minOccurs;
    1083         if (result == 0)
    1084             result = 1;
    1085
    1086         if (sp.getParticleType() != SchemaParticle.ELEMENT)
    1087             return result;
    1088
    1089         // it probably only makes sense to put comments in front of individual elements that repeat
    1090
    1091         if (sp.getMaxOccurs() == null)
    1092         {
    1093             // xmlc.insertComment("The next " + getItemNameOrType(sp, xmlc) + " may be repeated " + minOccurs + " or more times");
    1094             if (minOccurs == 0)
    1095                 xmlc.insertComment("Zero or more repetitions:");
    1096             else
    1097                 xmlc.insertComment(minOccurs + " or more repetitions:");
    1098         }
    1099         else if (sp.getIntMaxOccurs() > 1)
    1100         {
    1101             xmlc.insertComment(minOccurs + " to " + String.valueOf(sp.getMaxOccurs()) + " repetitions:");
    1102         }
    1103         else
    1104         {
    1105             xmlc.insertComment("Optional:");
    1106         }
    1107         return result;
    1108     }
    1109
    1110     /*
    1111      Return a name for the element or the particle type to use in the comment for minoccurs, max occurs
    1112     */
    1113     private String getItemNameOrType(SchemaParticle sp, XmlCursor xmlc)
    1114     {
    1115         String elementOrTypeName = null;
    1116         if (sp.getParticleType() == SchemaParticle.ELEMENT)
    1117         {
    1118             elementOrTypeName = "Element (" + sp.getName().getLocalPart() + ")";
    1119         }
    1120         else
    1121         {
    1122             elementOrTypeName = printParticleType(sp.getParticleType());
    1123         }
    1124         return elementOrTypeName;
    1125     }
    1126
    1127     private void processElement(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    1128     {
    1129         // cast as schema local element
    1130         SchemaLocalElement element = (SchemaLocalElement) sp;
    1131
    1132         // Add comment about type
    1133         addElementTypeAndRestricionsComment(element, xmlc);
    1134
    1135         /// ^  -> <elemenname></elem>^
    1136         if (_soapEnc)
    1137             xmlc.insertElement(element.getName().getLocalPart()); // soap encoded? drop namespaces.
    1138         else
    1139             xmlc.insertElement(element.getName().getLocalPart(), element.getName().getNamespaceURI());
    1140         /// -> <elem>^</elem>
    1141        // processAttributes( sp.getType(), xmlc );
    1142
    1143         xmlc.toPrevToken();
    1144         // -> <elem>stuff^</elem>
    1145
    1146         createSampleForType(element.getType(), xmlc);
    1147         // -> <elem>stuff</elem>^
    1148         xmlc.toNextToken();
    1149
    1150     }
    1151
    1152     private void moveToken(int numToMove, XmlCursor xmlc)
    1153     {
    1154         for (int i = 0; i < Math.abs(numToMove); i++)
    1155         {
    1156             if (numToMove < 0)
    1157             {
    1158                 xmlc.toPrevToken();
    1159             }
    1160             else
    1161             {
    1162                 xmlc.toNextToken();
    1163             }
    1164         }
    1165     }
    1166
    1167     private static final String formatQName(XmlCursor xmlc, QName qName)
    1168     {
    1169         XmlCursor parent = xmlc.newCursor();
    1170         parent.toParent();
    1171         String prefix = parent.prefixForNamespace(qName.getNamespaceURI());
    1172         parent.dispose();
    1173         String name;
    1174         if (prefix == null || prefix.length() == 0)
    1175             name = qName.getLocalPart();
    1176         else
    1177             name = prefix + ":" + qName.getLocalPart();
    1178         return name;
    1179     }
    1180
    1181     private static final QName HREF = new QName("href");
    1182     private static final QName ID = new QName("id");
    1183     public static final QName XSI_TYPE = new QName("http://www.w3.org/2001/XMLSchema-instance", "type");
    1184     private static final QName ENC_ARRAYTYPE = new QName("http://schemas.xmlsoap.org/soap/encoding/", "arrayType");
    1185     private static final QName ENC_OFFSET = new QName("http://schemas.xmlsoap.org/soap/encoding/", "offset");
    1186
    1187     private static final Set<QName> SKIPPED_SOAP_ATTRS = new HashSet<QName>(Arrays.asList(new QName[] { HREF, ID, ENC_OFFSET}));
    1188     private void processAttributes(SchemaType stype, XmlCursor xmlc)
    1189     {
    1190         if (_soapEnc)
    1191         {
    1192             QName typeName = stype.getName();
    1193             if (typeName != null)
    1194             {
    1195                 xmlc.insertAttributeWithValue(XSI_TYPE, formatQName(xmlc, typeName));
    1196             }
    1197         }
    1198
    1199         SchemaProperty[] attrProps = stype.getAttributeProperties();
    1200         for (int i = 0; i < attrProps.length; i++)
    1201         {
    1202             SchemaProperty attr = attrProps[i];
    1203
    1204             if( attr.getName().equals( new QName( "http://www.w3.org/2005/05/xmlmime", "contentType")))
    1205             {
    1206             	xmlc.insertAttributeWithValue(attr.getName(), "application/?" );
    1207             	continue;
    1208             }
    1209
    1210             if (_soapEnc)
    1211             {
    1212                 if (SKIPPED_SOAP_ATTRS.contains(attr.getName()))
    1213                     continue;
    1214                 if (ENC_ARRAYTYPE.equals(attr.getName()))
    1215                 {
    1216                     SOAPArrayType arrayType = ((SchemaWSDLArrayType)stype.getAttributeModel().getAttribute(attr.getName())).getWSDLArrayType();
    1217                     if (arrayType != null)
    1218                         xmlc.insertAttributeWithValue(attr.getName(), formatQName(xmlc, arrayType.getQName()) + arrayType.soap11DimensionString());
    1219                     continue;
    1220                 }
    1221             }
    1222             String defaultValue = attr.getDefaultText();
    1223             xmlc.insertAttributeWithValue(attr.getName(), defaultValue == null ?
    1224                 sampleDataForSimpleType(attr.getType()) : defaultValue);
    1225         }
    1226     }
    1227
    1228     private void processSequence(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    1229     {
    1230         SchemaParticle[] spc = sp.getParticleChildren();
    1231         for (int i=0; i < spc.length; i++)
    1232         {
    1233             /// <parent>maybestuff^</parent>
    1234             processParticle(spc[i], xmlc, mixed);
    1235             //<parent>maybestuff...morestuff^</parent>
    1236             if (mixed && i < spc.length-1)
    1237                 xmlc.insertChars(pick(WORDS));
    1238         }
    1239     }
    1240
    1241     private void processChoice(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    1242     {
    1243         SchemaParticle[] spc = sp.getParticleChildren();
    1244         xmlc.insertComment("You have a CHOICE of the next " + String.valueOf(spc.length) + " items at this level");
    1245         for (int i=0; i < spc.length; i++)
    1246         {
    1247             processParticle(spc[i], xmlc, mixed);
    1248         }
    1249     }
    1250
    1251     private void processAll(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    1252     {
    1253         SchemaParticle[] spc = sp.getParticleChildren();
    1254         // xmlc.insertComment("You may enter the following " + String.valueOf(spc.length) + " items in any order");
    1255         for (int i=0; i < spc.length; i++)
    1256         {
    1257             processParticle(spc[i], xmlc, mixed);
    1258             if (mixed && i < spc.length-1)
    1259                 xmlc.insertChars(pick(WORDS));
    1260         }
    1261     }
    1262
    1263     private void processWildCard(SchemaParticle sp, XmlCursor xmlc, boolean mixed)
    1264     {
    1265         xmlc.insertComment("You may enter ANY elements at this point");
    1266         //xmlc.insertElement("AnyElement");
    1267     }
    1268
    1269     /***
    1270      * This method will get the base type for the schema type
    1271      */
    1272
    1273     private static QName getClosestName(SchemaType sType)
    1274     {
    1275         while (sType.getName() == null)
    1276             sType = sType.getBaseType();
    1277
    1278         return sType.getName();
    1279     }
    1280
    1281     private String printParticleType(int particleType)
    1282     {
    1283         StringBuffer returnParticleType = new StringBuffer();
    1284         returnParticleType.append("Schema Particle Type: ");
    1285
    1286         switch (particleType)
    1287         {
    1288             case SchemaParticle.ALL :
    1289                 returnParticleType.append("ALL\n");
    1290                 break;
    1291             case SchemaParticle.CHOICE :
    1292                 returnParticleType.append("CHOICE\n");
    1293                 break;
    1294             case SchemaParticle.ELEMENT :
    1295                 returnParticleType.append("ELEMENT\n");
    1296                 break;
    1297             case SchemaParticle.SEQUENCE :
    1298                 returnParticleType.append("SEQUENCE\n");
    1299                 break;
    1300             case SchemaParticle.WILDCARD :
    1301                 returnParticleType.append("WILDCARD\n");
    1302                 break;
    1303             default :
    1304                 returnParticleType.append("Schema Particle Type Unknown");
    1305                 break;
    1306         }
    1307
    1308         return returnParticleType.toString();
    1309     }
    1310
    1311     private ArrayList<SchemaType> _typeStack = new ArrayList<SchemaType>();
    1312
    1313 	public boolean isIgnoreOptional()
    1314 	{
    1315 		return ignoreOptional;
    1316 	}
    1317
    1318 	public void setIgnoreOptional(boolean ignoreOptional)
    1319 	{
    1320 		this.ignoreOptional = ignoreOptional;
    1321 	}
    1322
    1323 	private void addElementTypeAndRestricionsComment(SchemaLocalElement element, XmlCursor xmlc) {
    1324
    1325 		SchemaType type = element.getType();
    1326 		if (_typeComment && (type != null && type.isSimpleType()))
    1327 		{
    1328 			String info = "";
    1329
    1330 			XmlAnySimpleType[] values = type.getEnumerationValues();
    1331 			if( values != null && values.length > 0 )
    1332 			{
    1333 				info = " - enumeration: [";
    1334 				for( int c = 0; c < values.length; c++ )
    1335 				{
    1336 					if( c > 0 )
    1337 						info += ",";
    1338
    1339 					info += values[c].getStringValue();
    1340 				}
    1341
    1342 				info += "]";
    1343 			}
    1344
    1345
    1346         	if( type.isAnonymousType()  )
    1347         		xmlc.insertComment("anonymous type" + info );
    1348         	else
    1349         		xmlc.insertComment("type: " + type.getName().getLocalPart() + info);
    1350         }
    1351 	}
    1352
    1353
    1354 }