1 17 package org.eclipse.emf.ecore.xmi.impl; 18 19 20 import java.io.File ; 21 import java.io.IOException ; 22 import java.io.OutputStream ; 23 import java.io.OutputStreamWriter ; 24 import java.lang.reflect.Field ; 25 import java.util.ArrayList ; 26 import java.util.Collections ; 27 import java.util.HashSet ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import java.util.Map ; 31 import java.util.Set ; 32 33 import org.eclipse.emf.common.util.EMap; 34 import org.eclipse.emf.common.util.URI; 35 import org.eclipse.emf.ecore.EClass; 36 import org.eclipse.emf.ecore.EClassifier; 37 import org.eclipse.emf.ecore.EDataType; 38 import org.eclipse.emf.ecore.EFactory; 39 import org.eclipse.emf.ecore.EObject; 40 import org.eclipse.emf.ecore.EPackage; 41 import org.eclipse.emf.ecore.EReference; 42 import org.eclipse.emf.ecore.EStructuralFeature; 43 import org.eclipse.emf.ecore.InternalEObject; 44 import org.eclipse.emf.ecore.resource.Resource; 45 import org.eclipse.emf.ecore.util.BasicExtendedMetaData; 46 import org.eclipse.emf.ecore.util.ExtendedMetaData; 47 import org.eclipse.emf.ecore.util.FeatureMap; 48 import org.eclipse.emf.ecore.util.InternalEList; 49 import org.eclipse.emf.ecore.xmi.DOMHandler; 50 import org.eclipse.emf.ecore.xmi.DanglingHREFException; 51 import org.eclipse.emf.ecore.xmi.NameInfo; 52 import org.eclipse.emf.ecore.xmi.XMLHelper; 53 import org.eclipse.emf.ecore.xmi.XMLResource; 54 import org.eclipse.emf.ecore.xmi.XMLSave; 55 import org.eclipse.emf.ecore.xml.namespace.XMLNamespacePackage; 56 import org.eclipse.emf.ecore.xml.type.AnyType; 57 import org.eclipse.emf.ecore.xml.type.SimpleAnyType; 58 import org.eclipse.emf.ecore.xml.type.XMLTypePackage; 59 import org.eclipse.emf.ecore.xml.type.internal.DataValue.XMLChar; 60 import org.w3c.dom.Attr ; 61 import org.w3c.dom.Document ; 62 import org.w3c.dom.Element ; 63 import org.w3c.dom.Node ; 64 65 66 70 public class XMLSaveImpl implements XMLSave 71 { 72 protected static final int INDEX_LOOKUP = 0; 73 74 final StringBuffer buffer = new StringBuffer (); 75 76 protected XMLHelper helper; 77 protected XMLString doc; 78 protected boolean declareXSI; 79 protected boolean useEncodedAttributeStyle; 80 protected boolean declareXML; 81 protected boolean saveTypeInfo; 82 protected XMLTypeInfo xmlTypeInfo; 83 protected boolean keepDefaults; 84 protected Escape escape; 85 protected Escape escapeURI; 86 protected Lookup featureTable; 87 protected String encoding; 88 protected String idAttributeName = "id"; 89 protected String idAttributeNS = null; 90 protected String processDanglingHREF; 91 protected boolean declareSchemaLocation; 92 protected boolean declareSchemaLocationImplementation; 93 protected XMLResource.XMLMap map; 94 protected ExtendedMetaData extendedMetaData; 95 protected EClass anySimpleType; 96 protected EClass anyType; 97 protected Map eObjectToExtensionMap; 98 protected EPackage xmlSchemaTypePackage = XMLTypePackage.eINSTANCE; 99 protected int flushThreshold = Integer.MAX_VALUE; 100 protected boolean toDOM; 101 protected DOMHandler handler; 102 protected Document document; 103 protected Node currentNode; 104 protected NameInfo nameInfo; 105 protected boolean useCache; 106 107 protected static final int SKIP = 0; 108 protected static final int SAME_DOC = 1; 109 protected static final int CROSS_DOC = 2; 110 111 protected static final int TRANSIENT = 0; 112 protected static final int DATATYPE_SINGLE = 1; 113 protected static final int DATATYPE_ELEMENT_SINGLE = 2; 114 protected static final int DATATYPE_CONTENT_SINGLE = 3; 115 protected static final int DATATYPE_SINGLE_NILLABLE = 4; 116 protected static final int DATATYPE_MANY = 5; 117 protected static final int OBJECT_CONTAIN_SINGLE = 6; 118 protected static final int OBJECT_CONTAIN_MANY = 7; 119 protected static final int OBJECT_HREF_SINGLE = 8; 120 protected static final int OBJECT_HREF_MANY = 9; 121 protected static final int OBJECT_CONTAIN_SINGLE_UNSETTABLE = 10; 122 protected static final int OBJECT_CONTAIN_MANY_UNSETTABLE = 11; 123 protected static final int OBJECT_HREF_SINGLE_UNSETTABLE = 12; 124 protected static final int OBJECT_HREF_MANY_UNSETTABLE = 13; 125 protected static final int OBJECT_ELEMENT_SINGLE = 14; 126 protected static final int OBJECT_ELEMENT_SINGLE_UNSETTABLE = 15; 127 protected static final int OBJECT_ELEMENT_MANY = 16; 128 protected static final int OBJECT_ELEMENT_IDREF_SINGLE = 17; 129 protected static final int OBJECT_ELEMENT_IDREF_SINGLE_UNSETTABLE = 18; 130 protected static final int OBJECT_ELEMENT_IDREF_MANY = 19; 131 protected static final int ATTRIBUTE_FEATURE_MAP = 20; 132 protected static final int ELEMENT_FEATURE_MAP = 21; 133 protected static final int OBJECT_ATTRIBUTE_SINGLE = 22; 134 protected static final int OBJECT_ATTRIBUTE_MANY = 23; 135 protected static final int OBJECT_ATTRIBUTE_IDREF_SINGLE = 24; 136 protected static final int OBJECT_ATTRIBUTE_IDREF_MANY = 25; 137 protected static final int DATATYPE_ATTRIBUTE_MANY = 26; 138 139 protected static final String XML_VERSION = "1.0"; 140 141 protected static final String XSI_NIL = XMLResource.XSI_NS+":"+XMLResource.NIL; protected static final String XSI_TYPE_NS = XMLResource.XSI_NS+":"+XMLResource.TYPE; protected static final String XSI_XMLNS = XMLResource.XML_NS+":"+XMLResource.XSI_NS; protected static final String XSI_SCHEMA_LOCATION = XMLResource.XSI_NS+":"+XMLResource.SCHEMA_LOCATION; protected static final String XSI_NO_NAMESPACE_SCHEMA_LOCATION = XMLResource.XSI_NS+":"+XMLResource.NO_NAMESPACE_SCHEMA_LOCATION; 147 protected static final int EMPTY_ELEMENT = 1; 148 protected static final int CONTENT_ELEMENT = 2; 149 150 public XMLSaveImpl(XMLHelper helper) 151 { 152 this.helper = helper; 153 } 154 155 161 public XMLSaveImpl(Map options, XMLHelper helper, String encoding) 162 { 163 this.helper = helper; 164 init(helper.getResource(), options); 165 this.encoding = encoding; 166 } 167 168 public Document save(XMLResource resource, Document doc, Map options, DOMHandler handler) 169 { 170 toDOM = true; 171 document = doc; 172 this.handler = handler; 173 174 init(resource, options); 175 List contents = resource.getContents(); 176 traverse(contents); 177 if (extendedMetaData != null && contents.size() >= 1) 178 { 179 EObject root = (EObject)contents.get(0); 180 EClass eClass = root.eClass(); 181 182 EReference xmlnsPrefixMapFeature = extendedMetaData.getXMLNSPrefixMapFeature(eClass); 183 if (xmlnsPrefixMapFeature != null) 184 { 185 EMap xmlnsPrefixMap = (EMap)root.eGet(xmlnsPrefixMapFeature); 186 for (Iterator i = helper.getPrefixToNamespaceMap().iterator(); i.hasNext(); ) 187 { 188 Map.Entry entry = (Map.Entry )i.next(); 189 Object key = entry.getKey(); 190 Object value = entry.getValue(); 191 Object currentValue = xmlnsPrefixMap.get(key); 192 if (currentValue == null ? value != null : !currentValue.equals(value)) 193 { 194 xmlnsPrefixMap.put(key, value); 195 } 196 } 197 } 198 } 199 return document; 200 } 201 202 public void save(XMLResource resource, OutputStream outputStream, Map options) throws IOException 203 { 204 init(resource, options); 205 List contents = resource.getContents(); 206 traverse(contents); 207 208 if (encoding.equals("US-ASCII") || encoding.equals("ASCII")) 209 { 210 writeAscii(outputStream); 211 outputStream.flush(); 212 } 213 else 214 { 215 OutputStreamWriter outputStreamWriter = new OutputStreamWriter (outputStream, helper.getJavaEncoding(encoding)); 216 write(outputStreamWriter); 217 outputStreamWriter.flush(); 218 } 219 220 if (extendedMetaData != null && contents.size() >= 1) 221 { 222 EObject root = (EObject)contents.get(0); 223 EClass eClass = root.eClass(); 224 225 EReference xmlnsPrefixMapFeature = extendedMetaData.getXMLNSPrefixMapFeature(eClass); 226 if (xmlnsPrefixMapFeature != null) 227 { 228 EMap xmlnsPrefixMap = (EMap)root.eGet(xmlnsPrefixMapFeature); 229 for (Iterator i = helper.getPrefixToNamespaceMap().iterator(); i.hasNext(); ) 230 { 231 Map.Entry entry = (Map.Entry )i.next(); 232 Object key = entry.getKey(); 233 Object value = entry.getValue(); 234 Object currentValue = xmlnsPrefixMap.get(key); 235 if (currentValue == null ? value != null : !currentValue.equals(value)) 236 { 237 xmlnsPrefixMap.put(key, value); 238 } 239 } 240 } 241 } 242 243 if (processDanglingHREF == null || 244 XMLResource.OPTION_PROCESS_DANGLING_HREF_THROW.equals(processDanglingHREF)) 245 { 246 DanglingHREFException exception = helper.getDanglingHREFException(); 247 248 if (exception != null) 249 { 250 helper = null; 251 throw new Resource.IOWrappedException(exception); 252 } 253 } 254 255 if (useCache) 256 { 257 ConfigurationCache.INSTANCE.releasePrinter(doc); 258 if (escape != null) 259 { 260 ConfigurationCache.INSTANCE.releaseEscape(escape); 261 } 262 } 263 featureTable = null; 264 doc = null; 265 helper = null; 266 } 267 268 269 protected void init(XMLResource resource, Map options) 270 { 271 useCache = Boolean.TRUE.equals(options.get(XMLResource.OPTION_CONFIGURATION_CACHE)); 272 273 nameInfo = new NameInfoImpl(); 274 declareXSI = false; 275 keepDefaults = Boolean.TRUE.equals(options.get(XMLResource.OPTION_KEEP_DEFAULT_CONTENT)); 276 useEncodedAttributeStyle = Boolean.TRUE.equals(options.get(XMLResource.OPTION_USE_ENCODED_ATTRIBUTE_STYLE)); 277 declareSchemaLocationImplementation = Boolean.TRUE.equals(options.get(XMLResource.OPTION_SCHEMA_LOCATION_IMPLEMENTATION)); 278 declareSchemaLocation = declareSchemaLocationImplementation || Boolean.TRUE.equals(options.get(XMLResource.OPTION_SCHEMA_LOCATION)); 279 280 Object saveTypeInfoOption = options.get(XMLResource.OPTION_SAVE_TYPE_INFORMATION); 281 if (saveTypeInfoOption instanceof Boolean ) 282 { 283 saveTypeInfo = saveTypeInfoOption.equals(Boolean.TRUE); 284 if (saveTypeInfo) 285 { 286 xmlTypeInfo = new XMLTypeInfoImpl(); 287 } 288 } 289 else 290 { 291 saveTypeInfo = saveTypeInfoOption != null; 292 if (saveTypeInfo) 293 { 294 xmlTypeInfo = (XMLTypeInfo)saveTypeInfoOption; 295 } 296 } 297 298 anyType = (EClass)options.get(XMLResource.OPTION_ANY_TYPE); 299 anySimpleType = (EClass)options.get(XMLResource.OPTION_ANY_SIMPLE_TYPE); 300 if (anyType == null) 301 { 302 anyType = XMLTypePackage.eINSTANCE.getAnyType(); 303 anySimpleType = XMLTypePackage.eINSTANCE.getSimpleAnyType(); 304 } 305 306 Object extendedMetaDataOption = options.get(XMLResource.OPTION_EXTENDED_META_DATA); 307 if (extendedMetaDataOption instanceof Boolean ) 308 { 309 if (extendedMetaDataOption.equals(Boolean.TRUE)) 310 { 311 extendedMetaData = 312 resource == null || resource.getResourceSet() == null ? 313 ExtendedMetaData.INSTANCE : 314 new BasicExtendedMetaData(resource.getResourceSet().getPackageRegistry()); 315 } 316 } 317 else 318 { 319 extendedMetaData = (ExtendedMetaData)options.get(XMLResource.OPTION_EXTENDED_META_DATA); 320 } 321 322 if (!toDOM) 324 { 325 declareXML = !Boolean.FALSE.equals(options.get(XMLResource.OPTION_DECLARE_XML)); 326 327 if (options.get(XMLResource.OPTION_FLUSH_THRESHOLD) instanceof Integer ) 328 { 329 flushThreshold = ((Integer )options.get(XMLResource.OPTION_FLUSH_THRESHOLD)).intValue(); 330 } 331 332 String temporaryFileName = null; 333 if (Boolean.TRUE.equals(options.get(XMLResource.OPTION_USE_FILE_BUFFER))) 334 { 335 try 336 { 337 temporaryFileName = File.createTempFile("XMLSave", null).getPath(); 338 } 339 catch (IOException exception) 340 { 341 } 343 } 344 345 Integer lineWidth = (Integer )options.get(XMLResource.OPTION_LINE_WIDTH); 346 int effectiveLineWidth = lineWidth == null ? Integer.MAX_VALUE : lineWidth.intValue(); 347 String publicId = null, systemId = null; 348 if (resource != null && Boolean.TRUE.equals(options.get(XMLResource.OPTION_SAVE_DOCTYPE))) 349 { 350 publicId = resource.getPublicId(); 351 systemId = resource.getSystemId(); 352 } 353 if (useCache) 354 { 355 doc = ConfigurationCache.INSTANCE.getPrinter(); 356 doc.reset(publicId, systemId, effectiveLineWidth, temporaryFileName); 357 escape = Boolean.TRUE.equals(options.get(XMLResource.OPTION_SKIP_ESCAPE)) ? null : ConfigurationCache.INSTANCE.getEscape(); 358 } 359 else 360 { 361 doc = new XMLString(effectiveLineWidth, publicId, systemId, temporaryFileName); 362 escape = Boolean.TRUE.equals(options.get(XMLResource.OPTION_SKIP_ESCAPE)) ? null : new Escape(); 363 } 364 365 if (Boolean.FALSE.equals(options.get(XMLResource.OPTION_FORMATTED))) 366 { 367 doc.setUnformatted(true); 368 } 369 370 371 escapeURI = Boolean.FALSE.equals(options.get(XMLResource.OPTION_SKIP_ESCAPE_URI)) ? escape : null; 372 373 if (options.containsKey(XMLResource.OPTION_ENCODING)) 374 { 375 encoding = (String )options.get(XMLResource.OPTION_ENCODING); 376 } 377 else if (resource != null) 378 { 379 encoding = resource.getEncoding(); 380 } 381 } 382 else 383 { 384 if (handler instanceof DefaultDOMHandlerImpl) 386 { 387 ((DefaultDOMHandlerImpl)handler).setExtendedMetaData(extendedMetaData); 388 } 389 } 390 processDanglingHREF = (String ) options.get(XMLResource.OPTION_PROCESS_DANGLING_HREF); 391 helper.setProcessDanglingHREF(processDanglingHREF); 392 393 map = (XMLResource.XMLMap) options.get(XMLResource.OPTION_XML_MAP); 394 if (map != null) 395 { 396 helper.setXMLMap(map); 397 398 if (map.getIDAttributeName() != null) 399 { 400 idAttributeName = map.getIDAttributeName(); 401 } 402 } 403 404 if (resource != null) 405 { 406 eObjectToExtensionMap = resource.getEObjectToExtensionMap(); 407 if (eObjectToExtensionMap.isEmpty()) 408 { 409 eObjectToExtensionMap = null; 410 } 411 else if (extendedMetaData == null) 412 { 413 extendedMetaData = 414 resource.getResourceSet() == null ? 415 ExtendedMetaData.INSTANCE : 416 new BasicExtendedMetaData(resource.getResourceSet().getPackageRegistry()); 417 } 418 } 419 420 if (extendedMetaData != null) 421 { 422 helper.setExtendedMetaData(extendedMetaData); 423 if (resource != null && resource.getContents().size() >=1) 424 { 425 EObject root = (EObject)resource.getContents().get(0); 426 EClass eClass = root.eClass(); 427 428 EReference xmlnsPrefixMapFeature = extendedMetaData.getXMLNSPrefixMapFeature(eClass); 429 if (xmlnsPrefixMapFeature != null) 430 { 431 EMap xmlnsPrefixMap = (EMap)root.eGet(xmlnsPrefixMapFeature); 432 helper.setPrefixToNamespaceMap(xmlnsPrefixMap); 433 } 434 } 435 } 436 437 List lookup = (List )options.get(XMLResource.OPTION_USE_CACHED_LOOKUP_TABLE); 438 if (lookup != null) 439 { 440 if (lookup.isEmpty()) 442 { 443 featureTable = new Lookup(map, extendedMetaData); 444 lookup.add(featureTable); 445 } 446 else 447 { 448 featureTable = (Lookup)lookup.get(INDEX_LOOKUP); 449 } 450 } 451 else 452 { 453 featureTable = new Lookup(map, extendedMetaData); 455 } 456 } 457 458 public void traverse(List contents) 459 { 460 if (!toDOM && declareXML) 461 { 462 doc.add("<?xml version=\"" + XML_VERSION + "\" encoding=\"" + encoding + "\"?>"); 463 doc.addLine(); 464 } 465 466 int size = contents.size(); 467 468 Object mark; 471 472 if (size == 1) 473 { 474 mark = writeTopObject((EObject) contents.get(0)); 475 } 476 else 477 { 478 mark = writeTopObjects(contents); 479 } 480 if (!toDOM) 481 { 482 doc.resetToMark(mark); 485 } 486 else 487 { 488 currentNode = document.getDocumentElement(); 489 } 490 addNamespaceDeclarations(); 491 } 492 495 protected void writeTopAttributes(EObject top) 496 { 497 } 498 499 protected Object writeTopObject(EObject top) 500 { 501 EClass eClass = top.eClass(); 502 if (!toDOM) 503 { 504 if (extendedMetaData == null || featureTable.getDocumentRoot(eClass.getEPackage()) != eClass) 505 { 506 String name = helper.getQName(eClass); 507 doc.startElement(name); 508 writeTopAttributes(top); 509 Object mark = doc.mark(); 510 saveElementID(top); 511 return mark; 512 } 513 else 514 { 515 doc.startElement(null); 516 saveFeatures(top); 517 return null; 518 } 519 } 520 else 521 { 522 if (extendedMetaData == null || extendedMetaData.getDocumentRoot(eClass.getEPackage()) != eClass) 523 { 524 helper.populateNameInfo(nameInfo, eClass); 525 if (document.getLastChild() == null) 526 { 527 currentNode = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 528 currentNode = document.appendChild(currentNode); 529 } 530 else 531 { 532 currentNode = currentNode.appendChild(document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName())); 533 } 534 handler.recordValues(currentNode, null, null, top); 535 writeTopAttributes(top); 536 saveElementID(top); 537 return null; 538 } 539 else 540 { 541 saveFeatures(top); 542 return null; 543 } 544 } 545 } 546 547 protected Object writeTopObjects(List contents) 548 { 549 return writeTopObject((EObject)contents.get(0)); 550 } 551 552 protected void addNamespaceDeclarations() 553 { 554 EPackage noNamespacePackage = helper.getNoNamespacePackage(); 555 EPackage[] packages = helper.packages(); 556 buffer.setLength(0); 557 StringBuffer xsiSchemaLocation = buffer; 558 String xsiNoNamespaceSchemaLocation = null; 559 if (declareSchemaLocation) 560 { 561 Map handledBySchemaLocationMap = Collections.EMPTY_MAP; 562 563 if (extendedMetaData != null) 564 { 565 Resource resource = helper.getResource(); 566 if (resource != null && resource.getContents().size() >= 1) 567 { 568 EObject root = (EObject)resource.getContents().get(0); 569 EClass eClass = root.eClass(); 570 571 EReference xsiSchemaLocationMapFeature = extendedMetaData.getXSISchemaLocationMapFeature(eClass); 572 if (xsiSchemaLocationMapFeature != null) 573 { 574 EMap xsiSchemaLocationMap = (EMap)root.eGet(xsiSchemaLocationMapFeature); 575 if (!xsiSchemaLocationMap.isEmpty()) 576 { 577 handledBySchemaLocationMap = xsiSchemaLocationMap.map(); 578 declareXSI = true; 579 for (Iterator i = xsiSchemaLocationMap.entrySet().iterator(); i.hasNext(); ) 580 { 581 Map.Entry entry = (Map.Entry )i.next(); 582 String namespace = (String )entry.getKey(); 583 URI location = URI.createURI(entry.getValue().toString()); 584 if (namespace == null) 585 { 586 xsiNoNamespaceSchemaLocation = helper.deresolve(location).toString(); 587 } 588 else 589 { 590 if (xsiSchemaLocation.length() > 0) 591 { 592 xsiSchemaLocation.append(' '); 593 } 594 xsiSchemaLocation.append(namespace); 595 xsiSchemaLocation.append(' '); 596 xsiSchemaLocation.append(helper.deresolve(location).toString()); 597 } 598 } 599 } 600 } 601 } 602 } 603 604 for (int i = 0; i < packages.length; i++) 605 { 606 EPackage ePackage = packages[i]; 607 608 String javaImplementationLocation = null; 609 if (declareSchemaLocationImplementation) 610 { 611 try 614 { 615 Field field = ePackage.getClass().getField("eINSTANCE"); 616 javaImplementationLocation = "java://" + field.getDeclaringClass().getName(); 617 } 618 catch (Exception exception) 619 { 620 } 621 } 622 623 if (noNamespacePackage == ePackage) 624 { 625 if (ePackage.eResource() != null && !handledBySchemaLocationMap.containsKey(null)) 626 { 627 declareXSI = true; 628 if (javaImplementationLocation != null) 629 { 630 xsiNoNamespaceSchemaLocation = javaImplementationLocation; 631 } 632 else 633 { 634 xsiNoNamespaceSchemaLocation = helper.getHREF(ePackage); 635 if (xsiNoNamespaceSchemaLocation.endsWith("#/")) 636 { 637 xsiNoNamespaceSchemaLocation = xsiNoNamespaceSchemaLocation.substring(0, xsiNoNamespaceSchemaLocation.length() - 2); 638 } 639 } 640 } 641 } 642 else 643 { 644 Resource resource = ePackage.eResource(); 645 if (resource != null) 646 { 647 String nsURI = ePackage.getNsURI(); 648 if (!handledBySchemaLocationMap.containsKey(nsURI)) 649 { 650 URI uri = resource.getURI(); 651 if (javaImplementationLocation != null || (uri == null ? nsURI != null : !uri.toString().equals(nsURI))) 652 { 653 declareXSI = true; 654 if (xsiSchemaLocation.length() > 0) 655 { 656 xsiSchemaLocation.append(' '); 657 } 658 xsiSchemaLocation.append(nsURI); 659 xsiSchemaLocation.append(' '); 660 String location = javaImplementationLocation == null ? helper.getHREF(ePackage) : javaImplementationLocation; 661 if (location.endsWith("#/")) 662 { 663 location = location.substring(0, location.length() - 2); 664 } 665 xsiSchemaLocation.append(location); 666 } 667 } 668 } 669 } 670 } 671 } 672 673 if (declareXSI) 674 { 675 if (!toDOM) 676 { 677 doc.addAttribute(XSI_XMLNS, XMLResource.XSI_URI); 678 } 679 else 680 { 681 ((Element )currentNode).setAttributeNS(ExtendedMetaData.XMLNS_URI, XSI_XMLNS, XMLResource.XSI_URI); 682 } 683 } 684 685 for (int i = 0; i < packages.length; i++) 686 { 687 EPackage ePackage = packages[i]; 688 if (ePackage != noNamespacePackage && 689 ePackage != XMLNamespacePackage.eINSTANCE && 690 !ExtendedMetaData.XMLNS_URI.equals(ePackage.getNsURI())) 691 { 692 String nsURI = extendedMetaData == null ? ePackage.getNsURI() : extendedMetaData.getNamespace(ePackage); 693 if (ePackage == xmlSchemaTypePackage) 694 { 695 nsURI = XMLResource.XML_SCHEMA_URI; 696 } 697 if (nsURI != null && !isDuplicateURI(nsURI)) 698 { 699 List nsPrefixes = helper.getPrefixes(ePackage); 700 for (Iterator j = nsPrefixes.iterator(); j.hasNext(); ) 701 { 702 String nsPrefix = (String )j.next(); 703 if (!toDOM) 704 { 705 if (nsPrefix != null && nsPrefix.length() > 0) 706 { 707 doc.addAttributeNS(XMLResource.XML_NS, nsPrefix, nsURI); 708 } 709 else 710 { 711 doc.addAttribute(XMLResource.XML_NS, nsURI); 712 } 713 } 714 else 715 { 716 if (nsPrefix != null && nsPrefix.length() > 0) 717 { 718 ((Element )currentNode).setAttributeNS(ExtendedMetaData.XMLNS_URI, XMLResource.XML_NS +":" + nsPrefix, nsURI); 719 } 720 else 721 { 722 ((Element )currentNode).setAttributeNS(ExtendedMetaData.XMLNS_URI, XMLResource.XML_NS, nsURI); 723 } 724 } 725 } 726 } 727 } 728 } 729 730 if (xsiSchemaLocation.length() > 0) 731 { 732 if (!toDOM) 733 { 734 doc.addAttribute(XSI_SCHEMA_LOCATION, xsiSchemaLocation.toString()); 735 } 736 else 737 { 738 ((Element )currentNode).setAttributeNS(XMLResource.XSI_URI, XSI_SCHEMA_LOCATION, xsiSchemaLocation.toString()); 739 } 740 } 741 742 if (xsiNoNamespaceSchemaLocation != null) 743 { 744 if (!toDOM) 745 { 746 doc.addAttribute(XSI_NO_NAMESPACE_SCHEMA_LOCATION, xsiNoNamespaceSchemaLocation); 747 } 748 else 749 { 750 ((Element )currentNode).setAttributeNS(XMLResource.XSI_URI, XSI_NO_NAMESPACE_SCHEMA_LOCATION, xsiNoNamespaceSchemaLocation); 751 } 752 } 753 } 754 755 public boolean isDuplicateURI(String nsURI) 756 { 757 return false; 758 } 759 760 public void write(OutputStreamWriter os) throws IOException 761 { 762 doc.write(os, flushThreshold); 763 os.flush(); 764 } 765 766 public void writeAscii(OutputStream os) throws IOException 767 { 768 doc.writeAscii(os, flushThreshold); 769 os.flush(); 770 } 771 772 public char[] toChar() 773 { 774 int size = doc.getLength(); 775 char[] output = new char[size]; 776 doc.getChars(output, 0); 777 return output; 778 } 779 780 protected void saveElement(EObject o, EStructuralFeature f) 781 { 782 EClass eClass = o.eClass(); 783 EClassifier eType = f.getEType(); 784 785 if (extendedMetaData != null && eClass != eType) 786 { 787 String name = extendedMetaData.getName(eClass); 790 if (name.endsWith("_._type")) 791 { 792 String elementName = name.substring(0, name.indexOf("_._")); 793 String prefix = helper.getPrefix(eClass.getEPackage()); 794 if (!"".equals(prefix)) 795 { 796 elementName = prefix + ":" + elementName; 797 } 798 if (!toDOM) 799 { 800 doc.startElement(elementName); 801 } 802 else 803 { 804 currentNode = currentNode.appendChild(document.createElementNS(helper.getNamespaceURI(prefix), elementName)); 805 handler.recordValues(currentNode, o.eContainer(), f, o); 806 } 807 saveElementID(o); 808 return; 809 } 810 } 811 812 if (map != null) 813 { 814 XMLResource.XMLInfo info = map.getInfo(eClass); 815 if (info != null && info.getXMLRepresentation() == XMLResource.XMLInfo.ELEMENT) 816 { 817 if (!toDOM) 818 { 819 String elementName = helper.getQName(eClass); 820 doc.startElement(elementName); 821 } 822 else 823 { 824 helper.populateNameInfo(nameInfo, eClass); 825 if (currentNode == null) 826 { 827 currentNode = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 828 document.appendChild(currentNode); 829 handler.recordValues(currentNode, o.eContainer(), f, o); 830 } 831 else 832 { 833 currentNode = currentNode.appendChild(document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName())); 834 handler.recordValues(currentNode, o.eContainer(), f, o); 835 } 836 } 837 saveElementID(o); 838 return; 839 } 840 } 841 842 if (o instanceof AnyType) 843 { 844 helper.pushContext(); 845 for (Iterator i = ((AnyType)o).getAnyAttribute().iterator(); i.hasNext(); ) 846 { 847 FeatureMap.Entry entry = (FeatureMap.Entry)i.next(); 848 if (ExtendedMetaData.XMLNS_URI.equals(extendedMetaData.getNamespace(entry.getEStructuralFeature()))) 849 { 850 String uri = (String )entry.getValue(); 851 helper.addPrefix(extendedMetaData.getName(entry.getEStructuralFeature()), uri == null ? "" : uri); 852 } 853 } 854 } 855 if (!toDOM) 856 { 857 String featureName = helper.getQName(f); 858 doc.startElement(featureName); 859 } 860 else 861 { 862 helper.populateNameInfo(nameInfo, f); 863 if (currentNode == null) 864 { 865 currentNode = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 867 document.appendChild(currentNode); 868 handler.recordValues(currentNode, o.eContainer(), f, o); 869 } 870 else 871 { 872 currentNode = currentNode.appendChild(document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName())); 873 handler.recordValues(currentNode, o.eContainer(), f, o); 874 } 875 } 876 877 if (saveTypeInfo ? xmlTypeInfo.shouldSaveType(eClass, eType, f) : eClass != eType && eClass != anyType) 878 { 879 if (eClass == anySimpleType) 880 { 881 saveTypeAttribute(((SimpleAnyType)o).getInstanceType()); 882 } 883 else 884 { 885 saveTypeAttribute(eClass); 886 } 887 } 888 889 saveElementID(o); 890 } 891 892 protected void saveTypeAttribute(EClass eClass) 893 { 894 declareXSI = true; 895 if (!toDOM) 896 { 897 doc.addAttribute(XSI_TYPE_NS, helper.getQName(eClass)); 898 } 899 else 900 { 901 helper.populateNameInfo(nameInfo, eClass); 902 ((Element )currentNode).setAttributeNS(ExtendedMetaData.XSI_URI, XSI_TYPE_NS, nameInfo.getQualifiedName()); 903 } 904 905 } 906 907 protected void saveTypeAttribute(EDataType eDataType) 908 { 909 declareXSI = true; 910 if (!toDOM) 911 { 912 doc.addAttribute(XSI_TYPE_NS, helper.getQName(eDataType)); 913 } 914 else 915 { 916 helper.populateNameInfo(nameInfo, eDataType); 917 ((Element )currentNode).setAttributeNS(XMLResource.XSI_URI, XSI_TYPE_NS, nameInfo.getQualifiedName()); 918 } 919 } 920 921 protected boolean saveFeatures(EObject o) 922 { 923 EClass eClass = o.eClass(); 924 int contentKind = extendedMetaData == null ? ExtendedMetaData.UNSPECIFIED_CONTENT : extendedMetaData.getContentKind(eClass); 925 if (!toDOM) 926 { 927 switch (contentKind) 928 { 929 case ExtendedMetaData.MIXED_CONTENT: 930 case ExtendedMetaData.SIMPLE_CONTENT: 931 { 932 doc.setMixed(true); 933 break; 934 } 935 } 936 } 937 938 EStructuralFeature[] features = featureTable.getFeatures(eClass); 939 int[] featureKinds = featureTable.getKinds(eClass, features); 940 int[] elementFeatures = null; 941 int elementCount = 0; 942 943 String content = null; 944 945 LOOP: 947 for (int i = 0; i < features.length; i++ ) 948 { 949 int kind = featureKinds[i]; 950 EStructuralFeature f = features[i]; 951 if (kind != TRANSIENT && (o.eIsSet(f) || keepDefaults && f.getDefaultValueLiteral() != null)) 952 { 953 switch (kind) 954 { 955 case DATATYPE_ELEMENT_SINGLE: 956 { 957 if (contentKind == ExtendedMetaData.SIMPLE_CONTENT) 958 { 959 content = getDataTypeElementSingleSimple(o, f); 960 continue LOOP; 961 } 962 break; 963 } 964 case DATATYPE_SINGLE: 965 { 966 saveDataTypeSingle(o, f); 967 continue LOOP; 968 } 969 case DATATYPE_SINGLE_NILLABLE: 970 { 971 if (!isNil(o, f)) 972 { 973 saveDataTypeSingle(o, f); 974 continue LOOP; 975 } 976 break; 977 } 978 case OBJECT_ATTRIBUTE_SINGLE: 979 { 980 saveEObjectSingle(o, f); 981 continue LOOP; 982 } 983 case OBJECT_ATTRIBUTE_MANY: 984 { 985 saveEObjectMany(o, f); 986 continue LOOP; 987 } 988 case OBJECT_ATTRIBUTE_IDREF_SINGLE: 989 { 990 saveIDRefSingle(o, f); 991 continue LOOP; 992 } 993 case OBJECT_ATTRIBUTE_IDREF_MANY: 994 { 995 saveIDRefMany(o, f); 996 continue LOOP; 997 } 998 case OBJECT_HREF_SINGLE_UNSETTABLE: 999 { 1000 if (isNil(o, f)) 1001 { 1002 break; 1003 } 1004 } 1006 case OBJECT_HREF_SINGLE: 1007 { 1008 if (useEncodedAttributeStyle) 1009 { 1010 saveEObjectSingle(o, f); 1011 continue LOOP; 1012 } 1013 else 1014 { 1015 switch (sameDocSingle(o, f)) 1016 { 1017 case SAME_DOC: 1018 { 1019 saveIDRefSingle(o, f); 1020 continue LOOP; 1021 } 1022 case CROSS_DOC: 1023 { 1024 break; 1025 } 1026 default: 1027 { 1028 continue LOOP; 1029 } 1030 } 1031 } 1032 break; 1033 } 1034 case OBJECT_HREF_MANY_UNSETTABLE: 1035 { 1036 if (isEmpty(o, f)) 1037 { 1038 saveManyEmpty(o, f); 1039 continue LOOP; 1040 } 1041 } 1043 case OBJECT_HREF_MANY: 1044 { 1045 if (useEncodedAttributeStyle) 1046 { 1047 saveEObjectMany(o, f); 1048 continue LOOP; 1049 } 1050 else 1051 { 1052 switch (sameDocMany(o, f)) 1053 { 1054 case SAME_DOC: 1055 { 1056 saveIDRefMany(o, f); 1057 continue LOOP; 1058 } 1059 case CROSS_DOC: 1060 { 1061 break; 1062 } 1063 default: 1064 { 1065 continue LOOP; 1066 } 1067 } 1068 } 1069 break; 1070 } 1071 case OBJECT_ELEMENT_SINGLE_UNSETTABLE: 1072 case OBJECT_ELEMENT_SINGLE: 1073 { 1074 if (contentKind == ExtendedMetaData.SIMPLE_CONTENT) 1075 { 1076 content = getElementReferenceSingleSimple(o, f); 1077 continue LOOP; 1078 } 1079 break; 1080 } 1081 case OBJECT_ELEMENT_MANY: 1082 { 1083 if (contentKind == ExtendedMetaData.SIMPLE_CONTENT) 1084 { 1085 content = getElementReferenceManySimple(o, f); 1086 continue LOOP; 1087 } 1088 break; 1089 } 1090 case OBJECT_ELEMENT_IDREF_SINGLE_UNSETTABLE: 1091 case OBJECT_ELEMENT_IDREF_SINGLE: 1092 { 1093 if (contentKind == ExtendedMetaData.SIMPLE_CONTENT) 1094 { 1095 content = getElementIDRefSingleSimple(o, f); 1096 continue LOOP; 1097 } 1098 break; 1099 } 1100 case OBJECT_ELEMENT_IDREF_MANY: 1101 { 1102 if (contentKind == ExtendedMetaData.SIMPLE_CONTENT) 1103 { 1104 content = getElementIDRefManySimple(o, f); 1105 continue LOOP; 1106 } 1107 break; 1108 } 1109 case DATATYPE_ATTRIBUTE_MANY: 1110 { 1111 break; 1112 } 1113 case OBJECT_CONTAIN_MANY_UNSETTABLE: 1114 case DATATYPE_MANY: 1115 { 1116 if (isEmpty(o, f)) 1117 { 1118 saveManyEmpty(o, f); 1119 continue LOOP; 1120 } 1121 break; 1122 } 1123 case OBJECT_CONTAIN_SINGLE_UNSETTABLE: 1124 case OBJECT_CONTAIN_SINGLE: 1125 case OBJECT_CONTAIN_MANY: 1126 case ELEMENT_FEATURE_MAP: 1127 { 1128 break; 1129 } 1130 case ATTRIBUTE_FEATURE_MAP: 1131 { 1132 saveAttributeFeatureMap(o, f); 1133 continue LOOP; 1134 } 1135 default: 1136 { 1137 continue LOOP; 1138 } 1139 } 1140 1141 if (elementFeatures == null) 1144 { 1145 elementFeatures = new int[features.length]; 1146 } 1147 elementFeatures[elementCount++] = i; 1148 } 1149 } 1150 1151 processAttributeExtensions(o); 1152 1153 if (elementFeatures == null) 1154 { 1155 if (content == null) 1156 { 1157 content = getContent(o, features); 1158 } 1159 1160 if (content == null) 1161 { 1162 endSaveFeatures(o, EMPTY_ELEMENT, null); 1163 return false; 1164 } 1165 else 1166 { 1167 endSaveFeatures(o, CONTENT_ELEMENT, content); 1168 return true; 1169 } 1170 } 1171 1172 for (int i = 0; i < elementCount; i++ ) 1174 { 1175 int kind = featureKinds[elementFeatures[i]]; 1176 EStructuralFeature f = features[elementFeatures[i]]; 1177 switch (kind) 1178 { 1179 case DATATYPE_SINGLE_NILLABLE: 1180 { 1181 saveNil(o, f); 1182 break; 1183 } 1184 case ELEMENT_FEATURE_MAP: 1185 { 1186 saveElementFeatureMap(o, f); 1187 break; 1188 } 1189 case DATATYPE_MANY: 1190 { 1191 saveDataTypeMany(o, f); 1192 break; 1193 } 1194 case DATATYPE_ATTRIBUTE_MANY: 1195 { 1196 saveDataTypeAttributeMany(o, f); 1197 break; 1198 } 1199 case DATATYPE_ELEMENT_SINGLE: 1200 { 1201 saveDataTypeElementSingle(o, f); 1202 break; 1203 } 1204 case OBJECT_CONTAIN_SINGLE_UNSETTABLE: 1205 { 1206 if (isNil(o, f)) 1207 { 1208 saveNil(o, f); 1209 break; 1210 } 1211 } 1213 case OBJECT_CONTAIN_SINGLE: 1214 { 1215 saveContainedSingle(o, f); 1216 break; 1217 } 1218 case OBJECT_CONTAIN_MANY_UNSETTABLE: 1219 case OBJECT_CONTAIN_MANY: 1220 { 1221 saveContainedMany(o, f); 1222 break; 1223 } 1224 case OBJECT_HREF_SINGLE_UNSETTABLE: 1225 { 1226 if (isNil(o, f)) 1227 { 1228 saveNil(o, f); 1229 break; 1230 } 1231 } 1233 case OBJECT_HREF_SINGLE: 1234 { 1235 saveHRefSingle(o, f); 1236 break; 1237 } 1238 case OBJECT_HREF_MANY_UNSETTABLE: 1239 case OBJECT_HREF_MANY: 1240 { 1241 saveHRefMany(o, f); 1242 break; 1243 } 1244 case OBJECT_ELEMENT_SINGLE_UNSETTABLE: 1245 { 1246 if (isNil(o, f)) 1247 { 1248 saveNil(o, f); 1249 break; 1250 } 1251 } 1253 case OBJECT_ELEMENT_SINGLE: 1254 { 1255 saveElementReferenceSingle(o, f); 1256 break; 1257 } 1258 case OBJECT_ELEMENT_MANY: 1259 { 1260 saveElementReferenceMany(o, f); 1261 break; 1262 } 1263 case OBJECT_ELEMENT_IDREF_SINGLE_UNSETTABLE: 1264 { 1265 if (isNil(o, f)) 1266 { 1267 saveNil(o, f); 1268 break; 1269 } 1270 } 1272 case OBJECT_ELEMENT_IDREF_SINGLE: 1273 { 1274 saveElementIDRefSingle(o, f); 1275 break; 1276 } 1277 case OBJECT_ELEMENT_IDREF_MANY: 1278 { 1279 saveElementIDRefMany(o, f); 1280 break; 1281 } 1282 } 1283 } 1284 endSaveFeatures(o, 0, null); 1285 return true; 1286 } 1287 1288 protected void endSaveFeatures(EObject o, int elementType, String content) 1289 { 1290 if (processElementExtensions(o)) 1291 { 1292 if (o instanceof AnyType) 1293 { 1294 helper.popContext(); 1295 } 1296 if (!toDOM) 1297 { 1298 doc.endElement(); 1299 } 1300 } 1301 else 1302 { 1303 switch (elementType) 1304 { 1305 case EMPTY_ELEMENT: 1306 { 1307 if (!toDOM) 1308 { 1309 doc.endEmptyElement(); 1310 } 1311 break; 1312 } 1313 case CONTENT_ELEMENT: 1314 { 1315 if (!toDOM) 1316 { 1317 doc.endContentElement(content); 1318 } 1319 break; 1320 } 1321 default: 1322 { 1323 if (o instanceof AnyType) 1324 { 1325 helper.popContext(); 1326 } 1327 if (!toDOM) 1328 { 1329 doc.endElement(); 1330 } 1331 break; 1332 } 1333 } 1334 } 1335 if (toDOM) 1336 { 1337 currentNode = currentNode.getParentNode(); 1338 } 1339 } 1340 1341 1344 protected boolean processElementExtensions(EObject object) 1345 { 1346 if (eObjectToExtensionMap != null) 1347 { 1348 AnyType anyType = (AnyType)eObjectToExtensionMap.get(object); 1349 return anyType != null && saveElementFeatureMap(anyType, XMLTypePackage.eINSTANCE.getAnyType_Mixed()); 1350 } 1351 else 1352 { 1353 return false; 1354 } 1355 } 1356 1357 1359 protected void processAttributeExtensions(EObject object) 1360 { 1361 if (eObjectToExtensionMap != null) 1362 { 1363 AnyType anyType = (AnyType)eObjectToExtensionMap.get(object); 1364 if (anyType != null) 1365 { 1366 saveAttributeFeatureMap(anyType, XMLTypePackage.eINSTANCE.getAnyType_AnyAttribute()); 1367 } 1368 } 1369 } 1370 1371 protected void saveDataTypeSingle(EObject o, EStructuralFeature f) 1372 { 1373 Object value = helper.getValue(o, f); 1374 String svalue = getDatatypeValue(value, f, true); 1375 if (svalue != null) 1376 { 1377 if (!toDOM) 1378 { 1379 doc.addAttribute(helper.getQName(f), svalue); 1380 } 1381 else 1382 { 1383 helper.populateNameInfo(nameInfo, f); 1384 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1385 attr.setNodeValue(svalue); 1386 ((Element )currentNode).setAttributeNodeNS(attr); 1387 handler.recordValues(attr, o, f, value); 1388 } 1389 } 1390 } 1391 1392 protected boolean isNil(EObject o, EStructuralFeature f) 1393 { 1394 return helper.getValue(o, f) == null; 1395 } 1396 1397 protected boolean isEmpty(EObject o, EStructuralFeature f) 1398 { 1399 return ((List )helper.getValue(o, f)).isEmpty(); 1400 } 1401 1402 protected void saveNil(EObject o, EStructuralFeature f) 1403 { 1404 if (!toDOM) 1405 { 1406 saveNil(f); 1407 } 1408 else 1409 { 1410 declareXSI = true; 1411 helper.populateNameInfo(nameInfo, f); 1412 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1413 elem.setAttributeNS(ExtendedMetaData.XSI_URI, XSI_NIL, "true"); 1414 currentNode.appendChild(elem); 1415 handler.recordValues(currentNode.getLastChild(), o, f, null); 1416 } 1417 } 1418 1419 protected void saveNil(EStructuralFeature f) 1420 { 1421 declareXSI = true; 1422 doc.saveNilElement(helper.getQName(f)); 1423 } 1424 1425 protected void saveManyEmpty(EObject o, EStructuralFeature f) 1426 { 1427 if (!toDOM) 1428 { 1429 saveManyEmpty(f); 1430 } 1431 else 1432 { 1433 helper.populateNameInfo(nameInfo, f); 1434 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1435 ((Element )currentNode).setAttributeNodeNS(attr); 1436 handler.recordValues(attr, o, f, null); 1437 } 1438 } 1439 1440 protected void saveManyEmpty(EStructuralFeature f) 1441 { 1442 doc.addAttribute(helper.getQName(f), ""); 1443 } 1444 1445 protected void saveDataTypeMany(EObject o, EStructuralFeature f) 1446 { 1447 List values = (List )helper.getValue(o, f); 1448 int size = values.size(); 1449 if (size > 0) 1450 { 1451 if (!toDOM) 1453 { 1454 EDataType d = (EDataType)f.getEType(); 1455 EPackage ePackage = d.getEPackage(); 1456 EFactory fac = ePackage.getEFactoryInstance(); 1457 String name = helper.getQName(f); 1458 for (int i = 0; i < size; ++i) 1459 { 1460 Object value = values.get(i); 1461 if (value == null) 1462 { 1463 doc.startElement(name); 1464 doc.addAttribute(XSI_NIL, "true"); 1465 doc.endEmptyElement(); 1466 declareXSI = true; 1467 } 1468 else 1469 { 1470 String svalue = helper.convertToString(fac, d, value); 1471 if (escape != null) 1472 { 1473 svalue = escape.convert(svalue); 1474 } 1475 doc.saveDataValueElement(name, svalue); 1476 } 1477 } 1478 } 1479 else 1480 { 1481 EDataType d = (EDataType)f.getEType(); 1482 EPackage ePackage = d.getEPackage(); 1483 EFactory fac = ePackage.getEFactoryInstance(); 1484 helper.populateNameInfo(nameInfo, f); 1485 for (int i = 0; i < size; ++i) 1486 { 1487 Object value = values.get(i); 1488 if (value == null) 1489 { 1490 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1491 elem.setAttributeNS(XMLResource.XSI_URI, XSI_NIL, "true"); 1492 currentNode.appendChild(elem); 1493 handler.recordValues(elem, o, f, null); 1494 declareXSI = true; 1495 } 1496 else 1497 { 1498 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1499 Node text = document.createTextNode(helper.convertToString(fac, d, value)); 1500 elem.appendChild(text); 1501 currentNode.appendChild(elem); 1502 handler.recordValues(elem, o, f, value); 1503 handler.recordValues(text, o, f, value); 1504 } 1505 } 1506 } 1507 } 1508 } 1509 1510 protected void saveDataTypeAttributeMany(EObject o, EStructuralFeature f) 1511 { 1512 List values = (List )helper.getValue(o, f); 1513 int size = values.size(); 1514 if (size > 0) 1515 { 1516 EDataType d = (EDataType)f.getEType(); 1517 EPackage ePackage = d.getEPackage(); 1518 EFactory fac = ePackage.getEFactoryInstance(); 1519 StringBuffer stringValues = new StringBuffer (); 1520 for (int i = 0; i < size; ++i) 1521 { 1522 Object value = values.get(i); 1523 if (value != null) 1524 { 1525 String svalue = helper.convertToString(fac, d, value); 1526 if (escape != null) 1527 { 1528 svalue = escape.convert(svalue); 1529 } 1530 if (i > 0) 1531 { 1532 stringValues.append(' '); 1533 } 1534 stringValues.append(svalue); 1535 } 1536 } 1537 if (!toDOM) 1538 { 1539 String name = helper.getQName(f); 1540 doc.startAttribute(name); 1541 doc.addAttributeContent(stringValues.toString()); 1542 doc.endAttribute(); 1543 } 1544 else 1545 { 1546 helper.populateNameInfo(nameInfo, f); 1547 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1548 String value = stringValues.toString(); 1549 attr.setNodeValue(value); 1550 ((Element )currentNode).setAttributeNodeNS(attr); 1551 handler.recordValues(attr, o, f, value); 1552 } 1553 } 1554 } 1555 1556 protected void saveEObjectSingle(EObject o, EStructuralFeature f) 1557 { 1558 EObject value = (EObject)helper.getValue(o, f); 1559 if (value != null) 1560 { 1561 String id = helper.getHREF(value); 1562 if (id != null) 1563 { 1564 if (escapeURI != null) 1565 { 1566 id = escapeURI.convert(id); 1567 } 1568 buffer.setLength(0); 1569 if (!id.startsWith("#")) 1570 { 1571 EClass eClass = value.eClass(); 1572 EClass expectedType = (EClass)f.getEType(); 1573 if (saveTypeInfo ? xmlTypeInfo.shouldSaveType(eClass, expectedType, f) : eClass != expectedType && expectedType.isAbstract()) 1574 { 1575 buffer.append(helper.getQName(eClass)); 1576 buffer.append(" "); 1577 } 1578 } 1579 buffer.append(id); 1580 if (!toDOM) 1581 { 1582 String name = helper.getQName(f); 1583 doc.startAttribute(name); 1584 doc.addAttributeContent(buffer.toString()); 1585 doc.endAttribute(); 1586 } 1587 else 1588 { 1589 helper.populateNameInfo(nameInfo, f); 1590 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1591 attr.setNodeValue(buffer.toString()); 1592 ((Element )currentNode).setAttributeNodeNS(attr); 1593 handler.recordValues(attr, o, f, value); 1594 } 1595 } 1596 } 1597 } 1598 1599 protected void saveEObjectMany(EObject o, EStructuralFeature f) 1600 { 1601 InternalEList values = (InternalEList)helper.getValue(o, f); 1602 1603 if (!values.isEmpty()) 1604 { 1605 buffer.setLength(0); 1606 for (Iterator i = values.basicIterator();;) 1607 { 1608 EObject value = (EObject)i.next(); 1609 String id = helper.getHREF(value); 1610 if (id != null) 1611 { 1612 if (escapeURI != null) 1613 { 1614 id = escapeURI.convert(id); 1615 } 1616 if (!id.startsWith("#")) 1617 { 1618 EClass eClass = value.eClass(); 1619 EClass expectedType = (EClass)f.getEType(); 1620 if (saveTypeInfo ? xmlTypeInfo.shouldSaveType(eClass, expectedType, f) : eClass != expectedType && expectedType.isAbstract()) 1621 { 1622 buffer.append(helper.getQName(eClass)); 1623 buffer.append(" "); 1624 } 1625 } 1626 buffer.append(id); 1627 } 1628 if (i.hasNext()) 1629 { 1630 buffer.append(" "); 1631 } 1632 else 1633 { 1634 break; 1635 } 1636 } 1637 1638 if (!toDOM) 1639 { 1640 String name = helper.getQName(f); 1641 doc.startAttribute(name); 1642 doc.addAttributeContent(buffer.toString()); 1643 doc.endAttribute(); 1644 } 1645 else 1646 { 1647 helper.populateNameInfo(nameInfo, f); 1648 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1649 attr.setNodeValue(buffer.toString()); 1650 ((Element )currentNode).setAttributeNodeNS(attr); 1651 handler.recordValues(attr, o, f, values); 1652 } 1653 } 1654 } 1655 1656 protected void saveIDRefSingle(EObject o, EStructuralFeature f) 1657 { 1658 EObject value = (EObject)helper.getValue(o, f); 1659 if (value != null) 1660 { 1661 String id = helper.getIDREF(value); 1662 if (!toDOM) 1663 { 1664 String name = helper.getQName(f); 1665 doc.addAttribute(name, id); 1666 } 1667 else 1668 { 1669 helper.populateNameInfo(nameInfo, f); 1670 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1671 attr.setNodeValue(id); 1672 ((Element )currentNode).setAttributeNodeNS(attr); 1673 handler.recordValues(attr, o, f, value); 1674 } 1675 } 1676 } 1677 1678 protected void saveIDRefMany(EObject o, EStructuralFeature f) 1679 { 1680 InternalEList values = (InternalEList)helper.getValue(o, f); 1681 if (!values.isEmpty()) 1682 { 1683 buffer.setLength(0); 1684 StringBuffer ids = buffer; 1685 for (Iterator i = values.basicIterator();;) 1686 { 1687 EObject value = (EObject)i.next(); 1688 String id = helper.getIDREF(value); 1689 ids.append(id); 1690 if (i.hasNext()) 1691 { 1692 ids.append(" "); 1693 } 1694 else 1695 { 1696 break; 1697 } 1698 } 1699 if (!toDOM) 1700 { 1701 String name = helper.getQName(f); 1702 doc.addAttribute(name, ids.toString()); 1703 } 1704 else 1705 { 1706 helper.populateNameInfo(nameInfo, f); 1707 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1708 attr.setNodeValue(ids.toString()); 1709 ((Element )currentNode).setAttributeNodeNS(attr); 1710 handler.recordValues(attr, o, f, values); 1711 } 1712 } 1713 } 1714 1715 protected void saveElementReference(EObject remote, EStructuralFeature f) 1716 { 1717 String href = helper.getHREF(remote); 1718 if (href != null) 1719 { 1720 if (escapeURI != null) 1721 { 1722 href = escapeURI.convert(href); 1723 } 1724 if (!toDOM) 1725 { 1726 doc.startElement(helper.getQName(f)); 1727 } 1728 else 1729 { 1730 helper.populateNameInfo(nameInfo, f); 1731 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1732 Node text = document.createTextNode(href); 1733 elem.appendChild(text); 1734 currentNode = currentNode.appendChild(elem); 1735 handler.recordValues(elem, remote.eContainer(), f, remote); 1736 handler.recordValues(text, remote.eContainer(), f, remote); 1737 } 1738 EClass eClass = remote.eClass(); 1739 EClass expectedType = (EClass)f.getEType(); 1740 if (saveTypeInfo ? xmlTypeInfo.shouldSaveType(eClass, expectedType, f) : eClass != expectedType && expectedType.isAbstract()) 1741 { 1742 saveTypeAttribute(eClass); 1743 } 1744 if (!toDOM) 1745 { 1746 doc.endContentElement(href); 1747 } 1748 else 1749 { 1750 currentNode = currentNode.getParentNode(); 1751 } 1752 } 1753 } 1754 1755 protected void saveElementReferenceSingle(EObject o, EStructuralFeature f) 1756 { 1757 EObject value = (EObject)helper.getValue(o, f); 1758 if (value != null) 1759 { 1760 saveElementReference(value, f); 1761 } 1762 } 1763 1764 protected void saveElementReferenceMany(EObject o, EStructuralFeature f) 1765 { 1766 InternalEList values = (InternalEList)helper.getValue(o, f); 1767 int size = values.size(); 1768 for (int i = 0; i < size; i++) 1769 { 1770 saveElementReference((EObject)values.basicGet(i), f); 1771 } 1772 } 1773 1774 protected String getElementReferenceSingleSimple(EObject o, EStructuralFeature f) 1775 { 1776 EObject value = (EObject)helper.getValue(o, f); 1777 String svalue = helper.getHREF(value); 1778 if (escapeURI != null && svalue != null) 1779 { 1780 svalue = escapeURI.convert(svalue); 1781 } 1782 if (toDOM) 1783 { 1784 Node text = document.createTextNode(svalue); 1785 currentNode.appendChild(text); 1786 handler.recordValues(text, o, f, value); 1787 } 1788 return svalue; 1789 } 1790 1791 protected String getElementReferenceManySimple(EObject o, EStructuralFeature f) 1792 { 1793 InternalEList values = (InternalEList)helper.getValue(o, f); 1794 buffer.setLength(0); 1795 StringBuffer result = buffer; 1796 int size = values.size(); 1797 String href = null; 1798 for (int i = 0; i < size; i++) 1799 { 1800 href = helper.getHREF(((EObject)values.basicGet(i))); 1801 if (escapeURI != null && href != null) 1802 { 1803 href = escapeURI.convert(href); 1804 } 1805 result.append(href); 1806 result.append(' '); 1807 } 1808 String svalue = result.substring(0, result.length() - 1); 1809 if (toDOM) 1810 { 1811 Node text = document.createTextNode(svalue); 1812 currentNode.appendChild(text); 1813 handler.recordValues(text, o, f, values); 1814 } 1815 return svalue; 1816 } 1817 1818 protected void saveElementIDRef(EObject o, EObject target, EStructuralFeature f) 1819 { 1820 if (!toDOM) 1821 { 1822 saveElementIDRef(target, f); 1823 } 1824 else 1825 { 1826 String id = helper.getIDREF(target); 1827 helper.populateNameInfo(nameInfo, f); 1828 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1829 Node text = document.createTextNode(id); 1830 elem.appendChild(text); 1831 currentNode.appendChild(elem); 1832 handler.recordValues(elem, o, f, target); 1833 handler.recordValues(text, o, f, target); 1834 } 1835 } 1836 1837 protected void saveElementIDRef(EObject target, EStructuralFeature f) 1838 { 1839 String name = helper.getQName(f); 1840 String id = helper.getIDREF(target); 1841 doc.saveDataValueElement(name, id); 1842 } 1843 1844 protected void saveElementIDRefSingle(EObject o, EStructuralFeature f) 1845 { 1846 EObject value = (EObject)helper.getValue(o, f); 1847 if (value != null) 1848 { 1849 saveElementIDRef(o, value, f); 1850 } 1851 } 1852 1853 protected void saveElementIDRefMany(EObject o, EStructuralFeature f) 1854 { 1855 InternalEList values = (InternalEList)helper.getValue(o, f); 1856 int size = values.size(); 1857 for (int i = 0; i < size; i++) 1858 { 1859 saveElementIDRef(o, (EObject)values.basicGet(i), f); 1860 } 1861 } 1862 1863 protected String getElementIDRefSingleSimple(EObject o, EStructuralFeature f) 1864 { 1865 EObject value = (EObject)helper.getValue(o, f); 1866 String svalue = helper.getIDREF(value); 1867 if (toDOM) 1868 { 1869 Node text = document.createTextNode(svalue); 1870 currentNode.appendChild(text); 1871 handler.recordValues(text, o, f, value); 1872 } 1873 return svalue; 1874 } 1875 1876 protected String getElementIDRefManySimple(EObject o, EStructuralFeature f) 1877 { 1878 InternalEList values = (InternalEList)helper.getValue(o, f); 1879 buffer.setLength(0); 1880 StringBuffer result = buffer; 1881 for (int i = 0, size = values.size(); i < size; i++) 1882 { 1883 result.append(helper.getIDREF((EObject)values.basicGet(i))); 1884 result.append(' '); 1885 } 1886 String svalue = result.substring(0, result.length() - 1); 1887 if (toDOM) 1888 { 1889 Node text = document.createTextNode(svalue); 1890 currentNode.appendChild(text); 1891 handler.recordValues(text, o, f, values); 1892 } 1893 return svalue; 1894 } 1895 1896 1923 1924 protected void saveHref(EObject remote, EStructuralFeature f) 1925 { 1926 String href = helper.getHREF(remote); 1927 if (href != null) 1928 { 1929 if (escapeURI != null) 1930 { 1931 href = escapeURI.convert(href); 1932 } 1933 if (!toDOM) 1934 { 1935 String name = helper.getQName(f); 1936 doc.startElement(name); 1937 } 1938 else 1939 { 1940 helper.populateNameInfo(nameInfo, f); 1941 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 1942 currentNode = currentNode.appendChild(elem); 1943 handler.recordValues(elem, remote.eContainer(), f, remote); 1944 } 1945 EClass eClass = remote.eClass(); 1946 EClass expectedType = (EClass) f.getEType(); 1947 if (saveTypeInfo ? xmlTypeInfo.shouldSaveType(eClass, expectedType, f) : eClass != expectedType && expectedType.isAbstract()) 1948 { 1949 saveTypeAttribute(eClass); 1950 } 1951 if (!toDOM) 1952 { 1953 doc.addAttribute(XMLResource.HREF, href); 1954 doc.endEmptyElement(); 1955 } 1956 else 1957 { 1958 ((Element )currentNode).setAttributeNS(null, XMLResource.HREF, href); 1959 currentNode = currentNode.getParentNode(); 1960 } 1961 } 1962 } 1963 1964 protected void saveHRefSingle(EObject o, EStructuralFeature f) 1965 { 1966 EObject value = (EObject)helper.getValue(o, f); 1967 if (value != null) 1968 { 1969 saveHref(value, f); 1970 } 1971 } 1972 1973 protected void saveHRefMany(EObject o, EStructuralFeature f) 1974 { 1975 InternalEList values = (InternalEList)helper.getValue(o, f); 1976 int size = values.size(); 1977 for (int i = 0; i < size; i++) 1978 { 1979 saveHref((EObject)values.basicGet(i), f); 1980 } 1981 } 1982 1983 protected void saveContainedSingle(EObject o, EStructuralFeature f) 1984 { 1985 EObject value = (EObject)helper.getValue(o, f); 1986 if (value != null) 1987 { 1988 saveElement(value, f); 1989 } 1990 } 1991 1992 protected void saveContainedMany(EObject o, EStructuralFeature f) 1993 { 1994 List values = (List )helper.getValue(o, f); 1995 int size = values.size(); 1996 for (int i = 0; i < size; i++) 1997 { 1998 EObject value = (EObject)values.get(i); 1999 if (value != null) 2000 { 2001 saveElement(value, f); 2002 } 2003 } 2004 } 2005 2006 protected void saveFeatureMapElementReference(EObject o, EReference f) 2007 { 2008 saveElementReference(o, f); 2009 } 2010 2011 protected boolean saveElementFeatureMap(EObject o, EStructuralFeature f) 2012 { 2013 List values = (List )helper.getValue(o, f); 2014 int size = values.size(); 2015 for (int i = 0; i < size; i++) 2016 { 2017 FeatureMap.Entry entry = (FeatureMap.Entry)values.get(i); 2018 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 2019 Object value = entry.getValue(); 2020 if (entryFeature instanceof EReference) 2021 { 2022 if (value == null) 2023 { 2024 saveNil(o, entryFeature); 2025 } 2026 else 2027 { 2028 EReference referenceEntryFeature = (EReference)entryFeature; 2029 if (referenceEntryFeature.isContainment()) 2030 { 2031 saveElement((EObject)value, entryFeature); 2032 } 2033 else if (referenceEntryFeature.isResolveProxies()) 2034 { 2035 saveFeatureMapElementReference((EObject)value, referenceEntryFeature); 2036 } 2037 else 2038 { 2039 saveElementIDRef(o, (EObject)value, entryFeature); 2040 } 2041 } 2042 } 2043 else 2044 { 2045 if (entryFeature == XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Text()) 2046 { 2047 String svalue = value.toString(); 2048 if (escape != null) 2049 { 2050 svalue = escape.convertText(svalue); 2051 } 2052 if (!toDOM) 2053 { 2054 doc.addText(svalue); 2055 } 2056 else 2057 { 2058 Node text = document.createTextNode(svalue); 2059 currentNode.appendChild(text); 2060 handler.recordValues(text, o, f, entry); 2061 } 2062 } 2063 else if (entryFeature == XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_CDATA()) 2064 { 2065 String stringValue = value.toString(); 2066 if (escape != null) 2067 { 2068 stringValue = escape.convertLines(stringValue); 2069 } 2070 if (!toDOM) 2071 { 2072 doc.addCDATA(stringValue); 2073 } 2074 else 2075 { 2076 Node cdata = document.createCDATASection(stringValue); 2077 currentNode.appendChild(cdata); 2078 handler.recordValues(cdata, o, f, entry); 2079 } 2080 } 2081 else if (entryFeature == XMLTypePackage.eINSTANCE.getXMLTypeDocumentRoot_Comment()) 2082 { 2083 String stringValue = value.toString(); 2084 if (escape != null) 2085 { 2086 stringValue = escape.convertLines(stringValue); 2087 } 2088 if (!toDOM) 2089 { 2090 doc.addComment(stringValue); 2091 } 2092 else 2093 { 2094 currentNode.appendChild(document.createComment(stringValue)); 2096 } 2097 } 2098 else 2099 { 2100 saveElement(o, value, entryFeature); 2101 } 2102 } 2103 } 2104 return size > 0; 2105 } 2106 2107 protected void saveAttributeFeatureMap(EObject o, EStructuralFeature f) 2108 { 2109 List values = (List )helper.getValue(o, f); 2110 int size = values.size(); 2111 Set repeats = null; 2112 for (int i = 0; i < size; i++) 2113 { 2114 FeatureMap.Entry entry = (FeatureMap.Entry)values.get(i); 2115 EStructuralFeature entryFeature = entry.getEStructuralFeature(); 2116 if (entryFeature instanceof EReference) 2117 { 2118 EReference referenceEntryFeature = (EReference)entryFeature; 2119 if (referenceEntryFeature.isMany()) 2120 { 2121 if (repeats == null) 2122 { 2123 repeats = new HashSet (); 2124 } 2125 else if (repeats.contains(referenceEntryFeature)) 2126 { 2127 continue; 2128 } 2129 2130 repeats.add(referenceEntryFeature); 2131 2132 if (referenceEntryFeature.isResolveProxies()) 2133 { 2134 saveEObjectMany(o, entryFeature); 2135 } 2136 else 2137 { 2138 saveIDRefMany(o, entryFeature); 2139 } 2140 } 2141 else 2142 { 2143 if (referenceEntryFeature.isResolveProxies()) 2144 { 2145 saveEObjectSingle(o, entryFeature); 2146 } 2147 else 2148 { 2149 saveIDRefSingle(o, entryFeature); 2150 } 2151 } 2152 } 2153 else 2154 { 2155 Object value = entry.getValue(); 2156 String svalue = getDatatypeValue(value, entryFeature, true); 2157 if (!toDOM) 2158 { 2159 doc.addAttribute(helper.getQName(entryFeature), svalue); 2160 } 2161 else 2162 { 2163 helper.populateNameInfo(nameInfo, entryFeature); 2164 Attr attr = document.createAttributeNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 2165 attr.setNodeValue(svalue); 2166 ((Element )currentNode).setAttributeNodeNS(attr); 2167 handler.recordValues(attr, o, f, value); 2168 } 2169 } 2170 } 2171 } 2172 2173 protected int sameDocSingle(EObject o, EStructuralFeature f) 2174 { 2175 InternalEObject value = (InternalEObject)helper.getValue(o, f); 2176 if (value == null) 2177 { 2178 return SKIP; 2179 } 2180 else if (value.eIsProxy()) 2181 { 2182 return CROSS_DOC; 2183 } 2184 else 2185 { 2186 Resource res = value.eResource(); 2187 return res == helper.getResource() ? SAME_DOC : CROSS_DOC; 2188 } 2189 } 2190 2191 protected int sameDocMany(EObject o, EStructuralFeature f) 2192 { 2193 InternalEList values = (InternalEList)helper.getValue(o, f); 2194 if (values.isEmpty()) 2195 { 2196 return SKIP; 2197 } 2198 2199 for (Iterator i = values.basicIterator(); i.hasNext(); ) 2200 { 2201 InternalEObject value = (InternalEObject)i.next(); 2202 if (value.eIsProxy() || value.eResource() != helper.getResource()) { 2203 return CROSS_DOC; 2204 } 2205 } 2206 2207 return SAME_DOC; 2208 } 2209 2210 protected String getContent(EObject o, EStructuralFeature[] features) 2211 { 2212 if (map == null) 2213 { 2214 return null; 2215 } 2216 2217 for (int i = 0; i < features.length; i++) 2218 { 2219 EStructuralFeature feature = features[i]; 2220 XMLResource.XMLInfo info = map.getInfo(feature); 2221 if (info != null && info.getXMLRepresentation() == XMLResource.XMLInfo.CONTENT) 2222 { 2223 Object value = helper.getValue(o, feature); 2224 String svalue = getDatatypeValue(value, feature, false); 2225 if (toDOM) 2226 { 2227 Node text = document.createTextNode(svalue); 2228 currentNode.appendChild(text); 2229 handler.recordValues(text, o, feature, value); 2230 } 2231 return svalue; 2232 } 2233 } 2234 return null; 2235 } 2236 2237 protected void saveDataTypeElementSingle(EObject o, EStructuralFeature f) 2238 { 2239 saveElement(o, helper.getValue(o, f), f); 2240 } 2241 2242 protected String getDataTypeElementSingleSimple(EObject o, EStructuralFeature f) 2243 { 2244 Object value = helper.getValue(o, f); 2245 String svalue = getDatatypeValue(value, f, false); 2246 if (toDOM) 2247 { 2248 Node text = document.createTextNode(svalue); 2249 currentNode.appendChild(text); 2250 handler.recordValues(text, o, f, value); 2251 } 2252 return svalue; 2253 } 2254 2255 protected void saveElementID(EObject o) 2256 { 2257 String id = helper.getID(o); 2258 if (id != null) 2259 { 2260 if (!toDOM) 2261 { 2262 doc.addAttribute(idAttributeName, id); 2263 } 2264 else 2265 { 2266 Attr attr = document.createAttributeNS(idAttributeNS, idAttributeName); 2267 attr.setNodeValue(id); 2268 ((Element )currentNode).setAttributeNodeNS(attr); 2269 handler.recordValues(attr, o, null, o); 2270 } 2271 } 2272 saveFeatures(o); 2273 } 2274 2275 protected static class Lookup 2276 { 2277 protected static final int SHIFT = 10; 2278 protected static final int SIZE = 1 << SHIFT; protected static final int MASK = SIZE - 1; 2281 protected EClass[] classes; 2282 protected EStructuralFeature[][] features; 2283 protected int[][] featureKinds; 2284 protected XMLResource.XMLMap map; 2285 protected ExtendedMetaData extendedMetaData; 2286 protected ArrayList docRoots = new ArrayList (); 2287 2288 public Lookup(XMLResource.XMLMap map) 2289 { 2290 this(map, null); 2291 } 2292 2293 public Lookup(XMLResource.XMLMap map, ExtendedMetaData extendedMetaData) 2294 { 2295 this.map = map; 2296 this.extendedMetaData = extendedMetaData; 2297 classes = new EClass[SIZE]; 2298 features = new EStructuralFeature[SIZE][]; 2299 featureKinds = new int[SIZE][]; 2300 } 2301 2302 public EClass getDocumentRoot(EPackage epackage) 2303 { 2304 for (int i = 0; i < docRoots.size(); i += 2) 2305 { 2306 if (docRoots.get(i) == epackage) 2307 { 2308 return (EClass)docRoots.get(++i); 2309 } 2310 } 2311 docRoots.add(epackage); 2312 EClass docRoot = extendedMetaData.getDocumentRoot(epackage); 2313 docRoots.add(docRoot); 2314 return docRoot; 2315 } 2316 2317 public EStructuralFeature[] getFeatures(EClass cls) 2318 { 2319 int index = getIndex(cls); 2320 EClass c = classes[index]; 2321 2322 if (c == cls) 2323 { 2324 return features[index]; 2325 } 2326 2327 EStructuralFeature[] featureList = listFeatures(cls); 2328 if (c == null) 2329 { 2330 classes[index] = cls; 2331 features[index] = featureList; 2332 featureKinds[index] = listKinds(featureList); 2333 } 2334 return featureList; 2335 } 2336 2337 public int[] getKinds(EClass cls, EStructuralFeature[] featureList) 2338 { 2339 int index = getIndex(cls); 2340 EClass c = classes[index]; 2341 2342 if (c == cls) 2343 { 2344 return featureKinds[index]; 2345 } 2346 2347 int[] kindsList = listKinds(featureList); 2348 if (c == null) 2349 { 2350 classes[index] = cls; 2351 features[index] = featureList; 2352 featureKinds[index] = kindsList; 2353 } 2354 return kindsList; 2355 } 2356 2357 protected int getIndex(EClass cls) 2358 { 2359 String name = cls.getInstanceClassName(); 2360 int index = 0; 2361 if (name != null) 2362 { 2363 index = name.hashCode() & MASK; 2364 } 2365 else 2366 { 2367 index = cls.hashCode() >> SHIFT & MASK; 2368 } 2369 return index; 2370 } 2371 2372 protected EStructuralFeature[] listFeatures(EClass cls) 2373 { 2374 if (extendedMetaData != null) 2375 { 2376 List f = new ArrayList (); 2377 f.addAll(cls.getEAllStructuralFeatures()); 2378 List orderedElements = extendedMetaData.getAllElements(cls); 2379 f.removeAll(orderedElements); 2380 f.addAll(orderedElements); 2381 return (EStructuralFeature[]) f.toArray(new EStructuralFeature[f.size()]); 2382 } 2383 else 2384 { 2385 List f = map == null ? cls.getEAllStructuralFeatures() : map.getFeatures(cls); 2386 return (EStructuralFeature[]) f.toArray(new EStructuralFeature[f.size()]); 2387 } 2388 } 2389 2390 protected int[] listKinds(EStructuralFeature[] featureList) 2391 { 2392 int[] kinds = new int[featureList.length]; 2393 for (int i = featureList.length-1; i >= 0; i--) 2394 { 2395 kinds[i] = featureKind(featureList[i]); 2396 } 2397 2398 return kinds; 2399 } 2400 2401 protected int featureKind(EStructuralFeature f) 2402 { 2403 if (f.isTransient()) 2404 { 2405 return TRANSIENT; 2406 } 2407 2408 boolean isMany = f.isMany(); 2409 boolean isUnsettable = f.isUnsettable(); 2410 2411 if (f instanceof EReference) 2412 { 2413 EReference r = (EReference)f; 2414 if (r.isContainment()) 2415 { 2416 return 2417 isMany ? 2418 isUnsettable ? OBJECT_CONTAIN_MANY_UNSETTABLE : OBJECT_CONTAIN_MANY : 2419 isUnsettable ? OBJECT_CONTAIN_SINGLE_UNSETTABLE : OBJECT_CONTAIN_SINGLE; 2420 } 2421 EReference opposite = r.getEOpposite(); 2422 if (opposite != null && opposite.isContainment()) 2423 { 2424 return TRANSIENT; 2425 } 2426 2427 if (map != null) 2428 { 2429 XMLResource.XMLInfo info = map.getInfo(f); 2430 if (info != null && info.getXMLRepresentation() == XMLResource.XMLInfo.ELEMENT) 2431 { 2432 return 2433 isMany ? 2434 OBJECT_ELEMENT_MANY : 2435 r.isUnsettable() ? 2436 OBJECT_ELEMENT_SINGLE_UNSETTABLE : 2437 OBJECT_ELEMENT_SINGLE; 2438 } 2439 } 2440 2441 if (extendedMetaData != null) 2442 { 2443 switch (extendedMetaData.getFeatureKind(f)) 2444 { 2445 case ExtendedMetaData.ATTRIBUTE_FEATURE: 2446 { 2447 return 2448 r.isResolveProxies() ? 2449 isMany ? 2450 OBJECT_ATTRIBUTE_MANY : 2451 OBJECT_ATTRIBUTE_SINGLE : 2452 isMany ? 2453 OBJECT_ATTRIBUTE_IDREF_MANY : 2454 OBJECT_ATTRIBUTE_IDREF_SINGLE; 2455 } 2456 case ExtendedMetaData.SIMPLE_FEATURE: 2457 case ExtendedMetaData.ELEMENT_FEATURE: 2458 { 2459 return 2460 r.isResolveProxies() ? 2461 isMany ? 2462 OBJECT_ELEMENT_MANY : 2463 r.isUnsettable() ? 2464 OBJECT_ELEMENT_SINGLE_UNSETTABLE : 2465 OBJECT_ELEMENT_SINGLE : 2466 isMany ? 2467 OBJECT_ELEMENT_IDREF_MANY : 2468 r.isUnsettable() ? 2469 OBJECT_ELEMENT_IDREF_SINGLE_UNSETTABLE : 2470 OBJECT_ELEMENT_IDREF_SINGLE; 2471 } 2472 } 2473 } 2474 2475 return 2476 isMany ? 2477 isUnsettable ? OBJECT_HREF_MANY_UNSETTABLE : OBJECT_HREF_MANY : 2478 isUnsettable ? OBJECT_HREF_SINGLE_UNSETTABLE : OBJECT_HREF_SINGLE; 2479 } 2480 else 2481 { 2482 EDataType d = (EDataType) f.getEType(); 2484 if (!d.isSerializable()) 2485 { 2486 return TRANSIENT; 2487 } 2488 2489 if (d.getInstanceClass() == FeatureMap.Entry.class) 2490 { 2491 return 2492 extendedMetaData != null && extendedMetaData.getFeatureKind(f) == ExtendedMetaData.ATTRIBUTE_WILDCARD_FEATURE ? 2493 ATTRIBUTE_FEATURE_MAP : 2494 ELEMENT_FEATURE_MAP; 2495 } 2496 2497 if (extendedMetaData != null) 2498 { 2499 switch (extendedMetaData.getFeatureKind(f)) 2500 { 2501 case ExtendedMetaData.SIMPLE_FEATURE: 2502 { 2503 return DATATYPE_ELEMENT_SINGLE; 2504 } 2505 case ExtendedMetaData.ELEMENT_FEATURE: 2506 { 2507 return f.isMany() ? DATATYPE_MANY : DATATYPE_ELEMENT_SINGLE; 2508 } 2509 case ExtendedMetaData.ATTRIBUTE_FEATURE: 2510 { 2511 return f.isMany() ? DATATYPE_ATTRIBUTE_MANY: DATATYPE_SINGLE; 2512 } 2513 } 2514 } 2515 2516 if (isMany) 2517 { 2518 return DATATYPE_MANY; 2519 } 2520 2521 if (isUnsettable && map == null) 2522 { 2523 return DATATYPE_SINGLE_NILLABLE; 2524 } 2525 2526 if (map == null) 2527 { 2528 return DATATYPE_SINGLE; 2529 } 2530 else 2531 { 2532 XMLResource.XMLInfo info = map.getInfo(f); 2533 2534 if (info != null && info.getXMLRepresentation() == XMLResource.XMLInfo.ELEMENT) 2535 { 2536 return DATATYPE_ELEMENT_SINGLE; 2537 } 2538 else if (info != null && info.getXMLRepresentation() == XMLResource.XMLInfo.CONTENT) 2539 { 2540 return DATATYPE_CONTENT_SINGLE; 2541 } 2542 else 2543 { 2544 if (isUnsettable) 2545 return DATATYPE_SINGLE_NILLABLE; 2546 else 2547 return DATATYPE_SINGLE; 2548 } 2549 } 2550 } 2551 } 2552 } 2553 2554 protected String getDatatypeValue(Object value, EStructuralFeature f, boolean isAttribute) 2555 { 2556 if (value == null) 2557 { 2558 return null; 2559 } 2560 EDataType d = (EDataType)f.getEType(); 2561 EPackage ePackage = d.getEPackage(); 2562 EFactory fac = ePackage.getEFactoryInstance(); 2563 String svalue = helper.convertToString(fac, d, value); 2564 if (escape != null) 2565 { 2566 if (isAttribute) 2567 { 2568 svalue = escape.convert(svalue); 2569 } 2570 else 2571 { 2572 svalue = escape.convertText(svalue); 2573 } 2574 } 2575 return svalue; 2576 } 2577 2578 private void saveElement(EObject o, Object value, EStructuralFeature f) 2579 { 2580 if (value == null) 2581 { 2582 saveNil(o, f); 2583 } 2584 else 2585 { 2586 String svalue = getDatatypeValue(value, f, false); 2587 if (!toDOM) 2588 { 2589 doc.saveDataValueElement(helper.getQName(f), svalue); 2590 } 2591 else 2592 { 2593 helper.populateNameInfo(nameInfo, f); 2594 Element elem = document.createElementNS(nameInfo.getNamespaceURI(), nameInfo.getQualifiedName()); 2595 Node text = document.createTextNode(svalue); 2596 elem.appendChild(text); 2597 currentNode.appendChild(elem); 2598 handler.recordValues(elem, o, f, value); 2599 handler.recordValues(text, o, f, value); 2600 } 2601 } 2602 } 2603 2604 protected static class Escape 2605 { 2606 protected char[] value; 2607 2608 protected final char[] AMP = { '&', 'a', 'm', 'p', ';' }; 2609 protected final char[] LESS = { '&', 'l', 't',';' }; 2610 protected final char[] QUOTE = { '&', 'q', 'u', 'o', 't', ';' }; 2611 protected final char[] LF = { '&', '#', 'x', 'A', ';' }; 2612 protected final char[] CR = { '&', '#', 'x', 'D', ';' }; 2613 protected final char[] TAB = { '&', '#', 'x', '9', ';' }; 2614 protected final char[] LINE_FEED = System.getProperty("line.separator").toCharArray(); 2615 2616 public Escape() 2617 { 2618 value = new char[100]; 2619 } 2620 2621 2630 public String convert(String input) 2631 { 2632 boolean changed = false; 2634 int inputLength = input.length(); 2635 grow(inputLength); 2636 input.getChars(0, inputLength, value, 0); 2637 int pos = 0; 2638 char ch = 0; 2639 while (inputLength-- > 0) 2640 { 2641 ch = value[pos]; 2642 switch (ch) 2643 { 2644 case '&': 2645 pos = replace(pos, AMP, inputLength); 2646 changed = true; 2647 break; 2648 case '<': 2649 pos = replace(pos, LESS, inputLength); 2650 changed = true; 2651 break; 2652 case '"': 2653 pos = replace(pos, QUOTE, inputLength); 2654 changed = true; 2655 break; 2656 case '\n': 2657 { 2658 pos = replace(pos, LF, inputLength); 2659 changed = true; 2660 break; 2661 } 2662 case '\r': 2663 { 2664 pos = replace(pos, CR, inputLength); 2665 changed = true; 2666 break; 2667 } 2668 case '\t': 2669 { 2670 pos = replace(pos, TAB, inputLength); 2671 changed = true; 2672 break; 2673 } 2674 default: 2675 if (!XMLChar.isValid(ch)) 2676 { 2677 throw new RuntimeException ("An invalid XML character (Unicode: 0x" + Integer.toHexString(ch)+") was found in the element content:" +input); 2678 } 2679 pos++; 2680 break; 2681 } 2682 } 2683 2684 return changed ? new String (value, 0, pos) : input; 2685 } 2686 2687 2694 public String convertText(String input) 2695 { 2696 boolean changed = false; 2698 int inputLength = input.length(); 2699 grow(inputLength); 2700 input.getChars(0, inputLength, value, 0); 2701 int pos = 0; 2702 char ch; 2703 while (inputLength-- > 0) 2704 { 2705 ch = value[pos]; 2706 switch (ch) 2707 { 2708 case '&': 2709 pos = replace(pos, AMP, inputLength); 2710 changed = true; 2711 break; 2712 case '<': 2713 pos = replace(pos, LESS, inputLength); 2714 changed = true; 2715 break; 2716 case '"': 2717 pos = replace(pos, QUOTE, inputLength); 2718 changed = true; 2719 break; 2720 case '\n': 2721 { 2722 pos = replace(pos, LINE_FEED, inputLength); 2723 changed = true; 2724 break; 2725 } 2726 default: 2727 if (!XMLChar.isValid(ch)) 2728 { 2729 throw new RuntimeException ("An invalid XML character (Unicode: 0x" + Integer.toHexString(ch)+") was found in the element content:" +input); 2730 } 2731 pos++; 2732 break; 2733 } 2734 } 2735 2736 return changed ? new String (value, 0, pos) : input; 2737 } 2738 2739 2743 public String convertLines(String input) 2744 { 2745 boolean changed = false; 2746 int inputLength = input.length(); 2747 grow(inputLength); 2748 input.getChars(0, inputLength, value, 0); 2749 int pos = 0; 2750 while (inputLength-- > 0) 2751 { 2752 switch (value[pos]) 2753 { 2754 case '\n': 2755 { 2756 pos = replace(pos, LINE_FEED, inputLength); 2757 changed = true; 2758 break; 2759 } 2760 default: 2761 pos++; 2762 break; 2763 } 2764 } 2765 2766 return changed ? new String (value, 0, pos) : input; 2767 } 2768 2769 protected int replace(int pos, char[] replacement, int inputLength) 2770 { 2771 int rlen = replacement.length; 2772 int newPos = pos + rlen; 2773 grow(newPos + inputLength); 2774 System.arraycopy(value, pos+1, value, newPos, inputLength); 2775 System.arraycopy(replacement, 0, value, pos, rlen); 2776 return newPos; 2777 } 2778 2779 protected void grow(int newSize) 2780 { 2781 int vlen = value.length; 2782 if (vlen < newSize) 2783 { 2784 char[] newValue = new char[newSize + newSize/2]; 2785 System.arraycopy(value, 0, newValue, 0, vlen); 2786 value = newValue; 2787 } 2788 } 2789 } 2790 2791 2795 protected class XMLTypeInfoImpl implements XMLTypeInfo 2796 { 2797 2798 public boolean shouldSaveType(EClass objectType, EClassifier featureType, EStructuralFeature feature) 2799 { 2800 return objectType != featureType && objectType != anyType; 2801 } 2802 2803 public boolean shouldSaveType(EClass objectType, EClass featureType, EStructuralFeature feature) 2804 { 2805 return objectType != featureType; 2806 } 2807 } 2808} 2809 | Popular Tags |