source: trunk/docx4j/src/main/java/org/docx4j/openpackaging/packages/OpcPackage.java @ 1667

Revision 1667, 11.4 KB checked in by jharrop, 5 months ago (diff)

Albert Aymerich's patch to load content (docx and xml) from inputstreams.

  • Property svn:eol-style set to native
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
21
22package org.docx4j.openpackaging.packages;
23
24import java.io.BufferedInputStream;
25import java.io.FileInputStream;
26import java.io.FileNotFoundException;
27import java.io.FileOutputStream;
28import java.io.IOException;
29import java.io.InputStream;
30import java.util.HashMap;
31
32import javax.xml.bind.JAXBContext;
33import javax.xml.bind.JAXBElement;
34import javax.xml.bind.Marshaller;
35import javax.xml.bind.Unmarshaller;
36
37import org.apache.log4j.Logger;
38import org.docx4j.convert.out.flatOpcXml.FlatOpcXmlCreator;
39import org.docx4j.jaxb.Context;
40import org.docx4j.jaxb.NamespacePrefixMapperUtils;
41import org.docx4j.openpackaging.Base;
42import org.docx4j.openpackaging.contenttype.ContentTypeManager;
43import org.docx4j.openpackaging.exceptions.Docx4JException;
44import org.docx4j.openpackaging.exceptions.InvalidFormatException;
45import org.docx4j.openpackaging.io.LoadFromZipNG;
46import org.docx4j.openpackaging.io.SaveToZipFile;
47import org.docx4j.openpackaging.parts.CustomXmlDataStoragePart;
48import org.docx4j.openpackaging.parts.DocPropsCorePart;
49import org.docx4j.openpackaging.parts.DocPropsCustomPart;
50import org.docx4j.openpackaging.parts.DocPropsExtendedPart;
51import org.docx4j.openpackaging.parts.ExternalTarget;
52import org.docx4j.openpackaging.parts.Part;
53import org.docx4j.openpackaging.parts.PartName;
54import org.docx4j.openpackaging.parts.Parts;
55import org.docx4j.openpackaging.parts.relationships.Namespaces;
56
57
58/**
59 * Represent a Package as defined in the Open Packaging Specification.
60 *
61 * @author Jason Harrop
62 */
63public class OpcPackage extends Base {
64
65        private static Logger log = Logger.getLogger(OpcPackage.class);
66
67        /**
68         * This HashMap is intended to prevent loops during the loading
69         * of this package. TODO This doesn't really tell us anything that
70         * the contents of Parts couldn't also tell us (except that
71         * that doesn't contain the rels parts), so consider removing.
72         * At least replace it with a method, so this implementation
73         * detail is hidden!
74         */
75        public HashMap<String, String> handled = new HashMap<String, String>();
76       
77        /**
78         * Package parts collection.  This is a collection of _all_
79         * parts in the package (_except_ relationship parts),
80         * not just those referred to by the package-level relationships.
81         * It doesn't include external resources.
82         */
83        protected Parts parts = new Parts();
84
85        /**
86         * Retrieve the Parts object.
87         */
88        public Parts getParts() {
89
90                // Having a separate Parts object doesn't really buy
91                // us much, but live with it...
92               
93                return parts;           
94        }
95       
96        protected HashMap<ExternalTarget, Part> externalResources
97                = new HashMap<ExternalTarget, Part>();
98        public HashMap<ExternalTarget, Part> getExternalResources() {
99                return externalResources;               
100        }       
101       
102        protected HashMap<String, CustomXmlDataStoragePart> customXmlDataStorageParts
103                = new HashMap<String, CustomXmlDataStoragePart>(); // NB key is lowercase
104        public HashMap<String, CustomXmlDataStoragePart> getCustomXmlDataStorageParts() {
105                return customXmlDataStorageParts;
106        }       
107       
108        protected ContentTypeManager contentTypeManager;
109
110        public ContentTypeManager getContentTypeManager() {
111                return contentTypeManager;
112        }
113
114        public void setContentTypeManager(ContentTypeManager contentTypeManager) {
115                this.contentTypeManager = contentTypeManager;
116        }
117       
118       
119        /**
120         * Constructor.  Also creates a new content type manager
121         *
122         */
123        public OpcPackage() {
124                try {
125                        partName = new PartName("/", false);
126                       
127                        contentTypeManager = new ContentTypeManager();
128                } catch (Exception e) {
129                        log.error(e.getMessage());
130                        // TODO: handle exception
131                }
132        }
133
134        /**
135         * Constructor.
136         * 
137         * @param contentTypeManager
138         *            The content type manager to use
139         */
140        public OpcPackage(ContentTypeManager contentTypeManager) {
141                try {
142                        partName = new PartName("/", false);
143                       
144                        this.contentTypeManager = contentTypeManager;
145                } catch (Exception e) {
146                        log.error(e.getMessage());
147                        // TODO: handle exception
148                }
149        }
150       
151        public OpcPackage getPackage() {
152                return this;
153        }
154               
155       
156        protected DocPropsCorePart docPropsCorePart;
157
158        protected DocPropsExtendedPart docPropsExtendedPart;
159       
160        protected DocPropsCustomPart docPropsCustomPart;
161       
162       
163        /**
164         * Convenience method to create a WordprocessingMLPackage
165         * or PresentationMLPackage
166         * from an existing File (.docx/.docxm, .ppxtx or Flat OPC .xml).
167     *
168         * @param docxFile
169         *            The docx file
170         */     
171        public static OpcPackage load(final java.io.File docxFile) throws Docx4JException {
172               
173                try {
174                        if (docxFile.getName().endsWith(".xml")) {
175                                return OpcPackage.load(new FileInputStream(docxFile),false);
176                        }
177                        return OpcPackage.load(new FileInputStream(docxFile),true);
178                } catch (final FileNotFoundException e) {
179                        OpcPackage.log.error(e);
180                        throw new Docx4JException("Couldn't load file from " + docxFile.getAbsolutePath(), e);
181                }
182        }
183
184        /**
185         * Convenience method to create a WordprocessingMLPackage
186         * or PresentationMLPackage
187         * from an inputstream (.docx/.docxm, .ppxtx or Flat OPC .xml).
188         * It detects the convenient format inspecting two first bytes of stream (magic bytes).
189         * For office 2007 'x' formats, these two bytes are 'PK' (same as zip file) 
190     *
191         * @param inputStream
192         *            The docx file
193         */     
194        public static OpcPackage load(final InputStream inputStream) throws Docx4JException{
195                //try to detect the type of file using a bufferedinputstream
196                final BufferedInputStream bis = new BufferedInputStream(inputStream);
197                bis.mark(0);
198                final byte[] firstTwobytes=new byte[2];
199                int read=0;
200                try {
201                        read = bis.read(firstTwobytes);
202                        bis.reset();
203                } catch (final IOException e) {
204                        throw new Docx4JException("Error reading from the stream", e);
205                }
206                if (read!=2){
207                        throw new Docx4JException("Error reading from the stream (no bytes available)");
208                }
209                final boolean docxType = (firstTwobytes[0]=='P' && firstTwobytes[1]=='K');
210                return OpcPackage.load(bis,docxType);
211        }
212       
213        /**
214         * convenience method to load a word2007 document
215         * from an existing inputstream (.docx/.docxm, .ppxtx or Flat OPC .xml).
216         *
217         * @param is
218         * @param docxFormat
219         * @return
220         * @throws Docx4JException
221         */
222        public static OpcPackage load(final InputStream is, final boolean docxFormat) throws Docx4JException {
223                if (docxFormat){
224                        final LoadFromZipNG loader = new LoadFromZipNG();
225                        return loader.get(is);
226                }
227                org.docx4j.convert.in.FlatOpcXmlImporter xmlPackage;
228                try {
229                        final Unmarshaller u = Context.jcXmlPackage.createUnmarshaller();
230                        u.setEventHandler(new org.docx4j.jaxb.JaxbValidationEventHandler());
231
232                        final org.docx4j.xmlPackage.Package wmlPackageEl = (org.docx4j.xmlPackage.Package)((JAXBElement)u.unmarshal(
233                                        new javax.xml.transform.stream.StreamSource(is))).getValue();
234
235                        xmlPackage = new org.docx4j.convert.in.FlatOpcXmlImporter( wmlPackageEl);
236                } catch (final Exception e) {
237                        OpcPackage.log.error(e);
238                        throw new Docx4JException("Couldn't load xml from stream ",e);
239                }
240                return xmlPackage.get();
241        }
242
243        /**
244         * Convenience method to save a WordprocessingMLPackage
245         * or PresentationMLPackage to a File.
246     *
247         * @param docxFile
248         *            The docx file
249         */     
250        public void save(java.io.File docxFile) throws Docx4JException {
251
252                if (docxFile.getName().endsWith(".xml")) {
253                       
254                        // Create a org.docx4j.wml.Package object
255                        FlatOpcXmlCreator worker = new FlatOpcXmlCreator(this);
256                        org.docx4j.xmlPackage.Package pkg = worker.get();
257               
258                // Now marshall it
259                        JAXBContext jc = Context.jcXmlPackage;
260                        try {
261                                Marshaller marshaller=jc.createMarshaller();
262                               
263                                marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
264                                NamespacePrefixMapperUtils.setProperty(marshaller,
265                                                NamespacePrefixMapperUtils.getPrefixMapper());                 
266                               
267                                marshaller.marshal(pkg, new FileOutputStream(docxFile));
268                        } catch (Exception e) {
269                                throw new Docx4JException("Error saving Flat OPC XML", e);
270                        }       
271                        return;
272                }
273                       
274                SaveToZipFile saver = new SaveToZipFile(this);
275                saver.save(docxFile);
276        }
277       
278       
279       
280
281        @Override
282        public boolean setPartShortcut(Part part, String relationshipType) {
283                if (relationshipType.equals(Namespaces.PROPERTIES_CORE)) {
284                        docPropsCorePart = (DocPropsCorePart)part;
285                        return true;                   
286                } else if (relationshipType.equals(Namespaces.PROPERTIES_CUSTOM)) {
287                        docPropsCustomPart = (DocPropsCustomPart)part;
288                        return true;                   
289                } else if (relationshipType.equals(Namespaces.PROPERTIES_EXTENDED)) {
290                        docPropsExtendedPart = (DocPropsExtendedPart)part;
291                        return true;                   
292                } else {       
293                        return false;
294                }
295        }
296
297        public DocPropsCorePart getDocPropsCorePart() {
298//              if (docPropsCorePart==null) {
299//                      try {
300//                              docPropsCorePart = new org.docx4j.openpackaging.parts.DocPropsCorePart();
301//                              this.addTargetPart(docPropsCorePart);
302//                             
303//                              org.docx4j.docProps.core.ObjectFactory factory =
304//                                      new org.docx4j.docProps.core.ObjectFactory();                           
305//                              org.docx4j.docProps.core.CoreProperties properties = factory.createCoreProperties();
306//                              ((org.docx4j.openpackaging.parts.JaxbXmlPart)docPropsCorePart).setJaxbElement((Object)properties);
307//                              ((org.docx4j.openpackaging.parts.JaxbXmlPart)docPropsCorePart).setJAXBContext(Context.jcDocPropsCore);                                         
308//                      } catch (InvalidFormatException e) {
309//                              // TODO Auto-generated catch block
310//                              e.printStackTrace();
311//                      }                       
312//              }
313                return docPropsCorePart;
314        }
315
316        public DocPropsExtendedPart getDocPropsExtendedPart() {
317//              if (docPropsExtendedPart==null) {
318//                      try {
319//                              docPropsExtendedPart = new org.docx4j.openpackaging.parts.DocPropsExtendedPart();
320//                              this.addTargetPart(docPropsExtendedPart);
321//                             
322//                              org.docx4j.docProps.extended.ObjectFactory factory =
323//                                      new org.docx4j.docProps.extended.ObjectFactory();                               
324//                              org.docx4j.docProps.extended.Properties properties = factory.createProperties();
325//                              ((org.docx4j.openpackaging.parts.JaxbXmlPart)docPropsExtendedPart).setJaxbElement((Object)properties);
326//                              ((org.docx4j.openpackaging.parts.JaxbXmlPart)docPropsExtendedPart).setJAXBContext(Context.jcDocPropsExtended);                                                                         
327//                      } catch (InvalidFormatException e) {
328//                              // TODO Auto-generated catch block
329//                              e.printStackTrace();
330//                      }                       
331//              }
332                return docPropsExtendedPart;
333        }
334
335        /**
336         * Get DocPropsCustomPart, if any.
337         *
338         * @return
339         */
340        public DocPropsCustomPart getDocPropsCustomPart() {
341               
342//              if (docPropsCustomPart==null) {
343//                      try {
344//                              docPropsCustomPart = new org.docx4j.openpackaging.parts.DocPropsCustomPart();
345//                              this.addTargetPart(docPropsCustomPart);
346//                             
347//                              org.docx4j.docProps.custom.ObjectFactory factory =
348//                                      new org.docx4j.docProps.custom.ObjectFactory();
349//                             
350//                              org.docx4j.docProps.custom.Properties properties = factory.createProperties();
351//                              ((org.docx4j.openpackaging.parts.JaxbXmlPart)docPropsCustomPart).setJaxbElement((Object)properties);
352//
353//                              ((org.docx4j.openpackaging.parts.JaxbXmlPart)docPropsCustomPart).setJAXBContext(Context.jcDocPropsCustom);                                                                             
354//                             
355//                      } catch (InvalidFormatException e) {
356//                              // TODO Auto-generated catch block
357//                              e.printStackTrace();
358//                      }                       
359//              }
360               
361                return docPropsCustomPart;
362        }
363
364
365
366
367}
Note: See TracBrowser for help on using the repository browser.