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