Changeset 1449


Ignore:
Timestamp:
03/06/11 04:28:14 (15 months ago)
Author:
jharrop
Message:

Handle a databinding which points to Core or Extended Properties, or CoverPage? props.

Location:
trunk/docx4j/src/main/java/org/docx4j
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/docx4j/src/main/java/org/docx4j/model/datastorage/BindingHandler.java

    r1441 r1449  
    99import javax.xml.bind.JAXBException; 
    1010import javax.xml.bind.Unmarshaller; 
     11import javax.xml.parsers.DocumentBuilderFactory; 
    1112import javax.xml.transform.Source; 
    1213import javax.xml.transform.Templates; 
    1314import javax.xml.transform.TransformerConfigurationException; 
    1415import javax.xml.transform.stream.StreamSource; 
     16import javax.xml.xpath.XPath; 
     17import javax.xml.xpath.XPathFactory; 
    1518 
    1619import org.apache.commons.codec.binary.Base64; 
     
    1922import org.docx4j.dml.wordprocessingDrawing.Inline; 
    2023import org.docx4j.jaxb.Context; 
     24import org.docx4j.jaxb.NamespacePrefixMappings; 
    2125import org.docx4j.openpackaging.exceptions.Docx4JException; 
    2226import org.docx4j.openpackaging.packages.WordprocessingMLPackage; 
    2327import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart; 
     28import org.docx4j.openpackaging.parts.DefaultXmlPart; 
    2429import org.docx4j.openpackaging.parts.JaxbXmlPart; 
     30import org.docx4j.openpackaging.parts.XmlPart; 
    2531import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage; 
    2632import org.docx4j.wml.CTSimpleField; 
     
    3642         
    3743        static Templates xslt;                   
     44        private static XPathFactory xPathFactory; 
     45        private static XPath xPath; 
    3846        static { 
    3947                try { 
     
    4755                        e.printStackTrace(); 
    4856                } 
     57                 
     58                xPathFactory = XPathFactory.newInstance(); 
     59                xPath = xPathFactory.newXPath();                 
    4960        } 
     61         
    5062         
    5163        public static void log(String message ) { 
     
    101113                                         
    102114                } 
     115 
     116                // These Store Item ID's come from Building Blocks.dotx glossary document 
     117                // Of these, only CoverPageProps is documented as an "Office Well Defined Custom XML Part", 
     118                // but even then, that documentation does not allocate a store item ID. 
     119                public static final String CORE_PROPERTIES_STOREITEMID =                "{6C3C8BC8-F283-45AE-878A-BAB7291924A1}"; 
     120                public static final String EXTENDED_PROPERTIES_STOREITEMID =    "{6668398D-A668-4E3E-A5EB-62B293D839F1}"; 
     121                public static final String COVERPAGE_PROPERTIES_STOREITEMID =   "{55AF091B-3C7A-41E3-B477-F2FDAA23CFDA}"; 
     122                 
    103123                 
    104124                /** 
    105                  * Used by OpenDoPE handler, but not by bind.xslt anymore. 
     125                 * Used by OpenDoPE handler, but not directly by bind.xslt anymore. 
    106126                 * Not multiLine aware. 
    107127                 *  
     
    112132                 * @return 
    113133                 */ 
    114                 public static String xpathGetString(Map<String, CustomXmlDataStoragePart> customXmlDataStorageParts, 
     134                public static String xpathGetString( 
     135                                WordprocessingMLPackage pkg, Map<String, CustomXmlDataStoragePart> customXmlDataStorageParts, 
    115136                                String storeItemId, String xpath, String prefixMappings) { 
    116137                         
    117                         CustomXmlDataStoragePart part = customXmlDataStorageParts.get(storeItemId.toLowerCase()); 
    118                         if (part==null) { 
    119                                 log.error("Couldn't locate part by storeItemId " + storeItemId); 
    120                                 return null; 
    121                         } 
    122138                        try { 
     139                                 
     140                                if (storeItemId.toUpperCase().equals(CORE_PROPERTIES_STOREITEMID)  ) { 
     141                                         
     142                                        return pkg.getDocPropsCorePart().xpathGetString(xpath, prefixMappings); 
     143                                         
     144                                } else if (storeItemId.toUpperCase().equals(EXTENDED_PROPERTIES_STOREITEMID) ) { 
     145                                         
     146                                        return pkg.getDocPropsExtendedPart().xpathGetString(xpath, prefixMappings); 
     147                                }  
     148                                 
     149                                CustomXmlDataStoragePart part  = customXmlDataStorageParts.get(storeItemId.toLowerCase()); 
     150                                        // Also handles cover page properties (since we've allocated it a store item id) 
     151                                        // Note that Word does not create that part until the user provides one or more prop values 
     152                                 
     153                                if (part==null) { 
     154                                        log.error("Couldn't locate part by storeItemId " + storeItemId); 
     155                                        return null; 
     156                                } 
     157                                 
    123158                                if (log.isDebugEnabled() ) { 
    124159                                        String r = part.getData().xpathGetString(xpath, prefixMappings); 
     
    135170 
    136171                 
     172                 
    137173                /** 
    138174                 */ 
    139                 public static DocumentFragment xpathGenerateRuns(Map<String, CustomXmlDataStoragePart> customXmlDataStorageParts, 
     175                public static DocumentFragment xpathGenerateRuns( 
     176                                WordprocessingMLPackage pkg, Map<String, CustomXmlDataStoragePart> customXmlDataStorageParts, 
    140177                                String storeItemId, String xpath, String prefixMappings, 
    141178                                NodeIterator rPrNodeIt, boolean multiLine) { 
     
    150187                         */ 
    151188 
    152                         CustomXmlDataStoragePart part = customXmlDataStorageParts.get(storeItemId.toLowerCase()); 
    153                         if (part==null) { 
    154                                 log.error("Couldn't locate part by storeItemId " + storeItemId); 
    155                                 return null; 
    156                         } 
     189                        String r = xpathGetString(pkg, customXmlDataStorageParts, storeItemId, xpath, prefixMappings); 
     190                        if (r==null) return null; 
    157191 
    158192                        DocumentFragment docfrag = null; // = document.createDocumentFragment(); 
     
    160194                         
    161195                        try { 
    162                                 String r = part.getData().xpathGetString(xpath, prefixMappings); 
    163196                                log.debug(xpath + " yielded result " + r); 
    164197                                 
     
    349382                } 
    350383 
    351          
    352  
    353384} 
  • trunk/docx4j/src/main/java/org/docx4j/model/datastorage/OpenDoPEHandler.java

    r1440 r1449  
    562562                                org.opendope.xpaths.Xpaths.Xpath xpath = getXPathFromCondition(c); 
    563563                                 
    564                                 String val = BindingHandler.xpathGetString(customXmlDataStorageParts, 
     564                                String val = BindingHandler.xpathGetString(wordMLPackage, 
     565                                                customXmlDataStorageParts, 
    565566                                                xpath.getDataBinding().getStoreItemID(), 
    566567                                                xpath.getDataBinding().getXpath(), 
     
    638639                                org.opendope.xpaths.Xpaths.Xpath xpathObj = XPathsPart.getXPathById(xPaths, xp); 
    639640                                String value = BindingHandler.xpathGetString( 
     641                                                                                                wordMLPackage, 
    640642                                                                                                customXmlDataStorageParts,  
    641643                                                                                                xpathObj.getDataBinding().getStoreItemID(), 
  • trunk/docx4j/src/main/java/org/docx4j/model/datastorage/bind.xslt

    r1441 r1449  
    6161                                                                <xsl:copy-of 
    6262                                                                select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     63                                                                                        $wmlPackage, 
    6364                                                                                        $customXmlDataStorageParts, 
    6465                                                                                        string(w:sdtPr/w:dataBinding/@w:storeItemID), 
     
    7374                                                        <xsl:copy-of 
    7475                                                        select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     76                                                                                $wmlPackage, 
    7577                                                                                $customXmlDataStorageParts, 
    7678                                                                                string(w:sdtPr/w:dataBinding/@w:storeItemID), 
  • trunk/docx4j/src/main/java/org/docx4j/openpackaging/io/Load.java

    r1421 r1449  
    3131import org.apache.log4j.Logger; 
    3232import org.docx4j.jaxb.Context; 
     33import org.docx4j.model.datastorage.BindingHandler; 
    3334import org.docx4j.model.datastorage.CustomXmlDataStorage; 
    3435import org.docx4j.model.datastorage.CustomXmlDataStorageImpl; 
     
    3839import org.docx4j.openpackaging.exceptions.PartUnrecognisedException; 
    3940import org.docx4j.openpackaging.packages.OpcPackage; 
     41import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart; 
    4042import org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart; 
    4143import org.docx4j.openpackaging.parts.Part; 
     
    276278                        if (entry instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePart) { 
    277279                                log.debug("Found a CustomXmlDataStoragePart, named " + entry.getPartName().getName() ); 
    278                                 if (entry.getRelationshipsPart()==null) { continue; } 
    279                                 log.debug(".. it has a rels part"); 
    280                                 // Look in its rels for rel of @Type customXmlProps (eg @Target="itemProps1.xml") 
    281                                 Relationship r = entry.getRelationshipsPart().getRelationshipByType( 
    282                                                 Namespaces.CUSTOM_XML_DATA_STORAGE_PROPERTIES); 
    283                                 if (r==null) { 
    284                                         log.debug(".. but that doesn't point to a  customXmlProps part"); 
    285                                         continue; 
     280                                String itemId = null; 
     281                                if (entry.getRelationshipsPart()==null) {  
     282                                        continue;  
     283                                } else { 
     284                                        log.debug(".. it has a rels part"); 
     285                                        // Look in its rels for rel of @Type customXmlProps (eg @Target="itemProps1.xml") 
     286                                        Relationship r = entry.getRelationshipsPart().getRelationshipByType( 
     287                                                        Namespaces.CUSTOM_XML_DATA_STORAGE_PROPERTIES); 
     288                                        if (r==null) { 
     289                                                log.debug(".. but that doesn't point to a  customXmlProps part"); 
     290                                                continue; 
     291                                        } 
     292                                        CustomXmlDataStoragePropertiesPart customXmlProps =  
     293                                                (CustomXmlDataStoragePropertiesPart)entry.getRelationshipsPart().getPart(r); 
     294                                        if (customXmlProps==null) { 
     295                                                log.error(".. but the target seems to be missing?"); 
     296                                                 
     297                                                try { 
     298                                                        org.w3c.dom.Document document = ((CustomXmlDataStoragePart)entry).getData().getDocument(); 
     299                                                        String localName = document.getDocumentElement().getLocalName(); 
     300                                                        log.debug(localName); 
     301                                                        if (document.getDocumentElement().isDefaultNamespace("http://schemas.microsoft.com/?office/?2006/?coverPageProps") 
     302                                                                        || localName.equals("CoverPageProperties" ) ) { 
     303                                                                // Special case: CoverPageProperties 
     304                                                                // See "Office Well Defined Custom XML Parts"; see documentinteropinitiative.org/additionalinfo/IS29500/sect5.aspx 
     305                                                                // Has a rels part, but sometimes no target?  Sometimes it definitely does ... 
     306                                                                // Give it the store item id, Word 2007 seems to consistently allocate   
     307                                                                itemId = BindingHandler.COVERPAGE_PROPERTIES_STOREITEMID.toLowerCase(); 
     308                                                        } else { 
     309                                                                continue; 
     310                                                        } 
     311                                                } catch (Docx4JException e) { 
     312                                                        e.printStackTrace(); 
     313                                                        continue; 
     314                                                } 
     315                                        } else { 
     316                                                itemId = customXmlProps.getItemId().toLowerCase(); 
     317                                        } 
    286318                                } 
    287                                 CustomXmlDataStoragePropertiesPart customXmlProps =  
    288                                         (CustomXmlDataStoragePropertiesPart)entry.getRelationshipsPart().getPart(r); 
    289                                 if (customXmlProps==null) { 
    290                                         log.error(".. but the target seems to be missing?"); 
    291                                         continue; 
    292                                 } 
    293                                 String itemId = customXmlProps.getItemId().toLowerCase(); 
    294319                                log.info("Identified/registered ds:itemId " + itemId); 
    295320                                if (pkg.getCustomXmlDataStorageParts().get(itemId.toLowerCase())!=null) { 
  • trunk/docx4j/src/main/java/org/docx4j/openpackaging/parts/DocPropsCorePart.java

    r1378 r1449  
    2020package org.docx4j.openpackaging.parts; 
    2121 
     22import java.io.IOException; 
     23 
    2224import javax.xml.bind.JAXBException; 
    2325import javax.xml.bind.Unmarshaller; 
     26import javax.xml.transform.Source; 
     27import javax.xml.transform.TransformerConfigurationException; 
     28import javax.xml.transform.stream.StreamSource; 
     29import javax.xml.xpath.XPath; 
     30import javax.xml.xpath.XPathFactory; 
    2431 
    2532import org.apache.log4j.Logger; 
     33import org.docx4j.XmlUtils; 
    2634import org.docx4j.docProps.core.CoreProperties; 
    2735import org.docx4j.jaxb.Context; 
     36import org.docx4j.jaxb.NamespacePrefixMappings; 
     37import org.docx4j.openpackaging.exceptions.Docx4JException; 
    2838import org.docx4j.openpackaging.exceptions.InvalidFormatException; 
    2939import org.docx4j.openpackaging.parts.relationships.Namespaces; 
     40import org.w3c.dom.Document; 
    3041import org.w3c.dom.Element; 
    3142 
     
    5162         
    5263        private static Logger log = Logger.getLogger(DocPropsCorePart.class); 
     64         
     65        private static XPathFactory xPathFactory; 
     66        private static XPath xPath; 
     67        static { 
     68                xPathFactory = XPathFactory.newInstance(); 
     69                xPath = xPathFactory.newXPath();                 
     70        } 
    5371         
    5472         /**  
     
    114132    } 
    115133 
     134        // Core Props and Extended Props can both be bound as if they 
     135        // were a custom xml part.  Copied from XmlPart. 
     136         
     137        public String xpathGetString(String xpathString, String prefixMappings)  throws Docx4JException { 
     138                 
     139                Document doc = XmlUtils.marshaltoW3CDomDocument( 
     140                                getJaxbElement(), Context.jcDocPropsCore ); 
     141                 
     142                try { 
     143                        getNamespaceContext().registerPrefixMappings(prefixMappings); 
     144                         
     145                        String result = xPath.evaluate(xpathString, doc ); 
     146                        log.debug(xpathString + " ---> " + result); 
     147                        return result; 
     148                } catch (Exception e) { 
     149                        throw new Docx4JException("Problems evaluating xpath '" + xpathString + "'", e); 
     150                } 
     151        } 
     152        private NamespacePrefixMappings nsContext; 
     153        private NamespacePrefixMappings getNamespaceContext() { 
     154                if (nsContext==null) { 
     155                        nsContext = new NamespacePrefixMappings(); 
     156                        xPath.setNamespaceContext(nsContext); 
     157                } 
     158                return nsContext; 
     159        } 
    116160     
    117161         
  • trunk/docx4j/src/main/java/org/docx4j/openpackaging/parts/DocPropsExtendedPart.java

    r1378 r1449  
    2424import javax.xml.bind.JAXBException; 
    2525import javax.xml.bind.Unmarshaller; 
     26import javax.xml.xpath.XPath; 
     27import javax.xml.xpath.XPathFactory; 
    2628 
    2729import org.apache.log4j.Logger; 
     30import org.docx4j.XmlUtils; 
    2831import org.docx4j.docProps.extended.Properties; 
    2932import org.docx4j.jaxb.Context; 
     33import org.docx4j.jaxb.NamespacePrefixMappings; 
     34import org.docx4j.openpackaging.exceptions.Docx4JException; 
    3035import org.docx4j.openpackaging.exceptions.InvalidFormatException; 
    3136import org.docx4j.openpackaging.parts.relationships.Namespaces; 
     37import org.w3c.dom.Document; 
    3238 
    3339 
     
    5763         
    5864        private static Logger log = Logger.getLogger(DocPropsExtendedPart.class); 
     65         
     66        private static XPathFactory xPathFactory; 
     67        private static XPath xPath; 
     68        static { 
     69                xPathFactory = XPathFactory.newInstance(); 
     70                xPath = xPathFactory.newXPath();                 
     71        } 
    5972         
    6073         /**  
     
    123136         
    124137    } 
     138 
     139        // Core Props and Extended Props can both be bound as if they 
     140        // were a custom xml part.  Copied from XmlPart. 
     141         
     142        public String xpathGetString(String xpathString, String prefixMappings)  throws Docx4JException { 
     143                 
     144                Document doc = XmlUtils.marshaltoW3CDomDocument( 
     145                                getJaxbElement(), Context.jcDocPropsExtended ); 
     146                 
     147                try { 
     148                        getNamespaceContext().registerPrefixMappings(prefixMappings); 
     149                         
     150                        String result = xPath.evaluate(xpathString, doc ); 
     151                        log.debug(xpathString + " ---> " + result); 
     152                        return result; 
     153                } catch (Exception e) { 
     154                        throw new Docx4JException("Problems evaluating xpath '" + xpathString + "'", e); 
     155                } 
     156        } 
     157        private NamespacePrefixMappings nsContext; 
     158        private NamespacePrefixMappings getNamespaceContext() { 
     159                if (nsContext==null) { 
     160                        nsContext = new NamespacePrefixMappings(); 
     161                        xPath.setNamespaceContext(nsContext); 
     162                } 
     163                return nsContext; 
     164        } 
    125165         
    126166} 
Note: See TracChangeset for help on using the changeset viewer.