source: trunk/docx4j/src/main/java/org/docx4j/openpackaging/parts/WordprocessingML/FooterPart.java @ 1737

Revision 1737, 8.5 KB checked in by jharrop, 5 months ago (diff)

Reference  http://java.net/jira/browse/JAXB-874

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1/*
2 *  Copyright 2007-2008, Plutext Pty Ltd.
3 *   
4 *  This file is part of docx4j.
5
6    docx4j is licensed under the Apache License, Version 2.0 (the "License");
7    you may not use this file except in compliance with the License.
8
9    You may obtain a copy of the License at
10
11        http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18
19 */
20
21package org.docx4j.openpackaging.parts.WordprocessingML;
22
23
24import java.util.List;
25
26import javax.xml.bind.Binder;
27import javax.xml.bind.JAXBException;
28import javax.xml.bind.UnmarshalException;
29import javax.xml.bind.Unmarshaller;
30import javax.xml.parsers.DocumentBuilderFactory;
31import javax.xml.transform.Templates;
32import javax.xml.transform.dom.DOMResult;
33
34import org.apache.log4j.Logger;
35import org.docx4j.XmlUtils;
36import org.docx4j.jaxb.Context;
37import org.docx4j.jaxb.JaxbValidationEventHandler;
38import org.docx4j.openpackaging.exceptions.InvalidFormatException;
39import org.docx4j.openpackaging.parts.JaxbXmlPart;
40import org.docx4j.openpackaging.parts.PartName;
41import org.docx4j.openpackaging.parts.relationships.Namespaces;
42import org.docx4j.wml.ContentAccessor;
43import org.docx4j.wml.Ftr;
44import org.docx4j.wml.Hdr;
45import org.w3c.dom.Node;
46
47
48public final class FooterPart extends JaxbXmlPart<Ftr>  implements ContentAccessor {
49       
50        private static Logger log = Logger.getLogger(FooterPart.class);                 
51       
52        public FooterPart(PartName partName) throws InvalidFormatException {
53                super(partName);
54                init();
55               
56        }
57
58        public FooterPart() throws InvalidFormatException {
59                super(new PartName("/word/footer.xml"));  // Not very useful, since normally there is more than one footer part
60                init();         
61        }               
62               
63                public void init() {
64               
65                // Used if this Part is added to [Content_Types].xml
66                setContentType(new  org.docx4j.openpackaging.contenttype.ContentType( 
67                                org.docx4j.openpackaging.contenttype.ContentTypes.WORDPROCESSINGML_FOOTER));
68
69                // Used when this Part is added to a rels
70                setRelationshipType(Namespaces.FOOTER);
71        }
72       
73    /**
74     * Convenience method to getJaxbElement().getBody().getContent()
75     * @since 2.7
76     */
77    public List<Object> getContent() {
78       
79        if (this.getJaxbElement()==null) {             
80                this.setJaxbElement( Context.getWmlObjectFactory().createFtr() );
81        }
82       
83        return this.getJaxbElement().getContent();
84    }   
85               
86        private Binder<Node> binder;
87       
88       
89        /**
90         * Enables synchronization between XML infoset nodes and JAXB objects
91         * representing same XML document.
92         *
93         * An instance of this class maintains the association between XML nodes
94         * of an infoset preserving view and a JAXB representation of an XML document.
95         * Navigation between the two views is provided by the methods
96         * getXMLNode(Object) and getJAXBNode(Object) .
97         *
98         * In theory, modifications can be made to either the infoset preserving view or
99         * the JAXB representation of the document while the other view remains
100         * unmodified. The binder ought to be able to synchronize the changes made in
101         * the modified view back into the other view using the appropriate
102         * Binder update methods, #updateXML(Object, Object) or #updateJAXB(Object).
103         *
104         * But JAXB doesn't currently work as advertised .. access to this
105         * object is offered for advanced users on an experimental basis only.
106     * @since 2.7.1
107         */
108        public Binder<Node> getBinder() {
109               
110                return binder;
111        }
112       
113        /**
114         * Fetch JAXB Nodes matching an XPath (for example "//w:p").
115         *
116         * If you have modified your JAXB objects (eg added or changed a
117         * w:p paragraph), you need to update the association. The problem
118         * is that this can only be done ONCE, owing to a bug in JAXB:
119         * see https://jaxb.dev.java.net/issues/show_bug.cgi?id=459
120         *
121         * So this is left for you to choose to do via the refreshXmlFirst parameter.   
122         *
123         * @param xpathExpr
124         * @param refreshXmlFirst
125         * @return
126         * @throws JAXBException
127     * @since 2.7.1
128         */     
129        public List<Object> getJAXBNodesViaXPath(String xpathExpr, boolean refreshXmlFirst) 
130                        throws JAXBException {
131               
132                return XmlUtils.getJAXBNodesViaXPath(binder, jaxbElement, xpathExpr, refreshXmlFirst);
133        }       
134
135        /**
136         * Fetch JAXB Nodes matching an XPath (for example ".//w:p" - note the dot,
137         * which is necessary for this sort of relative path).
138         *
139         * If you have modified your JAXB objects (eg added or changed a
140         * w:p paragraph), you need to update the association. The problem
141         * is that this can only be done ONCE, owing to a bug in JAXB:
142         * see https://jaxb.dev.java.net/issues/show_bug.cgi?id=459
143         *
144         * So this is left for you to choose to do via the refreshXmlFirst parameter.   
145
146         * @param xpathExpr
147         * @param someJaxbElement
148         * @param refreshXmlFirst
149         * @return
150         * @throws JAXBException
151     * @since 2.7.1
152         */
153        public List<Object> getJAXBNodesViaXPath(String xpathExpr, Object someJaxbElement, boolean refreshXmlFirst) 
154                throws JAXBException {
155
156                return XmlUtils.getJAXBNodesViaXPath(binder, someJaxbElement, xpathExpr, refreshXmlFirst);
157        }       
158       
159       
160    /**
161     * Unmarshal XML data from the specified InputStream and return the
162     * resulting content tree.  Validation event location information may
163     * be incomplete when using this form of the unmarshal API.
164     *
165     * <p>
166     * Implements <a href="#unmarshalGlobal">Unmarshal Global Root Element</a>.
167     *
168     * @param is the InputStream to unmarshal XML data from
169     * @return the newly created root object of the java content tree
170     *
171     * @throws JAXBException
172     *     If any unexpected errors occur while unmarshalling
173     * @since 2.7.1
174     */
175        @Override
176    public Ftr unmarshal( java.io.InputStream is ) throws JAXBException {
177                try {
178                       
179                        log.info("For MDP, unmarshall via binder");
180                        // InputStream to Document
181                        javax.xml.parsers.DocumentBuilderFactory dbf
182                                = DocumentBuilderFactory.newInstance();
183                        dbf.setNamespaceAware(true);
184                        org.w3c.dom.Document doc = dbf.newDocumentBuilder().parse(is);
185
186                        //
187                        binder = jc.createBinder();
188                       
189                        JaxbValidationEventHandler eventHandler = new JaxbValidationEventHandler();
190                        eventHandler.setContinue(false);
191                        binder.setEventHandler(eventHandler);
192                       
193                        try {
194                                jaxbElement =  (Ftr) binder.unmarshal( doc );
195                        } catch (UnmarshalException ue) {
196                                log.info("encountered unexpected content; pre-processing");
197                                eventHandler.setContinue(true);
198                                DOMResult result = new DOMResult();
199                                Templates mcPreprocessorXslt = JaxbValidationEventHandler.getMcPreprocessor();
200                                XmlUtils.transform(doc, mcPreprocessorXslt, null, result);
201                                doc = (org.w3c.dom.Document)result.getNode();
202                               
203                                try {                           
204                                        jaxbElement =  (Ftr) binder.unmarshal( doc );
205                                } catch (ClassCastException cce) {
206                                        // Work around for issue with JAXB binder, in Java 1.6
207                                        // See  http://java.net/jira/browse/JAXB-874 and comments in MainDocumentPart.                                 
208                                        log.warn("Binder not available for this docx");
209                                        Unmarshaller u = jc.createUnmarshaller();
210                                        jaxbElement = (Ftr) u.unmarshal( doc );                                 
211                                }
212                        }
213                       
214                        return jaxbElement;
215                       
216                } catch (Exception e ) {
217                        e.printStackTrace();
218                        return null;
219                }
220    }
221
222    /**
223     * @since 2.7.1
224     */ 
225        @Override
226    public Ftr unmarshal(org.w3c.dom.Element el) throws JAXBException {
227
228                try {
229
230                        binder = jc.createBinder();
231                        JaxbValidationEventHandler eventHandler = new JaxbValidationEventHandler();
232                        eventHandler.setContinue(false);
233                        binder.setEventHandler(eventHandler);
234                       
235                        try {
236                                jaxbElement =  (Ftr) binder.unmarshal( el );
237                        } catch (UnmarshalException ue) {
238                                log.info("encountered unexpected content; pre-processing");
239                                try {
240                                        org.w3c.dom.Document doc;
241                                        if (el instanceof org.w3c.dom.Document) {
242                                                doc = (org.w3c.dom.Document) el;
243                                        } else {
244                                                // Hope for the best. Dodgy though; what if this is
245                                                // being used on something deep in the tree?
246                                                // TODO: revisit
247                                                doc = el.getOwnerDocument();
248                                        }
249                                        eventHandler.setContinue(true);
250                                        DOMResult result = new DOMResult();
251                                        Templates mcPreprocessorXslt = JaxbValidationEventHandler
252                                                        .getMcPreprocessor();
253                                        XmlUtils.transform(doc, mcPreprocessorXslt, null, result);
254                                        doc = (org.w3c.dom.Document) result.getNode();
255                                        jaxbElement = (Ftr) binder
256                                                        .unmarshal(doc);
257                                } catch (Exception e) {
258                                        throw new JAXBException("Preprocessing exception", e);
259                                }
260                        }
261                        return jaxbElement;
262                       
263                } catch (JAXBException e) {
264                        log.error(e);
265                        throw e;
266                }
267        }
268       
269       
270       
271}
Note: See TracBrowser for help on using the repository browser.