1 16 17 package org.apache.axis.encoding.ser; 18 19 import org.apache.axis.Constants; 20 import org.apache.axis.components.logger.LogFactory; 21 import org.apache.axis.encoding.DeserializationContext; 22 import org.apache.axis.encoding.Deserializer; 23 import org.apache.axis.encoding.DeserializerImpl; 24 import org.apache.axis.encoding.DeserializerTarget; 25 import org.apache.axis.message.SOAPHandler; 26 import org.apache.axis.utils.ClassUtils; 27 import org.apache.axis.utils.JavaUtils; 28 import org.apache.axis.utils.Messages; 29 import org.apache.axis.wsdl.symbolTable.SchemaUtils; 30 import org.apache.commons.logging.Log; 31 import org.apache.axis.soap.SOAPConstants; 32 33 import org.xml.sax.Attributes ; 34 import org.xml.sax.SAXException ; 35 36 import javax.xml.namespace.QName ; 37 import java.util.ArrayList ; 38 import java.util.HashMap ; 39 import java.util.StringTokenizer ; 40 41 42 53 public class ArrayDeserializer extends DeserializerImpl 54 { 55 protected static Log log = 56 LogFactory.getLog(ArrayDeserializer.class.getName()); 57 58 public QName arrayType = null; 59 public int curIndex = 0; 60 QName defaultItemType; 61 int length; 62 Class arrayClass = null; 63 ArrayList mDimLength = null; ArrayList mDimFactor = null; SOAPConstants soapConstants = SOAPConstants.SOAP11_CONSTANTS; 66 67 78 public void onStartElement(String namespace, String localName, 79 String prefix, Attributes attributes, 80 DeserializationContext context) 81 throws SAXException 82 { 83 109 if (log.isDebugEnabled()) { 110 log.debug("Enter: ArrayDeserializer::startElement()"); 111 } 112 113 soapConstants = context.getSOAPConstants(); 114 115 QName typeQName = context.getTypeFromAttributes(namespace, 118 localName, 119 attributes); 120 if (typeQName == null) { 121 typeQName = getDefaultType(); 122 } 123 124 if (typeQName != null && 125 Constants.equals(Constants.SOAP_ARRAY, typeQName)) { 126 typeQName = null; 127 } 128 129 QName arrayTypeValue = context.getQNameFromString( 131 Constants.getValue(attributes, 132 Constants.URIS_SOAP_ENC, 133 soapConstants.getAttrItemType())); 134 135 String dimString = null; 139 QName innerQName = null; 140 String innerDimString = ""; 141 if (arrayTypeValue != null) { 142 if (soapConstants != SOAPConstants.SOAP12_CONSTANTS) { 143 String arrayTypeValueNamespaceURI = 146 arrayTypeValue.getNamespaceURI(); 147 String arrayTypeValueLocalPart = 148 arrayTypeValue.getLocalPart(); 149 150 int leftBracketIndex = 151 arrayTypeValueLocalPart.lastIndexOf('['); 152 int rightBracketIndex = 153 arrayTypeValueLocalPart.lastIndexOf(']'); 154 if (leftBracketIndex == -1 155 || rightBracketIndex == -1 156 || rightBracketIndex < leftBracketIndex) { 157 throw new IllegalArgumentException ( 158 Messages.getMessage("badArrayType00", 159 "" + arrayTypeValue)); 160 } 161 162 dimString = 163 arrayTypeValueLocalPart.substring(leftBracketIndex + 1, 164 rightBracketIndex); 165 arrayTypeValueLocalPart = 166 arrayTypeValueLocalPart.substring(0, leftBracketIndex); 167 168 if (arrayTypeValueLocalPart.endsWith("]")) { 170 defaultItemType = Constants.SOAP_ARRAY; 171 int bracket = arrayTypeValueLocalPart.indexOf("["); 172 innerQName = new QName (arrayTypeValueNamespaceURI, 173 arrayTypeValueLocalPart.substring(0, bracket)); 174 innerDimString = arrayTypeValueLocalPart.substring(bracket); 175 } else { 176 defaultItemType = new QName (arrayTypeValueNamespaceURI, 177 arrayTypeValueLocalPart); 178 } 179 180 } else { 181 String arraySizeValue = attributes.getValue(soapConstants.getEncodingURI(), Constants.ATTR_ARRAY_SIZE); 182 int leftStarIndex = arraySizeValue.lastIndexOf('*'); 183 184 if (leftStarIndex != -1) { 186 if (leftStarIndex == 0 && arraySizeValue.length() == 1) { 188 } else if (leftStarIndex == (arraySizeValue.length() - 1)) { 190 throw new IllegalArgumentException ( 191 Messages.getMessage("badArraySize00", 192 "" + arraySizeValue)); 193 } else { 195 dimString = arraySizeValue.substring(leftStarIndex + 2); 196 innerQName = arrayTypeValue; 197 innerDimString = arraySizeValue.substring(0, leftStarIndex + 1); 198 } 199 } else { 200 dimString = arraySizeValue; 201 } 202 203 if (innerDimString == null || innerDimString.length() == 0) { 204 defaultItemType = arrayTypeValue; 205 } else { 206 defaultItemType = Constants.SOAP_ARRAY12; 207 } 208 } 209 } 210 211 if (defaultItemType == null && typeQName == null) { 213 Class destClass = context.getDestinationClass(); 214 if (destClass != null && destClass.isArray()) { 215 } else { 217 defaultItemType = Constants.XSD_ANYTYPE; 218 } 219 } 220 221 arrayClass = null; 223 if (typeQName != null) { 224 arrayClass = context.getTypeMapping(). 225 getClassForQName(typeQName); 226 } 227 228 if (typeQName == null || arrayClass == null) { 229 Class arrayItemClass = null; 232 QName compQName = defaultItemType; 233 234 String dims = "[]"; 236 if (innerQName != null) { 237 compQName = innerQName; 238 239 if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) { 240 int offset = 0; 242 while ((offset = innerDimString.indexOf('*', offset)) != -1) { 243 dims += "[]"; 244 offset ++; 245 } 246 } else { 247 dims += innerDimString; 249 } 250 } 251 252 arrayItemClass = context.getTypeMapping().getClassForQName(compQName); 254 if (arrayItemClass != null) { 255 try { 256 String loadableArrayClassName = JavaUtils.getLoadableClassName( 260 JavaUtils.getTextClassName(arrayItemClass.getName()) + dims); 261 arrayClass = ClassUtils.forName(loadableArrayClassName, 262 true, 263 arrayItemClass.getClassLoader()); 264 } catch (Exception e) { 265 throw new SAXException ( 266 Messages.getMessage("noComponent00", 267 "" + defaultItemType)); 268 } 269 } 270 } 271 if (arrayClass == null) { 272 arrayClass = context.getDestinationClass(); 273 } 274 275 if (arrayClass == null) { 276 throw new SAXException ( 277 Messages.getMessage("noComponent00", "" + defaultItemType)); 278 } 279 280 if (dimString == null || dimString.length() == 0) { 281 value = new ArrayListExtension(arrayClass); 283 } else { 284 try 285 { 286 StringTokenizer tokenizer; 287 if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) { 288 tokenizer = new StringTokenizer (dimString); 289 } else { 290 tokenizer = new StringTokenizer (dimString, "[],"); 291 } 292 293 length = Integer.parseInt(tokenizer.nextToken()); 294 if (tokenizer.hasMoreTokens()) { 295 mDimLength = new ArrayList (); 301 mDimLength.add(new Integer (length)); 302 303 while(tokenizer.hasMoreTokens()) { 304 mDimLength.add( 305 new Integer ( 306 Integer.parseInt(tokenizer.nextToken()))); 307 } 308 } 309 310 ArrayList list = new ArrayListExtension(arrayClass, length); 313 314 value = list; 321 322 } 323 catch (NumberFormatException e) 324 { 325 throw new IllegalArgumentException ( 326 Messages.getMessage("badInteger00", dimString)); 327 } 328 } 329 330 String offset = Constants.getValue(attributes, 332 Constants.URIS_SOAP_ENC, 333 Constants.ATTR_OFFSET); 334 if (offset != null) { 335 if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) { 336 throw new SAXException (Messages.getMessage("noSparseArray")); 337 } 338 339 int leftBracketIndex = offset.lastIndexOf('['); 340 int rightBracketIndex = offset.lastIndexOf(']'); 341 342 if (leftBracketIndex == -1 343 || rightBracketIndex == -1 344 || rightBracketIndex < leftBracketIndex) 345 { 346 throw new SAXException ( 347 Messages.getMessage("badOffset00", offset)); 348 } 349 350 curIndex = 351 convertToIndex(offset.substring(leftBracketIndex + 1, 352 rightBracketIndex), 353 "badOffset00"); 354 } 355 356 if (log.isDebugEnabled()) { 357 log.debug("Exit: ArrayDeserializer::startElement()"); 358 } 359 } 360 361 362 373 public SOAPHandler onStartChild(String namespace, 374 String localName, 375 String prefix, 376 Attributes attributes, 377 DeserializationContext context) 378 throws SAXException 379 { 380 if (log.isDebugEnabled()) { 381 log.debug("Enter: ArrayDeserializer.onStartChild()"); 382 } 383 384 if (attributes != null) { 387 String pos = 388 Constants.getValue(attributes, 389 Constants.URIS_SOAP_ENC, 390 Constants.ATTR_POSITION); 391 if (pos != null) { 392 if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) { 393 throw new SAXException (Messages.getMessage("noSparseArray")); 394 } 395 396 int leftBracketIndex = pos.lastIndexOf('['); 397 int rightBracketIndex = pos.lastIndexOf(']'); 398 399 if (leftBracketIndex == -1 400 || rightBracketIndex == -1 401 || rightBracketIndex < leftBracketIndex) 402 { 403 throw new SAXException ( 404 Messages.getMessage("badPosition00", pos)); 405 } 406 407 curIndex = 408 convertToIndex(pos.substring(leftBracketIndex + 1, 409 rightBracketIndex), 410 "badPosition00"); 411 } 412 413 if (context.isNil(attributes)) { 416 setChildValue(null, new Integer (curIndex++)); 417 return null; 418 } 419 } 420 421 QName itemType = context.getTypeFromAttributes(namespace, 423 localName, 424 attributes); 425 426 Deserializer dSer = null; 428 if (itemType != null && (context.getCurElement().getHref() == null)) { 429 dSer = context.getDeserializerForType(itemType); 430 } 431 432 if (dSer == null) { 433 QName defaultType = defaultItemType; 435 Class javaType = null; 436 if (arrayClass != null && 437 arrayClass.isArray() && 438 defaultType == null) { 439 javaType = arrayClass.getComponentType(); 440 defaultType = context.getTypeMapping().getTypeQName(javaType); 441 } 442 443 if (itemType == null && dSer == null) { 453 if (defaultType != null && SchemaUtils.isSimpleSchemaType(defaultType)) { 454 dSer = context.getDeserializer(javaType, defaultType); 455 } 456 } 457 458 if (dSer == null) { 463 dSer = new DeserializerImpl(); 464 if (itemType == null) { 466 dSer.setDefaultType(defaultType); 467 } 468 } 469 } 470 471 472 dSer.registerValueTarget( 475 new DeserializerTarget(this, new Integer (curIndex))); 476 477 addChildDeserializer(dSer); 480 481 curIndex++; 482 483 context.setDestinationClass(arrayClass.getComponentType()); 486 487 if (log.isDebugEnabled()) { 488 log.debug("Exit: ArrayDeserializer.onStartChild()"); 489 } 490 491 return (SOAPHandler)dSer; 492 } 493 494 public void onEndChild(String namespace, String localName, DeserializationContext context) throws SAXException { 495 context.setDestinationClass(arrayClass); 497 } 498 499 public void characters(char[] chars, int i, int i1) throws SAXException { 500 for (int idx = i; i < i1; i++) { 501 if (!Character.isWhitespace(chars[idx])) 502 throw new SAXException (Messages.getMessage("charsInArray")); 503 } 504 } 505 506 521 public void setChildValue(Object value, Object hint) throws SAXException 522 { 523 if (log.isDebugEnabled()) { 524 log.debug("Enter: ArrayDeserializer::setValue(" + value + ", " + hint + ")"); 525 } 526 ArrayList list = (ArrayList )this.value; 527 int offset = ((Integer )hint).intValue(); 528 529 if (this.mDimLength == null) { 530 while (list.size() <= offset) { 533 list.add(null); 534 } 535 536 list.set(offset, value); 537 } else { 538 541 ArrayList mDimIndex = toMultiIndex(offset); 543 544 for(int i=0; i < mDimLength.size(); i++) { 546 int length = ((Integer )mDimLength.get(i)).intValue(); 547 int index = ((Integer )mDimIndex.get(i)).intValue(); 548 while (list.size() < length) { 549 list.add(null); 550 } 551 if (i < mDimLength.size()-1) { 554 if (list.get(index) == null) { 555 list.set(index, new ArrayList ()); 556 } 557 list = (ArrayList ) list.get(index); 558 } else { 559 list.set(index, value); 560 } 561 } 562 } 563 } 564 565 571 public void valueComplete() throws SAXException 572 { 573 if (componentsReady()) { 574 try { 575 if (arrayClass != null) { 576 value = JavaUtils.convert(value, arrayClass); 577 } 578 } catch (RuntimeException e) { 579 } 581 } 582 583 super.valueComplete(); 584 } 585 586 598 private int convertToIndex(String text, String exceptKey) 599 throws SAXException { 600 StringTokenizer tokenizer = new StringTokenizer (text, "[],"); 601 int index = 0; 602 try { 603 if (mDimLength == null) { 604 index = Integer.parseInt(tokenizer.nextToken()); 606 if (tokenizer.hasMoreTokens()) { 607 throw new SAXException ( 608 Messages.getMessage(exceptKey, text)); 609 } 610 } 611 else { 612 int dim = -1; 614 ArrayList work = new ArrayList (); 615 while(tokenizer.hasMoreTokens()) { 616 dim++; 619 if (dim >= mDimLength.size()) { 620 throw new SAXException ( 621 Messages.getMessage(exceptKey, text)); 622 } 623 int workIndex = Integer.parseInt(tokenizer.nextToken()); 625 626 if (workIndex < 0 || 628 workIndex >= 629 ((Integer )mDimLength.get(dim)).intValue()) { 630 throw new SAXException ( 631 Messages.getMessage(exceptKey, text)); 632 } 633 work.add(new Integer (workIndex)); 634 } 635 index = toSingleIndex(work); } 637 } catch (SAXException e) { 638 throw e; 639 } catch (Exception e) { 640 throw new SAXException (Messages.getMessage(exceptKey, text)); 641 } 642 return index; 643 } 644 645 650 private ArrayList toMultiIndex(int single) { 651 if (mDimLength == null) 652 return null; 653 654 if (mDimFactor == null) { 656 mDimFactor = new ArrayList (); 657 for (int i=0; i < mDimLength.size(); i++) { 658 int factor = 1; 659 for (int j=i+1; j<mDimLength.size(); j++) { 660 factor *= ((Integer )mDimLength.get(j)).intValue(); 661 } 662 mDimFactor.add(new Integer (factor)); 663 } 664 } 665 666 ArrayList rc = new ArrayList (); 667 for (int i=0; i < mDimLength.size(); i++) { 668 int factor = ((Integer )mDimFactor.get(i)).intValue(); 669 rc.add(new Integer (single / factor)); 670 single = single % factor; 671 } 672 return rc; 673 } 674 675 680 private int toSingleIndex(ArrayList indexArray) { 681 if (mDimLength == null || indexArray == null) 682 return -1; 683 684 if (mDimFactor == null) { 686 mDimFactor = new ArrayList (); 687 for (int i=0; i < mDimLength.size(); i++) { 688 int factor = 1; 689 for (int j=i+1; j<mDimLength.size(); j++) { 690 factor *= ((Integer )mDimLength.get(j)).intValue(); 691 } 692 mDimFactor.add(new Integer (factor)); 693 } 694 } 695 696 int single = 0; 697 for (int i=0; i < indexArray.size(); i++) { 698 single += ((Integer )mDimFactor.get(i)).intValue()* 699 ((Integer )indexArray.get(i)).intValue(); 700 } 701 return single; 702 } 703 704 711 public class ArrayListExtension extends ArrayList 712 implements JavaUtils.ConvertCache { 713 private HashMap table = null; 714 private Class arrayClass = null; 718 ArrayListExtension(Class arrayClass) { 719 super(); 720 this.arrayClass = arrayClass; 721 if (arrayClass == null || 724 arrayClass.isInterface() || 725 java.lang.reflect.Modifier.isAbstract( 726 arrayClass.getModifiers())) { 727 arrayClass = null; 728 } 729 } 730 ArrayListExtension(Class arrayClass, int length) { 731 super(length > 50000 ? 50000 : length); 733 this.arrayClass = arrayClass; 734 if (arrayClass == null || 737 arrayClass.isInterface() || 738 java.lang.reflect.Modifier.isAbstract( 739 arrayClass.getModifiers())) { 740 arrayClass = null; 741 } 742 } 743 746 public void setConvertedValue(Class cls, Object value) { 747 if (table == null) 748 table = new HashMap (); 749 table.put(cls, value); 750 } 751 754 public Object getConvertedValue(Class cls) { 755 if (table == null) 756 return null; 757 return table.get(cls); 758 } 759 760 763 public Class getDestClass() { 764 return arrayClass; 765 } 766 } 767 768 } 769 | Popular Tags |