Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   *  Copyright 2007-2009, Plutext Pty Ltd.
   *   
   *  This file is part of docx4j.
  
      docx4j is licensed under the Apache License, Version 2.0 (the "License"); 
      you may not use this file except in compliance with the License. 
  
      You may obtain a copy of the License at 
 
         http://www.apache.org/licenses/LICENSE-2.0 
 
     Unless required by applicable law or agreed to in writing, software 
     distributed under the License is distributed on an "AS IS" BASIS, 
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
     See the License for the specific language governing permissions and 
     limitations under the License.
 
  */
 
 package org.docx4j.openpackaging.io;
 
 
 
 import java.io.File;
 import java.net.URI;
 
 
Create a Package object from a Zip file or input stream. This class is a refactoring of LoadFromZipFile, which couldn't read from an input stream

Author(s):
jharrop
 
 public class LoadFromZipNG extends Load {
 	
 	//public HashMap<String, ByteArray> partByteArrays = new HashMap<String, ByteArray>();	
 	
 	private static Logger log = LoggerFactory.getLogger(LoadFromZipNG.class);
 
 	// Testing
 	public static void main(String[] argsthrows Exception {
 		String filepath = System.getProperty("user.dir") + "/sample-docs/FontEmbedded.docx";
 		.info("Path: " + filepath );
 		LoadFromZipNG loader = new LoadFromZipNG();
 		loader.get(filepath);		
	}
	 // HashMap containing the names of all the zip entries,
	// so we can tell whether there are any orphans
//	public HashMap unusedZipEntries = new HashMap();
	public LoadFromZipNG() {
//		this(new ContentTypeManager() );
	}
//	public LoadFromZipNG(ContentTypeManager ctm) {
//		this.ctm = ctm;
//	}
	public OpcPackage get(String filepaththrows Docx4JException {
		return get(new File(filepath));
	}
	public static byte[] getBytesFromInputStream(InputStream is)
		throws Exception {
		int c = bufIn.read();
		while (c != -1) {
			bos.write(c);
			c = bufIn.read();
		}
		bos.flush();
		baos.flush();		
		//bufIn.close(); //don't do that, since it closes the ZipInputStream after we've read an entry!
		bos.close();
		return baos.toByteArray();
	public OpcPackage get(File fthrows Docx4JException {
		.info("Filepath = " + f.getPath() );
		ZipFile zf = null;
		try {
			if (!f.exists()) {
				.info"Couldn't find " + f.getPath() );
			}
			zf = new ZipFile(f);
catch (IOException ioe) {
			throw new Docx4JException("Couldn't get ZipFile"ioe);
		}
		HashMap<StringByteArraypartByteArrays = new HashMap<StringByteArray>();
		Enumeration entries = zf.entries();
		while (entries.hasMoreElements()) {
			ZipEntry entry = (ZipEntryentries.nextElement();
			.info"\n\n" + entry.getName() + "\n" );
			InputStream in = null;
			try {			
				byte[] bytes =  getBytesFromInputStreamzf.getInputStream(entry) );
				partByteArrays.put(entry.getName(), new ByteArray(bytes) );
catch (Exception e) {
			}	
		}
		 // At this point, we've finished with the zip file
		 try {
			 zf.close();
		 } catch (IOException exc) {
		 }
		 
		return process(partByteArrays);
	}
	public OpcPackage get(InputStream isthrows Docx4JException {
		HashMap<StringByteArraypartByteArrays = new HashMap<StringByteArray>();	
       try {
            ZipInputStream zis = new ZipInputStream(is);
            ZipEntry entry = null;
            while ((entry = zis.getNextEntry()) != null) {
				byte[] bytes =  getBytesFromInputStreamzis );
				//log.debug("Extracting " + entry.getName());
				partByteArrays.put(entry.getName(), new ByteArray(bytes) );
            }
            zis.close();
        } catch (Exception e) {
            .error(e.getMessage());
            throw new Docx4JException("Error processing zip file (is it a zip file?)"e);
        }	
	            
		// At this point, we're finished with the zip input stream
        // TODO, so many of the below methods could be renamed.
        // If performance is ok, LoadFromJCR could be refactored to
        // work the same way
		return process(partByteArrays);
	}
	private OpcPackage process(HashMap<StringByteArraypartByteArraysthrows Docx4JException {
		long startTime = System.currentTimeMillis();				
		// 2. Create a new Package
		//		Eventually, you'll also be able to create an Excel package etc
		//		but only the WordML package exists at present
		try {
			InputStream is = getInputStreamFromZippedPartpartByteArrays,  "[Content_Types].xml");		
catch (IOException e) {
			throw new Docx4JException("Couldn't get [Content_Types].xml from ZipFile"e);
catch (NullPointerException e) {
			throw new Docx4JException("Couldn't get [Content_Types].xml from ZipFile"e);
		}
		// .. now find the name of the main part
		String partName = "_rels/.rels";
		RelationshipsPart rp = getRelationshipsPartFromZip(nullpartByteArrayspartName);
		if (rp==null) {
			throw new Docx4JException("_rels/.rels appears to be missing from this package!");
		}
		String mainPartName = PackageRelsUtil.getNameOfMainPart(rp);
		String pkgContentType = ctm.getContentType(new PartName("/" + mainPartName));
		// 2. Create a new Package; this'll return the appropriate subclass
		OpcPackage p = ctm.createPackage(pkgContentType);
		.info("Instantiated package of type " + p.getClass().getName() );
		rp.setSourceP(p); //
		// 5. Now recursively 
//		(i) create new Parts for each thing listed
//		in the relationships
//		(ii) add the new Part to the package
//		(iii) cross the PartName off unusedZipEntries
		addPartsFromRelationships(partByteArraysprpctm );
		// 6. Check unusedZipEntries is empty
//		if (log.isDebugEnabled()) {
//			 Iterator myVeryOwnIterator = unusedZipEntries.keySet().iterator();
//			 while(myVeryOwnIterator.hasNext()) {
//			     String key = (String)myVeryOwnIterator.next();
//			     log.info( key + "  " + unusedZipEntries.get(key));
//			 }
//		}
		 
		long endTime = System.currentTimeMillis();				
		.info("package read;  elapsed time: " + Math.round((endTime-startTime)) + " ms" );
		 return p;
	}
	//private RelationshipsPart getRelationshipsPartFromZip(Base p, ZipFile zf, String partName) 
	private RelationshipsPart getRelationshipsPartFromZip(Base pHashMap<StringByteArraypartByteArraysString partName
			throws Docx4JException {
//			Document contents = null;
//			try {
//				contents = getDocumentFromZippedPart( zf,  partName);
//			} catch (Exception e) {
//				e.printStackTrace();
//				throw new Docx4JException("Error getting document from Zipped Part", e);
//				
//			} 
//		// debugPrint(contents);
//		// TODO - why don't any of the part names in this document start with "/"?
//		return new RelationshipsPart( p, new PartName("/" + partName), contents );	
		RelationshipsPart rp = null;
		InputStream is = null;
		try {
			is =  getInputStreamFromZippedPartpartByteArrays,  partName);
			//thePart = new RelationshipsPart( p, new PartName("/" + partName), is );
			rp = new RelationshipsPart(new PartName("/" + partName) );
			rp.unmarshal(is);
catch (Exception e) {
			throw new Docx4JException("Error getting document from Zipped Part:" + partNamee);
finally {
			if (is != null) {
				try {
					is.close();
catch (IOException exc) {
				}
			}
		}
		return rp;
	// debugPrint(contents);
	// TODO - why don't any of the part names in this document start with "/"?
	}
	private static InputStream getInputStreamFromZippedPart(HashMap<StringByteArraypartByteArrays,
			String partNamethrows IOException {
        ByteArray bytes = partByteArrays.get(partName);
        if (bytes == nullthrow new IOException("part '" + partName + "' not found");
		return bytes.getInputStream();
	}
	/* recursively 
	(i) create new Parts for each thing listed
	in the relationships
	(ii) add the new Part to the package
	(iii) cross the PartName off unusedZipEntries
	*/
	//private void addPartsFromRelationships(ZipFile zf, Base source, RelationshipsPart rp)
	private void addPartsFromRelationships(HashMap<StringByteArraypartByteArrays
		throws Docx4JException {
		OpcPackage pkg = source.getPackage();				
//		for (Iterator it = rp.iterator(); it.hasNext(); ) {
//			Relationship r = (Relationship)it.next();
//			log.info("For Relationship Id=" + r.getId() + " Source is " 
//					+ r.getSource().getPartName() 
//					+ ", Target is " + r.getTargetURI() );
//			try {
//				
//				getPart(zf, pkg, rp, r);
//				
//			} catch (Exception e) {
//				throw new Docx4JException("Failed to add parts from relationships", e);
//			}
//		}
		for ( Relationship r : rp.getRelationships().getRelationship() ) {
			.debug("\n For Relationship Id=" + r.getId() 
" Source is " + rp.getSourceP().getPartName() 
", Target is " + r.getTarget()
", type: " + r.getType() );
				// This is usually the first logged comment for
				// a part, so start with a line break.
			try {				
				getPart(partByteArrayspkgrprctm);
catch (Exception e) {
				throw new Docx4JException("Failed to add parts from relationships"e);
			}
		}
	}

Get a Part (except a relationships part), and all its related parts. This can be called directly from outside the library, in which case the Part will not be owned by a Package until the calling code makes it so.

	//private void getPart(ZipFile zf, Package pkg, RelationshipsPart rp, Relationship r)
	private void getPart(HashMap<StringByteArraypartByteArraysOpcPackage pkgRelationshipsPart rp
		Base source = null;
		String resolvedPartUri = null;
			// Could be Internal or External
			// Example of Internal is w:drawing/wp:inline/wp:docPr/a:hlinkClick
			.info("Encountered (but not loading) hyperlink " + r.getTarget()  );				
			return;			
else 
			if (r.getTargetMode() == null
				|| !r.getTargetMode().equals("External") ) {
			// Usual case
			source = rp.getSourceP();
			resolvedPartUri = URIHelper.resolvePartUri(rp.getSourceURI(), new URI(r.getTarget() ) ).toString();		
			// Now drop leading "/'
			resolvedPartUri = resolvedPartUri.substring(1);				
			// Now normalise it .. ie abc/def/../ghi
			// becomes abc/ghi
			// Maybe this isn't necessary with a zip file,
			// - ZipFile class may be smart enough to do it.
			// But it is certainly necessary in the JCR case.
//			resolvedPartUri = (new java.net.URI(resolvedPartUri)).normalize().toString();
//			log.info("Normalised, it is " + resolvedPartUri );				
else {			
			// EXTERNAL			
					// It could instead be, for example, of type hyperlink,
					// and we don't want to try to fetch that
				.info("Loading external resource " + r.getTarget() 
						   + " of type " + r.getType() );
				BinaryPart bp = ExternalResourceUtils.getExternalResource(r.getTarget());
else {				
				.info("Encountered (but not loading) external resource " + r.getTarget() 
						   + " of type " + r.getType() );				
			}						
			return;
		}
		String relationshipType = r.getType();		
		Part part;
		if (pkg.handled.get(resolvedPartUri)!=null) {
			// The source Part (or Package) might have a convenience
			// method for this
			part = pkg.getParts().getParts().get(new PartName("/" + resolvedPartUri));
			if (source.setPartShortcut(partrelationshipType ) ) {
				.debug("Convenience method established from " + source.getPartName() 
" to " + part.getPartName());
			}			
			return;
		}
		part = getRawPart(partByteArraysctmresolvedPartUrir); // will throw exception if null
		// The source Part (or Package) might have a convenience
		// method for this
		if (source.setPartShortcut(partrelationshipType ) ) {
			.debug("Convenience method established from " + source.getPartName() 
" to " + part.getPartName());
		}
		if (part instanceof BinaryPart
				|| part instanceof DefaultXmlPart) {
			// The constructors of other parts should take care of this...
			part.setRelationshipType(relationshipType);
		}
		rp.loadPart(partr);
		pkg.handled.put(resolvedPartUriresolvedPartUri);
//		unusedZipEntries.put(resolvedPartUri, new Boolean(false));
		RelationshipsPart rrp = getRelationshipsPart(partByteArrayspart);
		if (rrp!=null) {
			// recurse via this parts relationships, if it has any
			addPartsFromRelationships(partByteArrayspartrrpctm );
			String relPart = PartName.getRelationshipsPartName(
//			unusedZipEntries.put(relPart, new Boolean(false));					
		}
	}

Get the Relationships Part (if there is one) for a given Part. Otherwise return null.

	//public RelationshipsPart getRelationshipsPart(ZipFile zf, Part part)
			Part part)
		RelationshipsPart rrp = null;
		// recurse via this parts relationships, if it has any
		//String relPart = PartName.getRelationshipsPartName(target);
		String relPart = PartName.getRelationshipsPartName(
		if (partByteArrays.get(relPart) !=null ) {
			.debug("Found relationships " + relPart );
			rrp = getRelationshipsPartFromZip(part,  partByteArrays,  relPart);
else {
			.debug("No relationships " + relPart );	
			return null;
		}
		return rrp;
	}



Get a Part (except a relationships part), but not its relationships part or related parts. Useful if you need quick access to just this part. This can be called directly from outside the library, in which case the Part will not be owned by a Package until the calling code makes it so.

Parameters:
partByteArrays
ctm
resolvedPartUri
rel
Returns:
Throws:
org.docx4j.openpackaging.exceptions.Docx4JException including if result is null
See also:
To get a Part and all its related parts, and add all to a package, use getPart.
	public static Part getRawPart(HashMap<StringByteArraypartByteArrays,
			ContentTypeManager ctmString resolvedPartUriRelationship rel)	
			throws Docx4JException {
		Part part = null;
		InputStream is = null;
		try {
			try {
				.debug("resolved uri: " + resolvedPartUri);
				is = getInputStreamFromZippedPartpartByteArrays,  resolvedPartUri);
				// Get a subclass of Part appropriate for this content type	
				// This will throw UnrecognisedPartException in the absence of
				// specific knowledge. Hence it is important to get the is
				// first, as we do above.
				part = ctm.getPart("/" + resolvedPartUrirel);				
				.info("ctm returned " + part.getClass().getName() );
				if (part instanceof org.docx4j.openpackaging.parts.ThemePart) {
else if (part instanceof org.docx4j.openpackaging.parts.DocPropsCorePart ) {
else if (part instanceof org.docx4j.openpackaging.parts.DocPropsCustomPart ) {
else if (part instanceof org.docx4j.openpackaging.parts.DocPropsExtendedPart ) {
else if (part instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePropertiesPart ) {
else if (part instanceof org.docx4j.openpackaging.parts.digitalsignature.XmlSignaturePart ) {
else if (part instanceof org.docx4j.openpackaging.parts.JaxbXmlPart) {
					// MainDocument part, Styles part, Font part etc
					//((org.docx4j.openpackaging.parts.JaxbXmlPart)part).setJAXBContext(Context.jc);
else if (part instanceof org.docx4j.openpackaging.parts.WordprocessingML.BinaryPart) {
					.debug("Detected BinaryPart " + part.getClass().getName() );
else if (part instanceof org.docx4j.openpackaging.parts.CustomXmlDataStoragePart ) {
					// Is it a part we know?
					try {
						Object o = u.unmarshalis );						
						PartName name = part.getPartName();
						if (o instanceof CoverPageProperties) {
							part = new DocPropsCoverPagePart(name);							
else if (o instanceof org.opendope.conditions.Conditions) {
							part = new ConditionsPart(name);
else if (o instanceof org.opendope.xpaths.Xpaths) {
							part = new XPathsPart(name);
else if (o instanceof org.opendope.questions.Questionnaire) {
							part = new QuestionsPart(name);
else if (o instanceof org.opendope.answers.Answers) {
							part = new StandardisedAnswersPart(name);
else if (o instanceof org.opendope.components.Components) {
							part = new ComponentsPart(name);
else if (o instanceof JAXBElement<?> 
								&& XmlUtils.unwrap(oinstanceof org.docx4j.bibliography.CTSources) {
							part = new BibliographyPart(name);
else {
							.error("TODO: handle known CustomXmlPart part  " + o.getClass().getName());
							is.reset();
							data.setDocument(is); // Not necessarily JAXB, that's just our method name
						}
catch (javax.xml.bind.UnmarshalException ue) {
						.warn("No JAXB model for this CustomXmlDataStorage part; " + ue.getMessage()  );
						is.reset();
						data.setDocument(is); // Not necessarily JAXB, that's just our method name
					}					
else if (part instanceof org.docx4j.openpackaging.parts.XmlPart ) {
//					try {
						((XmlPart)part).setDocument(is);
					// Experimental 22/6/2011; don't fall back to binary (which we used to) 
//					} catch (Docx4JException d) {
//						// This isn't an XML part after all,
//						// even though ContentTypeManager detected it as such
//						// So get it as a binary part
//						part = getBinaryPart(partByteArrays, ctm, resolvedPartUri);
//						log.warn("Could not parse as XML, so using BinaryPart for " 
//								+ resolvedPartUri);						
//						((BinaryPart)part).setBinaryData(is);
//					}
else {
					// Shouldn't happen, since ContentTypeManagerImpl should
					// return an instance of one of the above, or throw an
					// Exception.
					.error("No suitable part found for: " + resolvedPartUri);
					part = null;					
				}
catch (PartUnrecognisedException e) {
				.error("PartUnrecognisedException shouldn't happen anymore!"e);
				// Try to get it as a binary part
				part = getBinaryPart(partByteArraysctmresolvedPartUri);
				.warn("Using BinaryPart for " + resolvedPartUri);
			}
catch (Exception ex) {
			// IOException, URISyntaxException
			throw new Docx4JException("Failed to getPart"ex);			
finally {
			if (is != null) {
				try {
					is.close();
catch (IOException exc) {
				}
			}
		}
        if (part == null) {
            throw new Docx4JException("cannot find part " + resolvedPartUri + " from rel "rel.getId() + "=" + rel.getTarget());
        }
		return part;
	}
	//public static Part getBinaryPart(ZipFile zf, ContentTypeManager ctm, String resolvedPartUri)
	public static Part getBinaryPart(HashMap<StringByteArraypartByteArrays
			ContentTypeManager ctmString resolvedPartUri)	
			throws Docx4JException {
		Part part = null;
		InputStream in = null;					
		try {			
			//in = zf.getInputStream( zf.getEntry(resolvedPartUri ) );
			in = partByteArrays.get(resolvedPartUri).getInputStream();
			part = new BinaryPartnew PartName("/" + resolvedPartUri));
			// Set content type
							ctm.getContentType(new PartName("/" + resolvedPartUri)) ) );
			.info("Stored as BinaryData" );
catch (Exception ioe) {
finally {
			if (in != null) {
				try {
					in.close();
catch (IOException exc) {
				}
			}
		}
		return part;
	}	
	public static class ByteArray implements Serializable {
		private static final long serialVersionUID = -784146312250361899L;
		// 4469266984448028582L; 
		private byte[] bytes;
		public byte[] getBytes() {
			return ;
		}
		private String mimetype;
		public String getMimetype() {
			return ;			
		}
		public ByteArray(byte[] bytes) {
			this. = bytes;
			//log.info("Added " + bytes.length  );
		}
		public ByteArray(ByteBuffer bbString mimetype ) {
			bb.clear();
			 = new byte[bb.capacity()];
			bb.get(, 0, .);
			this. = mimetype;
		}
		}
		public int getLength() {
			return .;			
		}
	}
New to GrepCode? Check out our FAQ X