001: /*
002: * $Id: Cache.java,v 1.2 2007/12/20 18:17:41 rbair Exp $
003: *
004: * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
005: * Santa Clara, California 95054, U.S.A. All rights reserved.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this library; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
020: */
021:
022: package com.sun.pdfview;
023:
024: import java.awt.image.BufferedImage;
025: import java.lang.ref.SoftReference;
026: import java.util.Collections;
027: import java.util.HashMap;
028: import java.util.Map;
029:
030: /**
031: * A cache of PDF pages and images.
032: */
033: public class Cache {
034: /** the pages in the cache, mapped by page number */
035: private Map pages;
036:
037: /** Creates a new instance of a Cache */
038: public Cache() {
039: pages = Collections.synchronizedMap(new HashMap());
040: }
041:
042: /**
043: * Add a page to the cache. This method should be used for
044: * pages which have already been completely rendered.
045: *
046: * @param pageNumber the page number of this page
047: * @param page the page to add
048: */
049: public void addPage(Integer pageNumber, PDFPage page) {
050: addPageRecord(pageNumber, page, null);
051: }
052:
053: /**
054: * Add a page to the cache. This method should be used for
055: * pages which are still in the process of being rendered.
056: *
057: * @param pageNumber the page number of this page
058: * @param page the page to add
059: * @param parser the parser which is parsing this page
060: */
061: public void addPage(Integer pageNumber, PDFPage page,
062: PDFParser parser) {
063: addPageRecord(pageNumber, page, parser);
064: }
065:
066: /**
067: * Add an image to the cache. This method should be used for images
068: * which have already been completely rendered
069: *
070: * @param page page this image is associated with
071: * @param info the image info associated with this image
072: * @param image the image to add
073: */
074: public void addImage(PDFPage page, ImageInfo info,
075: BufferedImage image) {
076: addImageRecord(page, info, image, null);
077: }
078:
079: /**
080: * Add an image to the cache. This method should be used for images
081: * which are still in the process of being rendered.
082: *
083: * @param page the page this image is associated with
084: * @param info the image info associated with this image
085: * @param image the image to add
086: * @param renderer the renderer which is rendering this page
087: */
088: public void addImage(PDFPage page, ImageInfo info,
089: BufferedImage image, PDFRenderer renderer) {
090: addImageRecord(page, info, image, renderer);
091: }
092:
093: /**
094: * Get a page from the cache
095: *
096: * @param pageNumber the number of the page to get
097: * @return the page, if it is in the cache, or null if not
098: */
099: public PDFPage getPage(Integer pageNumber) {
100: PageRecord rec = getPageRecord(pageNumber);
101: if (rec != null) {
102: return (PDFPage) rec.value;
103: }
104:
105: // not found
106: return null;
107: }
108:
109: /**
110: * Get a page's parser from the cache
111: *
112: * @param pageNumber the number of the page to get the parser for
113: * @return the parser, or null if it is not in the cache
114: */
115: public PDFParser getPageParser(Integer pageNumber) {
116: PageRecord rec = getPageRecord(pageNumber);
117: if (rec != null) {
118: return (PDFParser) rec.generator;
119: }
120:
121: // not found
122: return null;
123: }
124:
125: /**
126: * Get an image from the cache
127: *
128: * @param page the page the image is associated with
129: * @param info the image info that describes the image
130: *
131: * @return the image if it is in the cache, or null if not
132: */
133: public BufferedImage getImage(PDFPage page, ImageInfo info) {
134: Record rec = getImageRecord(page, info);
135: if (rec != null) {
136: return (BufferedImage) rec.value;
137: }
138:
139: // not found
140: return null;
141: }
142:
143: /**
144: * Get an image's renderer from the cache
145: *
146: * @param page the page this image was generated from
147: * @param info the image info describing the image
148: * @return the renderer, or null if it is not in the cache
149: */
150: public PDFRenderer getImageRenderer(PDFPage page, ImageInfo info) {
151: Record rec = getImageRecord(page, info);
152: if (rec != null) {
153: return (PDFRenderer) rec.generator;
154: }
155:
156: // not found
157: return null;
158: }
159:
160: /**
161: * Remove a page and all its associated images, as well as its parser
162: * and renderers, from the cache
163: *
164: * @param pageNumber the number of the page to remove
165: */
166: public void removePage(Integer pageNumber) {
167: removePageRecord(pageNumber);
168: }
169:
170: /**
171: * Remove an image and its associated renderer from the cache
172: *
173: * @param page the page the image is generated from
174: * @param info the image info of the image to remove
175: */
176: public void removeImage(PDFPage page, ImageInfo info) {
177: removeImageRecord(page, info);
178: }
179:
180: /**
181: * The internal routine to add a page to the cache, and return the
182: * page record which was generated
183: */
184: PageRecord addPageRecord(Integer pageNumber, PDFPage page,
185: PDFParser parser) {
186: PageRecord rec = new PageRecord();
187: rec.value = page;
188: rec.generator = parser;
189:
190: pages.put(pageNumber, new SoftReference(rec));
191:
192: return rec;
193: }
194:
195: /**
196: * Get a page's record from the cache
197: *
198: * @return the record, or null if it's not in the cache
199: */
200: PageRecord getPageRecord(Integer pageNumber) {
201: // System.out.println("Request for page " + pageNumber);
202: SoftReference ref = (SoftReference) pages.get(pageNumber);
203: if (ref != null) {
204: String val = (ref.get() == null) ? " not in " : " in ";
205: // System.out.println("Page " + pageNumber + val + "cache");
206: return (PageRecord) ref.get();
207: }
208:
209: // System.out.println("Page " + pageNumber + " not in cache");
210: // not in cache
211: return null;
212: }
213:
214: /**
215: * Remove a page's record from the cache
216: */
217: PageRecord removePageRecord(Integer pageNumber) {
218: SoftReference ref = (SoftReference) pages.remove(pageNumber);
219: if (ref != null) {
220: return (PageRecord) ref.get();
221: }
222:
223: // not in cache
224: return null;
225: }
226:
227: /**
228: * The internal routine to add an image to the cache and return the
229: * record that was generated.
230: */
231: Record addImageRecord(PDFPage page, ImageInfo info,
232: BufferedImage image, PDFRenderer renderer) {
233: // first, find or create the relevant page record
234: Integer pageNumber = new Integer(page.getPageNumber());
235: PageRecord pageRec = getPageRecord(pageNumber);
236: if (pageRec == null) {
237: pageRec = addPageRecord(pageNumber, page, null);
238: }
239:
240: // next, create the image record
241: Record rec = new Record();
242: rec.value = image;
243: rec.generator = renderer;
244:
245: // add it to the cache
246: pageRec.images.put(info, new SoftReference(rec));
247:
248: return rec;
249: }
250:
251: /**
252: * Get an image's record from the cache
253: *
254: * @return the record, or null if it's not in the cache
255: */
256: Record getImageRecord(PDFPage page, ImageInfo info) {
257: // first find the relevant page record
258: Integer pageNumber = new Integer(page.getPageNumber());
259:
260: // System.out.println("Request for image on page " + pageNumber);
261:
262: PageRecord pageRec = getPageRecord(pageNumber);
263: if (pageRec != null) {
264: SoftReference ref = (SoftReference) pageRec.images
265: .get(info);
266: if (ref != null) {
267: String val = (ref.get() == null) ? " not in " : " in ";
268: // System.out.println("Image on page " + pageNumber + val + " cache");
269: return (Record) ref.get();
270: }
271: }
272:
273: // System.out.println("Image on page " + pageNumber + " not in cache");
274: // not found
275: return null;
276: }
277:
278: /**
279: * Remove an image's record from the cache
280: */
281: Record removeImageRecord(PDFPage page, ImageInfo info) {
282: // first find the relevant page record
283: Integer pageNumber = new Integer(page.getPageNumber());
284: PageRecord pageRec = getPageRecord(pageNumber);
285: if (pageRec != null) {
286: SoftReference ref = (SoftReference) pageRec.images
287: .remove(info);
288: if (ref != null) {
289: return (Record) ref.get();
290: }
291:
292: }
293:
294: return null;
295: }
296:
297: /** the basic information about a page or image */
298: class Record {
299: /** the page or image itself */
300: Object value;
301:
302: /** the thing generating the page, or null if done/not provided */
303: BaseWatchable generator;
304: }
305:
306: /** the record stored for each page in the cache */
307: class PageRecord extends Record {
308: /** any images associated with the page */
309: Map images;
310:
311: /** create a new page record */
312: public PageRecord() {
313: images = Collections.synchronizedMap(new HashMap());
314: }
315: }
316: }
|