source: trunk/docx4j/src/main/java/org/docx4j/openpackaging/parts/Part.java @ 1670

Revision 1670, 6.8 KB checked in by jharrop, 8 months ago (diff)

List<Relationship> sourceRelationships

  • 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.parts;
23
24import java.net.URI;
25import java.util.ArrayList;
26import java.util.List;
27
28import org.docx4j.openpackaging.Base;
29import org.docx4j.openpackaging.contenttype.ContentType;
30import org.docx4j.openpackaging.exceptions.Docx4JException;
31import org.docx4j.openpackaging.exceptions.InvalidFormatException;
32import org.docx4j.openpackaging.packages.OpcPackage;
33import org.docx4j.openpackaging.parts.relationships.RelationshipsPart;
34import org.docx4j.relationships.Relationship;
35
36import org.apache.log4j.Logger;
37
38
39/**
40 * An abstraction of an Open Packaging Convention (OPC) Part.
41 *
42 * OPC Parts are either XML, or binary (or text) documents.
43 *
44 * Most are XML documents.
45 * 
46 * docx4j aims to represent XML parts using JAXB.  We have
47 * JAXB representations for all the common parts.
48 *
49 * To instantiate a Part use (or create) an appropriate subclass.
50 * When an existing document is being loaded, ContentTypeManager.getPart
51 * will instantiate the appropriate subclass.
52 */
53public abstract class Part extends Base {
54       
55        /**
56         * Logger.
57         */
58        protected static Logger log = Logger.getLogger(Part.class);
59
60       
61        protected OpcPackage pack;
62       
63        private List<Relationship> sourceRelationships = new ArrayList<Relationship>();
64
65    /**
66     * @since 2.7.1
67     */
68        public List<Relationship> getSourceRelationships() {
69                return sourceRelationships;
70        }
71       
72        /**
73         * @return the sourceRelationship
74         */
75        @Deprecated
76        public Relationship getSourceRelationship() {
77                return sourceRelationships.get(0);
78        }
79        /**
80         * NB a media part could be referenced from multiple
81         * source parts, but this method can only record one!
82         *
83         * @param sourceRelationship the sourceRelationship to set
84         */
85        @Deprecated
86        public void setSourceRelationship(Relationship sourceRelationship) {
87                sourceRelationships.clear();
88                sourceRelationships.add(sourceRelationship);
89        }
90       
91        /** The Namespace of this Part. 
92         *  Used when adding the Part to a relationship Part.
93         *  TODO: set this when the Part is constructed.
94         */
95        private String relationshipType;
96        public String getRelationshipType() {
97                if (relationshipType == null ) {
98                        // 20091029, since we now have sourceRelationship,
99                        // there is little point in also have relationshipType,
100                        // except for a part which isn't yet connected to
101                        // a package via a relationship.
102                        return this.sourceRelationships.get(0).getType();
103                        // It ought to be the same in each source rel
104                } else {
105                        return relationshipType;
106                }
107        }
108        public void setRelationshipType(String relationshipType) {
109                this.relationshipType = relationshipType;
110        }
111       
112       
113        /** Every part is the target of some relationship,
114         * specified in a RelationshipsPart. Every part can also
115         * have its own RelationshipsPart - for that, see Base
116         * (since Package has one as well).
117         */
118        private RelationshipsPart owningRelationshipPart;
119       
120        // TODO, instead of Part.getOwningRelationshipPart(),
121        // it would be better to have getOwningRelationship(),
122        // and if required, to get OwningRelationshipPart from that
123
124               
125        public RelationshipsPart getOwningRelationshipPart() {
126                return owningRelationshipPart;
127        }
128
129        public void setOwningRelationshipPart(
130                        RelationshipsPart owningRelationshipPart) {
131                this.owningRelationshipPart = owningRelationshipPart;
132        }
133       
134        public Part() {
135               
136        }
137
138        /**
139         * Constructor.
140         *
141         * @param pack
142         *            Parent package.
143         * @param partName
144         *            The part name, relative to the parent Package root.
145         * @throws InvalidFormatException
146         *             If the specified URI is not valid.
147         */
148        public Part(PartName partName)
149                        throws InvalidFormatException {
150                log.info( partName.getName() );
151                this.partName = partName;
152        }
153       
154
155       
156        /**
157         * Constructor.
158         *
159         * @param pack
160         *            Parent package.
161         * @param partName
162         *            The part name, relative to the parent Package root.
163         * @param contentType
164         *            The Multipurpose Internet Mail Extensions (MIME) content type
165         *            of the part's data stream.
166         */
167        public Part(PartName partName,
168                        String contentType) throws InvalidFormatException {
169                this(partName);
170                this.contentType = new ContentType(contentType);
171        }
172               
173       
174        public OpcPackage getPackage() {
175                if (pack==null) {
176                        log.error("Package field null for this Part " + this.getClass().getName() );
177                }
178                return pack;
179        }
180       
181        // TODO - this is not always set ...
182        // think through whether, and if so
183        // where and how it should be set
184        public void setPackage( OpcPackage pack) {
185                log.debug("setPackage called for " + this.getClass().getName() );
186                this.pack = pack;
187        }
188
189
190        @Override
191        public boolean setPartShortcut(Part part, String relationshipType) {
192                return false;
193        }
194
195        // The version of this part.
196        // Useful for some applications, particularly where unzipped parts
197        // are stored in a document management system.
198        // This field is available for the use of client applications as
199        // they see fit.
200        private long version;
201        public void setVersion(long version) {
202                this.version = version;
203        }
204        public long getVersion() {             
205                return version;
206        }
207       
208       
209        /**
210         * Rename this part.  Useful when merging documents, if you need to
211         * take action to avoid name collisions.
212         *
213         * @param newName
214         */
215        public void setPartName(PartName newName) {
216               
217                log.info("Renaming part " + this.getPartName().getName() + " to " + newName.getName() );
218               
219                // Remove this part
220                this.getPackage().getParts().remove(this.getPartName() );
221               
222                // Update the source relationship
223                // Work out new target
224                URI tobeRelativized = newName.getURI();
225                URI relativizeAgainst = this.getOwningRelationshipPart().getSourceURI();
226                log.debug("Relativising target " + tobeRelativized
227                                + " against source " + relativizeAgainst);
228                String result = org.docx4j.openpackaging.URIHelper.relativizeURI(relativizeAgainst, tobeRelativized).toString(); 
229                if (relativizeAgainst.getPath().equals("/")
230                                && result.startsWith("/")) {
231                        result = result.substring(1);
232                }
233                log.debug("Result " + result);
234                for (Relationship rel : sourceRelationships) {
235                        rel.setTarget(result);
236                }
237
238                // Set the new part name
239                this.partName = newName;
240               
241                // Add this part back to the parts collection
242                this.getPackage().getParts().put(this);
243        }
244
245    public abstract boolean isContentEqual(Part other) throws Docx4JException;
246
247}
Note: See TracBrowser for help on using the repository browser.