KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > it > stefanochizzolini > clown > objects > PdfIndirectObject


1 /*
2   Copyright 2006 Stefano Chizzolini. http://clown.stefanochizzolini.it
3
4   Contributors:
5     * Stefano Chizzolini (original code developer, info@stefanochizzolini.it):
6       contributed code is Copyright 2006 by Stefano Chizzolini.
7
8   This file should be part of the source code distribution of "PDF Clown library"
9   (the Program): see the accompanying README files for more info.
10
11   This Program is free software; you can redistribute it and/or modify it under
12   the terms of the GNU General Public License as published by the Free Software
13   Foundation; either version 2 of the License, or (at your option) any later version.
14
15   This Program is distributed in the hope that it will be useful, but WITHOUT ANY
16   WARRANTY, either expressed or implied; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more details.
18
19   You should have received a copy of the GNU General Public License along with this
20   Program (see README files); if not, go to the GNU website (http://www.gnu.org/).
21
22   Redistribution and use, with or without modification, are permitted provided that such
23   redistributions retain the above copyright notice, license and disclaimer, along with
24   this list of conditions.
25 */

26
27 package it.stefanochizzolini.clown.objects;
28
29 import it.stefanochizzolini.clown.bytes.IOutputStream;
30 import it.stefanochizzolini.clown.files.File;
31 import it.stefanochizzolini.clown.tokens.Parser;
32 import it.stefanochizzolini.clown.tokens.XRefEntry;
33 import it.stefanochizzolini.clown.tokens.XRefEntryUsageEnum;
34
35 /**
36   PDF indirect object.
37 */

38 public class PdfIndirectObject
39   extends PdfObject
40   implements IPdfIndirectObject
41 {
42   // <class>
43
// <static>
44
// <fields>
45
private final String JavaDoc UsageFree = "f";
46   private final String JavaDoc UsageInUse = "n";
47   // </fields>
48
// </static>
49

50   // <dynamic>
51
// <fields>
52
private PdfDataObject dataObject;
53   private File file;
54   private boolean original;
55   private PdfReference reference;
56   private XRefEntry xrefEntry;
57   // </fields>
58

59   // <constructors>
60
/**
61     <h3>Remarks</h3>
62     <p>For internal use only.</p>
63     @param file Associated file.
64     @param dataObject Data object associated to the indirect object.
65       It MUST be null if the indirect object is original (i.e. coming from an existing file) or
66       free.
67       It MUST be NOT null if the indirect object is new and in-use.
68     @param xrefEntry Cross-reference entry associated to the indirect object.
69       If the indirect object is new, its offset field MUST be set to 0 (zero).
70   */

71   public PdfIndirectObject(
72     File file,
73     PdfDataObject dataObject,
74     XRefEntry xrefEntry
75     )
76   {
77     this.file = file;
78     this.dataObject = dataObject;
79     this.xrefEntry = xrefEntry;
80
81     this.original = (xrefEntry.getOffset() != 0);
82     this.reference = new PdfReference(
83       this,
84       xrefEntry.getNumber(),
85       xrefEntry.getGeneration()
86       );
87   }
88   // </constructors>
89

90   // <interface>
91
// <public>
92
public File getFile(
93     )
94   {return file;}
95
96   @Override JavaDoc
97   public int hashCode(
98     )
99   {
100     /*
101       NOTE: Uniqueness should be achieved XORring the (local) reference hashcode
102       with the (global) file hashcode.
103       NOTE: DO NOT directly invoke reference.hashCode() method here as
104       it would trigger an infinite loop, as it conversely relies on this method.
105     */

106     return reference.getID().hashCode() ^ file.hashCode();
107   }
108
109   public boolean isInUse(
110     )
111   {return (xrefEntry.getUsage() == XRefEntryUsageEnum.InUse);}
112
113   public boolean isOriginal(
114     )
115   {return original;}
116
117   public void update(
118     )
119   {
120     if(original)
121     {
122       /*
123         NOTE: It's expected that dropOriginal() is invoked by IndirectObjects set() method;
124         such an action is delegated because clients may invoke directly set() method, skipping
125         this method.
126       */

127       file.getIndirectObjects().update(this);
128     }
129   }
130
131   // <IPdfIndirectObject>
132
@Override JavaDoc
133   public Object JavaDoc clone(
134     File context
135     )
136   {return context.getIndirectObjects().addExternal(this);}
137
138   public void delete(
139     )
140   {
141     if(file != null)
142     {
143       /*
144         NOTE: It's expected that dropFile() is invoked by IndirectObjects remove() method;
145         such an action is delegated because clients may invoke directly remove() method, skipping
146         this method.
147       */

148       file.getIndirectObjects().remove(xrefEntry.getNumber());
149     }
150   }
151
152   public PdfDataObject getDataObject(
153     )
154   {
155     if(dataObject == null)
156     {
157       /*
158         NOTE: indirect data object is null in 2 cases:
159         1) when the entry is free (no data object at all);
160         2) when the indirect object hasn't been initialized yet
161           because it comes from a parsed reference (late-bound data object).
162         In case 1 data object MUST keep itself null,
163         while in case 2 data object MUST be initialized.
164       */

165
166       // Is the entry free [case 1]?
167
// NOTE: Free entries have NO indirect data object associated with.
168
if(xrefEntry.getUsage() == XRefEntryUsageEnum.Free)
169         return null;
170
171       // In-use entry (late-bound data object [case 2]).
172
try
173       {
174         Parser parser = file.getReader().getParser();
175         // Retrieve the associated data object among the original objects!
176
parser.seek(xrefEntry.getOffset());
177         // Skip indirect-object header!
178
parser.moveNext(4);
179         // Get the indirect data object!
180
dataObject = parser.parsePdfObject();
181       }
182       catch(Exception JavaDoc e)
183       {throw new RuntimeException JavaDoc(e);}
184     }
185
186     return dataObject;
187   }
188
189   public PdfIndirectObject getIndirectObject(
190     )
191   {return this;}
192
193   public PdfReference getReference(
194     )
195   {return reference;}
196   // </IPdfIndirectObject>
197
// </public>
198

199   // <internal>
200
/**
201     <h3>Remarks</h3>
202     <p>For internal use only.</p>
203   */

204   public void dropFile(
205     )
206   {file = null;}
207
208   /**
209     <h3>Remarks</h3>
210     <p>For internal use only.</p>
211   */

212   public void dropOriginal(
213     )
214   {original = false;}
215
216   String JavaDoc getUsage(
217     )
218   {
219     switch(xrefEntry.getUsage())
220     {
221       case Free:
222         return UsageFree;
223       case InUse:
224         return UsageInUse;
225       default: // Should NEVER happen.
226
throw new RuntimeException JavaDoc("Invalid xref usage value.");
227     }
228   }
229
230   /**
231     <h3>Remarks</h3>
232     <p>For internal use only.</p>
233   */

234   @Override JavaDoc
235   public int writeTo(
236     IOutputStream stream
237     )
238   {
239     // Header.
240
int size = stream.write(reference.getID() + " obj\n");
241
242     // Body.
243
size += getDataObject().writeTo(stream);
244
245     // Tail.
246
size += stream.write("\nendobj\n");
247
248     return size;
249   }
250   // </internal>
251
// </interface>
252
// </dynamic>
253
// </class>
254
}
Popular Tags