/** * Get the PackagePart that is the target of a relationship. * * @param rel A relationship from this part to another one * @return The target part of the relationship */ public PackagePart GetRelatedPart(PackageRelationship rel) { // Ensure this is one of ours if (!IsRelationshipExists(rel)) { throw new ArgumentException("Relationship " + rel + " doesn't start with this part " + _partName); } // Get the target URI, excluding any relative fragments Uri target = rel.TargetUri; if (target.OriginalString.IndexOf('#') >= 0) { String t = target.ToString(); try { target = PackagingUriHelper.ParseUri(t.Substring(0, t.IndexOf('#')), UriKind.Absolute); } catch (UriFormatException) { throw new InvalidFormatException("Invalid target URI: " + t); } } // Turn that into a name, and fetch PackagePartName relName = PackagingUriHelper.CreatePartName(target); PackagePart part = _container.GetPart(relName); if (part == null) { throw new ArgumentException("No part found for relationship " + rel); } return(part); }
/** * Create a new MemoryPackagePart from the specified URI and content type * * * aram partName The part URI. * * @param contentType * The part content type. * @return The newly created zip package part, else <b>null</b>. */ protected override PackagePart CreatePartImpl(PackagePartName partName, String contentType, bool loadRelationships) { if (contentType == null) { throw new ArgumentException("contentType"); } if (partName == null) { throw new ArgumentException("partName"); } try { return(new MemoryPackagePart(this, partName, contentType, loadRelationships)); } catch (InvalidFormatException) { // TODO - don't use system.err. Is it valid to return null when this exception occurs? //System.err.println(e); return(null); } }
/** * Delete a part from the package * * @throws ArgumentException * Throws if the part URI is nulll or invalid. */ protected override void RemovePartImpl(PackagePartName partName) { if (partName == null) { throw new ArgumentException("partUri"); } }
/** * Add a relationship to a part (except relationships part). * <p> * Check rule M1.25: The Relationships part shall not have relationships to * any other part. Package implementers shall enforce this requirement upon * the attempt to create such a relationship and shall treat any such * relationship as invalid. * </p> * @param targetPartName * Name of the target part. This one must be relative to the * source root directory of the part. * @param targetMode * Mode [Internal|External]. * @param relationshipType * Type of relationship. * @param id * Relationship unique id. * @return The newly created and added relationship * * @throws InvalidFormatException * If the URI point to a relationship part URI. * @see org.apache.poi.OpenXml4Net.opc.RelationshipSource#AddRelationship(org.apache.poi.OpenXml4Net.opc.PackagePartName, * org.apache.poi.OpenXml4Net.opc.TargetMode, java.lang.String, java.lang.String) */ public PackageRelationship AddRelationship(PackagePartName targetPartName, TargetMode targetMode, String relationshipType, String id) { _container.ThrowExceptionIfReadOnly(); if (targetPartName == null) { throw new ArgumentException("targetPartName"); } //if (targetMode == null) //{ // throw new ArgumentException("targetMode"); //} if (relationshipType == null) { throw new ArgumentException("relationshipType"); } if (this.IsRelationshipPart || targetPartName.IsRelationshipPartURI()) { throw new InvalidOperationException( "Rule M1.25: The Relationships part shall not have relationships to any other part."); } if (_relationships == null) { _relationships = new PackageRelationshipCollection(); } return(_relationships.AddRelationship(targetPartName.URI, targetMode, relationshipType, id)); }
/** * Implement the getPart() method to retrieve a part from its URI in the * current package * * * @see #getPart(PackageRelationship) */ protected override PackagePart GetPartImpl(PackagePartName partName) { if (partList.ContainsKey(partName)) { return(partList[partName]); } return(null); }
/** * Compare based on the package part name, using a natural sort order */ public int CompareTo(PackagePart other) { // NOTE could also throw a NullPointerException() if desired if (other == null) { return(-1); } return(PackagePartName.Compare(this._partName, other._partName)); }
/** * Get the relationship part name of the specified part. * * @param part * The part . * @return The relationship part name of the specified part. Be careful, * only the correct name is returned, this method does not check if * the part really exist in a package ! * @throws InvalidOperationException * Throws if the specified part is a relationship part. */ private static PackagePartName GetRelationshipPartName(PackagePart part) { PackagePartName partName; if (part == null) { partName = PackagingUriHelper.PACKAGE_ROOT_PART_NAME; } else { partName = part.PartName; } return(PackagingUriHelper.GetRelationshipPartName(partName)); }
/** * Constructor. * * @param pack * Parent package. * @param partName * The part name, relative to the parent Package root. * @param contentType * The content type. * @param loadRelationships * Specify if the relationships will be loaded * @throws InvalidFormatException * If the specified URI is not valid. */ protected PackagePart(OPCPackage pack, PackagePartName partName, ContentType contentType, bool loadRelationships) { this._partName = partName; this._contentType = contentType; this._container = (ZipPackage)pack; // TODO - enforcing ZipPackage here - perhaps should change constructor signature // Check if this part is a relationship part _isRelationshipPart = this._partName.IsRelationshipPartURI(); // Load relationships if any if (loadRelationships) { LoadRelationships(); } }
/* Static initialization */ static PackagingUriHelper() { RELATIONSHIP_PART_SEGMENT_NAME = "_rels"; RELATIONSHIP_PART_EXTENSION_NAME = ".rels"; FORWARD_SLASH_CHAR = '/'; FORWARD_SLASH_STRING = "/"; PACKAGE_PROPERTIES_SEGMENT_NAME = "docProps"; PACKAGE_CORE_PROPERTIES_NAME = "core.xml"; // Make Uri Uri uriPACKAGE_ROOT_URI = null; Uri uriPACKAGE_RELATIONSHIPS_ROOT_URI = null; Uri uriPACKAGE_PROPERTIES_URI = null; uriPACKAGE_ROOT_URI = ParseUri("/", UriKind.Relative); uriPACKAGE_RELATIONSHIPS_ROOT_URI = ParseUri(FORWARD_SLASH_CHAR + RELATIONSHIP_PART_SEGMENT_NAME + FORWARD_SLASH_CHAR + RELATIONSHIP_PART_EXTENSION_NAME, UriKind.Relative); packageRootUri = ParseUri("/", UriKind.Relative); uriPACKAGE_PROPERTIES_URI = ParseUri(FORWARD_SLASH_CHAR + PACKAGE_PROPERTIES_SEGMENT_NAME + FORWARD_SLASH_CHAR + PACKAGE_CORE_PROPERTIES_NAME, UriKind.Relative); PACKAGE_ROOT_URI = uriPACKAGE_ROOT_URI; PACKAGE_RELATIONSHIPS_ROOT_URI = uriPACKAGE_RELATIONSHIPS_ROOT_URI; CORE_PROPERTIES_URI = uriPACKAGE_PROPERTIES_URI; // Make part name from previous Uri PackagePartName tmpPACKAGE_ROOT_PART_NAME = null; PackagePartName tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = null; PackagePartName tmpCORE_PROPERTIES_URI = null; try { tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME = CreatePartName(PACKAGE_RELATIONSHIPS_ROOT_URI); tmpCORE_PROPERTIES_URI = CreatePartName(CORE_PROPERTIES_URI); tmpPACKAGE_ROOT_PART_NAME = new PackagePartName(PACKAGE_ROOT_URI, false); } catch (InvalidFormatException) { // Should never happen in production as all data are fixed } PACKAGE_RELATIONSHIPS_ROOT_PART_NAME = tmpPACKAGE_RELATIONSHIPS_ROOT_PART_NAME; CORE_PROPERTIES_PART_NAME = tmpCORE_PROPERTIES_URI; PACKAGE_ROOT_PART_NAME = tmpPACKAGE_ROOT_PART_NAME; }
/** * Build a part name where the relationship should be stored ((ex * /word/document.xml -> /word/_rels/document.xml.rels) * * @param partName * Source part Uri * @return the full path (as Uri) of the relation file * @throws InvalidOperationException * Throws if the specified Uri is a relationshp part. */ public static PackagePartName GetRelationshipPartName( PackagePartName partName) { if (partName == null) { throw new ArgumentException("partName"); } if (PackagingUriHelper.PACKAGE_ROOT_URI.OriginalString == partName.URI .OriginalString) { return(PackagingUriHelper.PACKAGE_RELATIONSHIPS_ROOT_PART_NAME); } if (partName.IsRelationshipPartURI()) { throw new InvalidOperationException("Can't be a relationship part"); } String fullPath = partName.URI.OriginalString; String filename = GetFilename(partName.URI); fullPath = fullPath.Substring(0, fullPath.Length - filename.Length); fullPath = Combine(fullPath, PackagingUriHelper.RELATIONSHIP_PART_SEGMENT_NAME); fullPath = Combine(fullPath, filename); fullPath = fullPath + PackagingUriHelper.RELATIONSHIP_PART_EXTENSION_NAME; PackagePartName retPartName; try { retPartName = CreatePartName(fullPath); } catch (InvalidFormatException) { // Should never happen in production as all data are fixed but in // case of return null: return(null); } return(retPartName); }
/** * Constructor. Parse the existing package relationship part if one exists. * * @param container * The parent package. * @param part * The part that own this relationships collection. If <b>null</b> * then this part is considered as the package root. * @throws InvalidFormatException * If an error occurs during the parsing of the relatinships * part fo the specified part. */ public PackageRelationshipCollection(OPCPackage container, PackagePart part) : this() { if (container == null) { throw new ArgumentException("container"); } // Check if the specified part is not a relationship part if (part != null && part.IsRelationshipPart) { throw new ArgumentException("part"); } this.container = container; this.sourcePart = part; this.partName = GetRelationshipPartName(part); if ((container.GetPackageAccess() != PackageAccess.WRITE) && container.ContainPart(this.partName)) { relationshipPart = container.GetPart(this.partName); ParseRelationshipsPart(relationshipPart); } }
/** * Retrieves the parts from this package. We assume that the package has not * been yet inspect to retrieve all the parts, this method will open the * archive and look for all parts contain inside it. If the package part * list is not empty, it will be emptied. * * @return All parts contain in this package. * @throws InvalidFormatException * Throws if the package is not valid. */ protected override PackagePart[] GetPartsImpl() { if (this.partList == null) { // The package has just been created, we create an empty part // list. this.partList = new PackagePartCollection(); } if (this.zipArchive == null) { PackagePart[] pp = new PackagePart[this.partList.Values.Count]; this.partList.Values.CopyTo(pp, 0); return(pp); } // First we need to parse the content type part IEnumerator entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = (ZipEntry)entries.Current; if (entry.Name.ToLower().Equals( ContentTypeManager.CONTENT_TYPES_PART_NAME.ToLower())) { try { this.contentTypeManager = new ZipContentTypeManager( ZipArchive.GetInputStream(entry), this); } catch (IOException e) { throw new InvalidFormatException(e.Message, e); } break; } } // At this point, we should have loaded the content type part if (this.contentTypeManager == null) { int numEntries = 0; // Is it a different Zip-based format? bool hasMimetype = false; bool hasSettingsXML = false; entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = entries.Current as ZipEntry; if (entry.Name.Equals(MIMETYPE)) { hasMimetype = true; } if (entry.Name.Equals(SETTINGS_XML)) { hasSettingsXML = true; } numEntries++; } if (hasMimetype && hasSettingsXML) { throw new ODFNotOfficeXmlFileException( "The supplied data appears to be in ODF (Open Document) Format. " + "Formats like these (eg ODS, ODP) are not supported, try Apache ODFToolkit"); } if (numEntries == 0) { throw new NotOfficeXmlFileException( "No valid entries or contents found, this is not a valid OOXML " + "(Office Open XML) file"); } // Fallback exception throw new InvalidFormatException( "Package should contain a content type part [M1.13]"); } // Now create all the relationships // (Need to create relationships before other // parts, otherwise we might create a part before // its relationship exists, and then it won't tie up) entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = (ZipEntry)entries.Current; PackagePartName partName = BuildPartName(entry); if (partName == null) { continue; } // Only proceed for Relationships at this stage String contentType = contentTypeManager.GetContentType(partName); if (contentType != null && contentType.Equals(ContentTypes.RELATIONSHIPS_PART)) { try { PackagePart part = new ZipPackagePart(this, entry, partName, contentType); partList[partName] = part; } catch (InvalidOperationException e) { throw new InvalidFormatException(e.Message, e); } } } // Then we can go through all the other parts entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = entries.Current as ZipEntry; PackagePartName partName = BuildPartName(entry); if (partName == null) { continue; } String contentType = contentTypeManager.GetContentType(partName); if (contentType != null && contentType.Equals(ContentTypes.RELATIONSHIPS_PART)) { // Already handled } else if (contentType != null) { try { PackagePart part = new ZipPackagePart(this, entry, partName, contentType); partList[partName] = part; } catch (InvalidOperationException e) { throw new InvalidFormatException(e.Message, e); } } else { throw new InvalidFormatException( "The part " + partName.URI.OriginalString + " does not have any content type ! Rule: Package require content types when retrieving a part from a package. [M.1.14]"); } } ZipPackagePart[] returnArray = new ZipPackagePart[partList.Count]; partList.Values.CopyTo(returnArray, 0); return(returnArray); }
/** * Constructor. * * @param container * The container package. * @param zipEntry * The zip entry corresponding to this part. * @param partName * The part name. * @param contentType * Content type. * @throws InvalidFormatException * Throws if the content of this part is invalid. */ public ZipPackagePart(OPCPackage container, ZipEntry zipEntry, PackagePartName partName, String contentType) : base(container, partName, contentType) { this.zipEntry = zipEntry; }
/** * Retrieves the parts from this package. We assume that the package has not * been yet inspect to retrieve all the parts, this method will open the * archive and look for all parts contain inside it. If the package part * list is not empty, it will be emptied. * * @return All parts contain in this package. * @throws InvalidFormatException * Throws if the package is not valid. */ protected override PackagePart[] GetPartsImpl() { if (this.partList == null) { // The package has just been created, we create an empty part // list. this.partList = new PackagePartCollection(); } if (this.zipArchive == null) { PackagePart[] pp = new PackagePart[this.partList.Values.Count]; this.partList.Values.CopyTo(pp, 0); return(pp); } // First we need to parse the content type part IEnumerator entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = (ZipEntry)entries.Current; if (entry.Name.Equals( ContentTypeManager.CONTENT_TYPES_PART_NAME)) { try { this.contentTypeManager = new ZipContentTypeManager( ZipArchive.GetInputStream(entry), this); } catch (IOException e) { throw new InvalidFormatException(e.Message); } break; } } // At this point, we should have loaded the content type part if (this.contentTypeManager == null) { throw new InvalidFormatException( "Package should contain a content type part [M1.13]"); } // Now create all the relationships // (Need to create relationships before other // parts, otherwise we might create a part before // its relationship exists, and then it won't tie up) entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = (ZipEntry)entries.Current; PackagePartName partName = BuildPartName(entry); if (partName == null) { continue; } // Only proceed for Relationships at this stage String contentType = contentTypeManager.GetContentType(partName); if (contentType != null && contentType.Equals(ContentTypes.RELATIONSHIPS_PART)) { try { partList[partName] = new ZipPackagePart(this, entry, partName, contentType); } catch (InvalidOperationException e) { throw new InvalidFormatException(e.Message); } } } // Then we can go through all the other parts entries = this.zipArchive.Entries; while (entries.MoveNext()) { ZipEntry entry = entries.Current as ZipEntry; PackagePartName partName = BuildPartName(entry); if (partName == null) { continue; } String contentType = contentTypeManager .GetContentType(partName); if (contentType != null && contentType.Equals(ContentTypes.RELATIONSHIPS_PART)) { // Already handled } else if (contentType != null) { try { partList[partName] = new ZipPackagePart(this, entry, partName, contentType); } catch (InvalidOperationException e) { throw new InvalidFormatException(e.Message); } } else { throw new InvalidFormatException( "The part " + partName.URI.OriginalString + " does not have any content type ! Rule: Package require content types when retrieving a part from a package. [M.1.14]"); } } ZipPackagePart[] returnArray = new ZipPackagePart[partList.Count]; partList.Values.CopyTo(returnArray, 0); return(returnArray); }
/** * Constructor. * * @param pack * Parent package. * @param partName * The part name, relative to the parent Package root. * @param contentType * The Multipurpose Internet Mail Extensions (MIME) content type * of the part's data stream. */ public PackagePart(OPCPackage pack, PackagePartName partName, String contentType) : this(pack, partName, new ContentType(contentType)) { }
/** * Add a relationship to a part (except relationships part). * * @param targetPartName * Name of the target part. This one must be relative to the * source root directory of the part. * @param targetMode * Mode [Internal|External]. * @param relationshipType * Type of relationship. * @return The newly created and added relationship * @see org.apache.poi.OpenXml4Net.opc.RelationshipSource#AddRelationship(org.apache.poi.OpenXml4Net.opc.PackagePartName, * org.apache.poi.OpenXml4Net.opc.TargetMode, java.lang.String) */ public PackageRelationship AddRelationship(PackagePartName targetPartName, TargetMode targetMode, String relationshipType) { return(AddRelationship(targetPartName, targetMode, relationshipType, null)); }
/** * Constructor. * * @param pack * Parent package. * @param partName * The part name, relative to the parent Package root. * @param contentType * The content type. * @throws InvalidFormatException * If the specified URI is not valid. */ protected PackagePart(OPCPackage pack, PackagePartName partName, ContentType contentType) : this(pack, partName, contentType, true) { }
/** * Constructor. * * @param container * The container package. * @param partName * Part name. * @param contentType * Content type. * @throws InvalidFormatException * Throws if the content of this part invalid. */ public ZipPackagePart(OPCPackage container, PackagePartName partName, String contentType) : base(container, partName, contentType) { }