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