Changeset 1658 for trunk


Ignore:
Timestamp:
09/13/11 14:41:04 (8 months ago)
Author:
jharrop
Message:

Word can only resolve an XPath binding which results in an element (as opposed to a boolean, integer, string or node-set).
OpenDoPE processing can handle these other results types (some of them anyway).
Up until now, that processing was done in OpenDoPEHandler.
Now it is done in BindingHandler? and bind.xslt, for consistency with how normal Word XPath bindings are handled by docx4j.

Location:
trunk/docx4j/src/main/java/org/docx4j/model/datastorage
Files:
3 edited

Legend:

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

    r1647 r1658  
    2222import org.docx4j.dml.wordprocessingDrawing.Inline; 
    2323import org.docx4j.jaxb.Context; 
     24import org.docx4j.model.sdt.QueryString; 
    2425import org.docx4j.openpackaging.exceptions.Docx4JException; 
    2526import org.docx4j.openpackaging.packages.WordprocessingMLPackage; 
     
    2930import org.docx4j.openpackaging.parts.WordprocessingML.FooterPart; 
    3031import org.docx4j.openpackaging.parts.WordprocessingML.HeaderPart; 
     32import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart; 
     33import org.docx4j.openpackaging.parts.opendope.XPathsPart; 
    3134import org.docx4j.openpackaging.parts.relationships.Namespaces; 
    3235import org.docx4j.openpackaging.parts.relationships.RelationshipsPart; 
     
    3437import org.docx4j.wml.P.Hyperlink; 
    3538import org.docx4j.wml.RPr; 
     39import org.opendope.xpaths.Xpaths.Xpath; 
    3640import org.w3c.dom.Document; 
    3741import org.w3c.dom.DocumentFragment; 
     
    144148                                        part.getJaxbElement() );         
    145149                         
     150                        XPathsPart xPathsPart = null; 
     151                         
     152                        if ( ((WordprocessingMLPackage)pkg).getMainDocumentPart().getXPathsPart() == null) { 
     153                                log.error("OpenDoPE XPaths part missing"); 
     154                                //throw new Docx4JException("OpenDoPE XPaths part missing"); 
     155                        } else { 
     156                                xPathsPart = ((WordprocessingMLPackage)pkg).getMainDocumentPart().getXPathsPart(); 
     157                                //log.debug(XmlUtils.marshaltoString(xPaths, true, true)); 
     158                        } 
     159                         
     160                         
    146161                        JAXBContext jc = Context.jc; 
    147162                        try { 
     
    157172                                transformParameters.put("wmlPackage", (WordprocessingMLPackage)pkg);                     
    158173                                transformParameters.put("sourcePart", part);                     
     174                                transformParameters.put("xPathsPart", xPathsPart);                       
    159175                                                 
    160176                                org.docx4j.XmlUtils.transform(doc, xslt, transformParameters, result); 
     
    249265                         
    250266                        try { 
    251                                 log.debug(xpath + " yielded result " + r); 
     267                                log.info(xpath + " yielded result " + r); 
    252268                                 
    253269                                RPr rPr = null; 
     
    515531                } 
    516532                 
     533                public static DocumentFragment xpathGenerateRuns( 
     534                                WordprocessingMLPackage pkg,  
     535                                JaxbXmlPart sourcePart,                          
     536                                Map<String, CustomXmlDataStoragePart> customXmlDataStorageParts, 
     537                                XPathsPart xPathsPart, 
     538                                String odTag,  
     539                                NodeIterator rPrNodeIt, boolean multiLine) { 
     540                         
     541                        QueryString qs = new QueryString(); 
     542                        HashMap<String, String> map = qs.parseQueryString(odTag, true); 
     543                         
     544                        String xpathId = map.get(OpenDoPEHandler.BINDING_ROLE_XPATH); 
     545                         
     546                        log.info("Looking for xpath by id: " + xpathId); 
     547                 
     548                         
     549                        Xpath xpath = xPathsPart.getXPathById(xPathsPart.getJaxbElement(), xpathId); 
     550                         
     551                        String storeItemId = xpath.getDataBinding().getStoreItemID(); 
     552                        String xpathExp = xpath.getDataBinding().getXpath(); 
     553                        String prefixMappings = xpath.getDataBinding().getPrefixMappings(); 
     554                         
     555                        return xpathGenerateRuns( 
     556                                         pkg,  
     557                                         sourcePart,                             
     558                                         customXmlDataStorageParts, 
     559                                         storeItemId,  xpathExp,  prefixMappings, 
     560                                         rPrNodeIt,  multiLine); 
     561                         
     562                } 
     563                 
     564                 
    517565 
    518566} 
  • trunk/docx4j/src/main/java/org/docx4j/model/datastorage/OpenDoPEHandler.java

    r1653 r1658  
    719719                } else if (xp != null) { 
    720720 
    721                         if (getSdtPr(sdt).getDataBinding() != null) { 
    722                                 // the XPath evaluates to an element, which Word can 
    723                                 // handle, so do nothing (shouldn't get here anyway though) 
    724                                 List<Object> newContent = new ArrayList<Object>(); 
    725                                 newContent.add(sdt); 
    726                                 return newContent; 
    727                         } 
    728                         log.info("Processing XPath expression: " + tag.getVal()); 
    729                         log.info(XmlUtils.marshaltoString(sdt, true, true)); 
    730  
    731                         List<Object> contentList = null; 
    732                         if (sdt instanceof org.docx4j.wml.SdtBlock) { 
    733                                 contentList = ((org.docx4j.wml.SdtBlock) sdt).getSdtContent() 
    734                                                 .getContent(); 
    735                         } else if (sdt instanceof org.docx4j.wml.SdtRun) { // sdt in 
    736                                                                                                                                 // paragraph 
    737                                 contentList = ((org.docx4j.wml.SdtRun) sdt).getSdtContent() 
    738                                                 .getContent(); 
    739                         } 
    740                         // An CTSdtRow or CTSdtCell shouldn't be bound 
    741                         if (contentList == null || contentList.size() == 0) { 
    742                                 List<Object> newContent = new ArrayList<Object>(); 
    743                                 newContent.add(sdt); 
    744                                 return newContent; 
    745                         } 
    746  
    747                         // Word can't handle an XPath that returns something else 
    748                         // eg string or boolean or number, so work this out. 
     721                        // Word can't handle an XPath that returns something  
     722                        // other than an element  
     723                        // eg string or boolean or number, so we'll need to work this out. 
    749724                        // In principal, we could do this in this pre-processing step, 
    750                         // or via bind.xslt. But probably slightly better to do it here. 
    751                         org.opendope.xpaths.Xpaths.Xpath xpathObj = XPathsPart 
    752                                         .getXPathById(xPaths, xp); 
    753                         String value = BindingHandler.xpathGetString(wordMLPackage, 
    754                                         customXmlDataStorageParts, xpathObj.getDataBinding() 
    755                                                         .getStoreItemID(), xpathObj.getDataBinding() 
    756                                                         .getXpath(), xpathObj.getDataBinding() 
    757                                                         .getPrefixMappings()); 
    758                         log.info(xpathObj.getDataBinding().getXpath()); 
    759  
    760                         // Now insert 
    761                         R r = null; 
    762                         Object firstBlock = contentList.get(0); 
    763                         if (firstBlock instanceof P) { 
    764                                 if (((P) firstBlock).getParagraphContent().get(0) instanceof R) { 
    765                                         r = (R) ((P) firstBlock).getParagraphContent().get(0); 
    766                                 } 
    767                         } else if (firstBlock instanceof R) { 
    768                                 r = ((R) firstBlock); 
    769                         } 
    770                         if (r == null) { 
    771                                 // Give up 
    772                                 log.warn("Couldn't find a run in which to insert xpath value"); 
    773                                 List<Object> newContent = new ArrayList<Object>(); 
    774                                 newContent.add(sdt); 
    775                                 return newContent; 
    776                         } 
    777                         Text wt = null; 
    778                         Object firstInline = XmlUtils.unwrap(r.getRunContent().get(0)); 
    779                         if (firstInline instanceof Text) { 
    780                                 wt = (Text) firstInline; 
    781                         } else { 
    782                                 log.warn("First was " + firstInline); 
    783                                 wt = Context.getWmlObjectFactory().createText(); 
    784                                 r.getRunContent().add(wt); 
    785                         } 
    786                         wt.setValue(value); 
    787                         // Return the sdt with this value set 
     725                        // or via bind.xslt.  
     726                         
     727                        // Doing it here means the bind.xslt step can be restricted to pure 
     728                        // Word-like processing. 
     729                         
     730                        // Doing it there means we can take advantage of the multiline 
     731                        // processing we have there, and less code. 
     732                        // So as from 13 Sept 2011 (what will be 2.7.1), do it there.  
     733                                                 
    788734                        List<Object> newContent = new ArrayList<Object>(); 
    789735                        newContent.add(sdt); 
  • trunk/docx4j/src/main/java/org/docx4j/model/datastorage/bind.xslt

    r1645 r1658  
    2222<xsl:param name="wmlPackage"/> <!-- select="'passed in'"-->      
    2323<xsl:param name="sourcePart"/> <!-- select="'passed in'"-->      
     24<xsl:param name="xPathsPart"/> <!-- select="'passed in'"-->      
    2425 
    2526  <xsl:template match="/ | @*|node()"> 
     
    163164                        </xsl:copy>                                      
    164165                </xsl:when> 
     166                 
     167                <xsl:when test="contains(string(w:sdtPr/w:tag/@w:val), 'od:xpath')"> 
     168                        <!--  honour extended bind (Word databinding only works when a element is returned); 
     169                                  (this used to be in OpenDoPEHandler, but moved 13 Sept 2011 for docx4j 2.7.1. 
     170                              here we support boolean, integer. What to do with node-set?? --> 
     171                        <xsl:copy> 
     172                             <xsl:apply-templates select="w:sdtPr"/> 
     173                              
     174                             <xsl:if test="w:stdEndPr"> 
     175                                <xsl:copy-of select="w:sdtEndPr"/> 
     176                        </xsl:if> 
     177                              
     178                             <w:sdtContent> 
     179                                <xsl:variable name="multiLine" select="w:sdtPr/w:text/@w:multiLine='1' or w:sdtPr/w:text/@w:multiLine='true' or w:sdtPr/w:text/@w:multiLine='yes'" />  
     180                                 
     181                                        <xsl:choose> 
     182                                                <xsl:when test="w:sdtContent/w:tbl"> 
     183                                                        <w:tbl> 
     184                                                                <xsl:copy-of select="w:sdtContent/w:tbl/w:tblPr"/> 
     185                                                                <xsl:copy-of select="w:sdtContent/w:tbl/w:tblGrid"/> 
     186                                                                <w:tr> 
     187                                                                        <xsl:copy-of select="w:sdtContent/w:tbl/w:tr/w:trPr"/> 
     188                                                                        <w:tc> 
     189                                                                                <xsl:copy-of select="w:sdtContent/w:tbl/w:tr/w:trPr/w:tc/w:tcPr"/> 
     190                                                                                <w:p> 
     191                                                                                        <xsl:copy-of select="w:sdtContent/w:tbl/w:tr/w:tc/w:p/w:pPr"/> 
     192                                                                                         
     193                                                                                        <xsl:copy-of 
     194                                                                                        select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     195                                                                                                                $wmlPackage, 
     196                                                                                                                $sourcePart, 
     197                                                                                                                $customXmlDataStorageParts, 
     198                                                                                                                $xPathsPart, 
     199                                                                                                                string(w:sdtPr/w:tag/@w:val), 
     200                                                                                                                w:sdtPr/w:rPr, 
     201                                                                                                                $multiLine )" /> 
     202                                                                                </w:p> 
     203                                                                        </w:tc> 
     204                                                                </w:tr> 
     205                                                        </w:tbl> 
     206                                                </xsl:when>                                              
     207                                                <xsl:when test="w:sdtContent/w:tr"> 
     208                                                        <w:tr> 
     209                                                                <xsl:copy-of select="w:sdtContent/w:tr/w:trPr"/> 
     210                                                                <w:tc> 
     211                                                                        <xsl:copy-of select="w:sdtContent/w:tr/w:trPr/w:tc/w:tcPr"/> 
     212                                                                        <w:p> 
     213                                                                                <xsl:copy-of select="w:sdtContent/w:tr/w:tc/w:p/w:pPr"/> 
     214                                                                                 
     215                                                                                <xsl:copy-of 
     216                                                                                select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     217                                                                                                        $wmlPackage, 
     218                                                                                                        $sourcePart, 
     219                                                                                                        $customXmlDataStorageParts, 
     220                                                                                                        $xPathsPart, 
     221                                                                                                        string(w:sdtPr/w:tag/@w:val), 
     222                                                                                                        w:sdtPr/w:rPr, 
     223                                                                                                        $multiLine )" /> 
     224                                                                        </w:p> 
     225                                                                </w:tc> 
     226                                                        </w:tr> 
     227                                                </xsl:when>                                              
     228                                                <xsl:when test="w:sdtContent/w:tc"> 
     229                                                        <w:tc> 
     230                                                                <!--  preserve existing w:tcPr --> 
     231                                                                <xsl:copy-of select="w:sdtContent/w:tc/w:tcPr"/> 
     232                                                                <w:p> 
     233                                                                        <!--  preserve existing w:pPr --> 
     234                                                                        <xsl:copy-of select="w:sdtContent/w:tc/w:p/w:pPr"/> 
     235                                                                         
     236                                                                        <!--  create runs --> 
     237                                                                        <xsl:copy-of 
     238                                                                        select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     239                                                                                                $wmlPackage, 
     240                                                                                                $sourcePart, 
     241                                                                                                $customXmlDataStorageParts, 
     242                                                                                                $xPathsPart, 
     243                                                                                                string(w:sdtPr/w:tag/@w:val), 
     244                                                                                                w:sdtPr/w:rPr, 
     245                                                                                                $multiLine )" /> 
     246                                                                </w:p> 
     247                                                        </w:tc> 
     248                                                </xsl:when>                                              
     249                                                <xsl:when test="w:sdtContent/w:p"> 
     250                                                        <w:p> 
     251                                                                <!--  preserve existing w:pPr --> 
     252                                                                <xsl:copy-of select="w:sdtContent/w:p/w:pPr"/> 
     253                                                                 
     254                                                                <!--  create runs --> 
     255                                                                <xsl:copy-of 
     256                                                                select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     257                                                                                        $wmlPackage, 
     258                                                                                        $sourcePart, 
     259                                                                                        $customXmlDataStorageParts, 
     260                                                                                        $xPathsPart, 
     261                                                                                        string(w:sdtPr/w:tag/@w:val), 
     262                                                                                        w:sdtPr/w:rPr, 
     263                                                                                        $multiLine )" /> 
     264                                                        </w:p> 
     265                                                </xsl:when> 
     266                                                <xsl:otherwise>  <!--  run level -->  
     267                                                        <!--  can we insert a fragment ie multiple runs? -->             
     268                                                        <xsl:copy-of 
     269                                                        select="java:org.docx4j.model.datastorage.BindingHandler.xpathGenerateRuns( 
     270                                                                                $wmlPackage, 
     271                                                                                $sourcePart, 
     272                                                                                $customXmlDataStorageParts, 
     273                                                                                $xPathsPart, 
     274                                                                                string(w:sdtPr/w:tag/@w:val), 
     275                                                                                w:sdtPr/w:rPr, 
     276                                                                                $multiLine )" /> 
     277                                                </xsl:otherwise>                 
     278                                        </xsl:choose>     
     279                             </w:sdtContent> 
     280                              
     281                        </xsl:copy>                                      
     282                </xsl:when> 
     283                 
     284                 
     285                 
    165286                <xsl:otherwise> <!--  no w:dataBinding, or one spec says to ignore -->                   
    166287                    <xsl:copy> 
Note: See TracChangeset for help on using the changeset viewer.