Changeset 1004 for trunk/docx4j/src/main/java/org/docx4j/openpackaging/contenttype/ContentTypeManager.java
- Timestamp:
- 01/09/10 18:15:02 (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/docx4j/src/main/java/org/docx4j/openpackaging/contenttype/ContentTypeManager.java
r954 r1004 60 60 import java.util.zip.ZipOutputStream; 61 61 62 import javax.xml.bind.JAXBElement; 63 import javax.xml.bind.JAXBException; 64 import javax.xml.bind.Marshaller; 65 import javax.xml.bind.Unmarshaller; 66 62 67 import org.apache.log4j.Logger; 68 import org.docx4j.jaxb.Context; 69 import org.docx4j.jaxb.NamespacePrefixMapperUtils; 63 70 import org.docx4j.openpackaging.exceptions.InvalidFormatException; 64 71 import org.docx4j.openpackaging.exceptions.PartUnrecognisedException; … … 67 74 import org.docx4j.openpackaging.parts.*; 68 75 import org.docx4j.openpackaging.parts.WordprocessingML.*; 69 import org.dom4j.Document;70 import org.dom4j.DocumentException;71 import org.dom4j.DocumentHelper;72 import org.dom4j.Element;73 import org.dom4j.Namespace;74 import org.dom4j.QName;75 import org.dom4j.io.SAXReader;76 76 77 77 … … 115 115 * Default content type tree. <Extension, ContentType> 116 116 */ 117 private TreeMap<String, String> defaultContentType;117 private TreeMap<String, CTDefault> defaultContentType; 118 118 119 119 /** 120 120 * Override content type tree. 121 121 */ 122 private TreeMap<URI, String> overrideContentType; 123 124 /** 125 * Constructor. Parses the content of the specified input stream. 126 * 127 * @param archive 128 * If different of <i>null</i> then the content types part is 129 * retrieve and parse. 130 * @throws InvalidFormatException 131 * If the content types part content is not valid. 132 */ 133 public ContentTypeManager(Document contentTypes) throws InvalidFormatException { 134 init(); 135 if (contentTypes != null) { 136 try { 137 parseContentTypesFile(contentTypes); 138 } catch (InvalidFormatException e) { 139 throw new InvalidFormatException( 140 "Can't read content types part !"); 141 } 142 } else { 143 log.warn("Passed null content types ?!"); 144 } 145 } 122 private TreeMap<URI, CTOverride> overrideContentType; 123 124 private static ObjectFactory ctFactory = new ObjectFactory(); 146 125 147 126 public ContentTypeManager() { … … 150 129 151 130 private void init() { 152 defaultContentType = new TreeMap<String, String>();153 overrideContentType = new TreeMap<URI, String>();154 } 155 156 /**157 * Build association extention-> content type (will be stored in158 * [Content_Types].xml) for example ContentType="image/png" Extension="png"159 *160 * @param partUri161 * the uri that will be stored162 * @return <b>false</b> if an error occured.163 */164 public void addContentType(PartName partName, String contentType) {165 boolean defaultCTExists = false;166 String extension = partName.getExtension();167 if ((extension.length() == 0)168 || (this.defaultContentType.containsKey(extension)169 && !(defaultCTExists = this.defaultContentType.containsValue(contentType)))) {170 this.addOverrideContentType(partName.getURI(), contentType);171 } else if (!defaultCTExists) {172 this.addDefaultContentType(extension, contentType);173 }174 }131 defaultContentType = new TreeMap<String, CTDefault>(); 132 overrideContentType = new TreeMap<URI, CTOverride>(); 133 } 134 135 // /** 136 // * Build association extention-> content type (will be stored in 137 // * [Content_Types].xml) for example ContentType="image/png" Extension="png" 138 // * 139 // * @param partUri 140 // * the uri that will be stored 141 // * @return <b>false</b> if an error occured. 142 // */ 143 // public void addContentType(PartName partName, String contentType) { 144 // boolean defaultCTExists = false; 145 // String extension = partName.getExtension(); 146 // if ((extension.length() == 0) 147 // || (this.defaultContentType.containsKey(extension) 148 // && !(defaultCTExists = this.defaultContentType.containsValue(contentType)))) { 149 // this.addOverrideContentType(partName.getURI(), contentType); 150 // } else if (!defaultCTExists) { 151 // this.addDefaultContentType(extension, contentType); 152 // } 153 // } 175 154 176 155 /** … … 182 161 * Content type of the part. 183 162 */ 184 public void addOverrideContentType(URI partUri, StringcontentType) {163 public void addOverrideContentType(URI partUri, CTOverride contentType) { 185 164 log.info("Registered " + partUri.toString() ); 186 165 overrideContentType.put(partUri, contentType); 166 } 167 168 public void addOverrideContentType(URI partUri, String contentType) { 169 170 CTOverride overrideCT = ctFactory.createCTOverride(); 171 overrideCT.setPartName( partUri.toASCIIString() ); 172 overrideCT.setContentType(contentType ); 173 174 overrideContentType.put(partUri, overrideCT); 175 187 176 } 188 177 … … 205 194 if (e != null) { 206 195 log.debug("Inspecting " + e.getValue()); 207 if ( (( String)e.getValue()).equals(contentType) ) {196 if ( ((CTOverride)e.getValue()).getContentType().equals(contentType) ) { 208 197 log.debug("Matched!"); 209 198 return (URI)e.getKey(); … … 222 211 223 212 // look for an override 224 String contentType = (String)overrideContentType.get(new URI(partName)); 225 if (contentType!=null ) { 213 CTOverride overrideCT = (CTOverride) overrideContentType.get(new URI(partName)); 214 if (overrideCT!=null ) { 215 String contentType = overrideCT.getContentType(); 226 216 log.debug("Found content type '" + contentType + "' for " + partName); 227 217 p = newPartForContentType(contentType, partName); … … 233 223 String ext = partName.substring(partName.indexOf(".") + 1); 234 224 log.info("Looking at extension '" + ext); 235 contentType = (String)defaultContentType.get(ext); 236 if (contentType!=null ) { 225 CTDefault defaultCT = (CTDefault)defaultContentType.get(ext); 226 if (defaultCT!=null ) { 227 String contentType = defaultCT.getContentType(); 237 228 log.info("Found content type '" + contentType + "' for " 238 229 + partName); … … 442 433 * The content type associated with the specified extension. 443 434 */ 444 public void addDefaultContentType(String extension, StringcontentType) {435 public void addDefaultContentType(String extension, CTDefault contentType) { 445 436 log.debug("Registered " + extension ); 446 437 defaultContentType.put(extension, contentType); 447 438 } 439 440 public void addDefaultContentType(String extension, String contentType) { 441 442 CTDefault defaultCT = ctFactory.createCTDefault(); 443 defaultCT.setExtension("extension"); 444 defaultCT.setContentType(contentType); 445 446 log.debug("Registered " + extension ); 447 defaultContentType.put(extension, defaultCT); 448 } 449 448 450 449 451 /** … … 506 508 if ((this.overrideContentType != null) 507 509 && this.overrideContentType.containsKey(partName.getURI())) 508 return this.overrideContentType.get(partName.getURI()) ;510 return this.overrideContentType.get(partName.getURI()).getContentType(); 509 511 510 512 String extension = partName.getExtension(); 511 513 if (this.defaultContentType.containsKey(extension)) 512 return this.defaultContentType.get(extension) ;514 return this.defaultContentType.get(extension).getContentType(); 513 515 514 516 return null; … … 533 535 } 534 536 535 /** 536 * Parse the content types part. 537 * 538 * @throws InvalidFormatException 539 * Throws if the content type doesn't exist or the XML format is 540 * invalid. 541 */ 542 public void parseContentTypesFile(Document xmlContentTypeDoc) 543 throws InvalidFormatException { 544 //log.info("parseContentTypesFile"); 537 538 public void parseContentTypesFile(InputStream contentTypes) 539 throws InvalidFormatException { 540 541 CTTypes types; 542 545 543 try { 546 547 // Default content types 548 List defaultTypes = xmlContentTypeDoc.getRootElement().elements( 549 DEFAULT_TAG_NAME); 550 Iterator elementIteratorDefault = defaultTypes.iterator(); 551 while (elementIteratorDefault.hasNext()) { 552 Element element = (Element) elementIteratorDefault.next(); 553 String extension = element.attribute(EXTENSION_ATTRIBUTE_NAME) 554 .getValue(); 555 //log.info("found " + DEFAULT_TAG_NAME + extension); 556 String contentType = element.attribute( 557 CONTENT_TYPE_ATTRIBUTE_NAME).getValue(); 558 addDefaultContentType(extension, contentType); 544 545 Unmarshaller u = Context.jcContentTypes.createUnmarshaller(); 546 547 //u.setSchema(org.docx4j.jaxb.WmlSchema.schema); 548 u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler()); 549 550 log.debug("unmarshalling " + this.getClass().getName() ); 551 552 Object res = u.unmarshal( contentTypes ); 553 types = (CTTypes)((JAXBElement)res).getValue(); 554 log.debug( types.getClass().getName() + " unmarshalled" ); 555 556 CTDefault defaultCT; 557 CTOverride overrideCT; 558 for(Object o : types.getDefaultOrOverride() ) { 559 560 if (o instanceof CTDefault) { 561 defaultCT = (CTDefault)o; 562 addDefaultContentType( defaultCT.getExtension(), defaultCT ); 563 } 564 565 if (o instanceof CTOverride) { 566 overrideCT = (CTOverride)o; 567 URI uri = new URI(overrideCT.getPartName() ); 568 addOverrideContentType(uri, overrideCT ); 569 } 559 570 } 560 561 // Overriden content types 562 List overrideTypes = xmlContentTypeDoc.getRootElement().elements( 563 OVERRIDE_TAG_NAME); 564 Iterator elementIteratorOverride = overrideTypes.iterator(); 565 while (elementIteratorOverride.hasNext()) { 566 Element element = (Element) elementIteratorOverride.next(); 567 URI uri = new URI(element.attribute(PART_NAME_ATTRIBUTE_NAME) 568 .getValue()); 569 String contentType = element.attribute( 570 CONTENT_TYPE_ATTRIBUTE_NAME).getValue(); 571 addOverrideContentType(uri, contentType); 571 572 } catch (Exception e ) { 573 log.error(e); 574 throw new InvalidFormatException("Bad [Content_Types].xml", e); 575 } 576 577 578 } 579 580 private CTTypes buildTypes() { 581 582 // Build the JAXB object 583 ObjectFactory factory = new ObjectFactory(); 584 CTTypes types = factory.createCTTypes(); 585 586 for (Entry<String, CTDefault> entry : defaultContentType.entrySet()) { 587 types.getDefaultOrOverride().add(entry.getValue()); 588 } 589 590 if (overrideContentType != null) { 591 for (Entry<URI, CTOverride> entry : overrideContentType.entrySet()) { 592 types.getDefaultOrOverride().add(entry.getValue()); 572 593 } 573 } catch (URISyntaxException urie) { 574 throw new InvalidFormatException(urie.getMessage()); 575 } 576 } 577 578 /** 579 * Generates the XML for the contents type part. 580 * 581 * @param outStream 582 * The output stream use to save the XML content of the content 583 * types part. 584 * @return <b>true</b> if the operation success, else <b>false</b>. 585 */ 586 public Document getDocument() { 587 Document xmlOutDoc = DocumentHelper.createDocument(); 588 589 // Building namespace 590 Namespace dfNs = Namespace.get("", TYPES_NAMESPACE_URI); 591 Element typesElem = xmlOutDoc 592 .addElement(new QName(TYPES_TAG_NAME, dfNs)); 593 594 // Adding default types 595 for (Entry<String, String> entry : defaultContentType.entrySet()) { 596 appendDefaultType(typesElem, entry); 597 } 598 599 // Adding specific types if any exist 600 if (overrideContentType != null) { 601 for (Entry<URI, String> entry : overrideContentType.entrySet()) { 602 appendSpecificTypes(typesElem, entry); 603 } 604 } 605 xmlOutDoc.normalize(); 606 607 return xmlOutDoc; 608 } 609 610 /** 611 * Use to append specific type XML elements, use by the save() method. 612 * 613 * @param root 614 * XML parent element use to append this override type element. 615 * @param entry 616 * The values to append. 617 * @see #save(ZipOutputStream) 618 */ 619 private void appendSpecificTypes(Element root, Entry<URI, String> entry) { 620 root.addElement(OVERRIDE_TAG_NAME).addAttribute( 621 PART_NAME_ATTRIBUTE_NAME, ((URI) entry.getKey()).getPath()) 622 .addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, 623 (String) entry.getValue()); 624 } 625 626 /** 627 * Use to append default types XML elements, use by the save() metid. 628 * 629 * @param root 630 * XML parent element use to append this default type element. 631 * @param entry 632 * The values to append. 633 * @see #save(ZipOutputStream) 634 */ 635 private void appendDefaultType(Element root, Entry<String, String> entry) { 636 root.addElement(DEFAULT_TAG_NAME).addAttribute( 637 EXTENSION_ATTRIBUTE_NAME, (String) entry.getKey()) 638 .addAttribute(CONTENT_TYPE_ATTRIBUTE_NAME, 639 (String) entry.getValue()); 640 641 } 594 } 595 return types; 596 } 597 598 public void marshal(org.w3c.dom.Node node) throws JAXBException { 599 600 try { 601 Marshaller marshaller = Context.jcContentTypes.createMarshaller(); 602 603 NamespacePrefixMapperUtils.setProperty(marshaller, 604 NamespacePrefixMapperUtils.getPrefixMapper() ); 605 606 log.debug("marshalling " + this.getClass().getName() + " ..." ); 607 608 marshaller.marshal(buildTypes(), node); 609 610 log.info("content types marshalled \n\n" ); 611 612 } catch (JAXBException e) { 613 //e.printStackTrace(); 614 log.error(e); 615 throw e; 616 } 617 } 618 619 public void marshal(java.io.OutputStream os) throws JAXBException { 620 621 try { 622 Marshaller marshaller = Context.jcContentTypes.createMarshaller(); 623 624 NamespacePrefixMapperUtils.setProperty(marshaller, 625 NamespacePrefixMapperUtils.getPrefixMapper() ); 626 627 log.debug("marshalling " + this.getClass().getName() + " ..." ); 628 629 marshaller.marshal(buildTypes(), os); 630 631 log.info("content types marshalled \n\n" ); 632 633 } catch (JAXBException e) { 634 //e.printStackTrace(); 635 log.error(e); 636 throw e; 637 } 638 } 639 640 642 641 643 642 /* Return a package of the appropriate type. Used when loading an existing
Note: See TracChangeset
for help on using the changeset viewer.
