KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > wings > StaticResource


1 /*
2  * $Id: StaticResource.java,v 1.8 2005/05/13 15:47:09 blueshift Exp $
3  * Copyright 2000,2005 wingS development team.
4  *
5  * This file is part of wingS (http://www.j-wings.org).
6  *
7  * wingS is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; either version 2.1
10  * of the License, or (at your option) any later version.
11  *
12  * Please see COPYING for the complete licence.
13  */

14 package org.wings;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.wings.externalizer.ExternalizeManager;
19 import org.wings.io.Device;
20 import org.wings.session.PropertyService;
21 import org.wings.session.SessionManager;
22
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26
27 /**
28  * @author <a HREF="mailto:haaf@mercatis.de">Armin Haaf</a>
29  * @author <a HREF="mailto:H.Zeller@acm.org">Henner Zeller</a>
30  * @version $Revision: 1.8 $
31  */

32 public abstract class StaticResource extends Resource {
33     private final transient static Log log = LogFactory.getLog(StaticResource.class);
34     /**
35      * Flags that influence the behaviour of the externalize manager
36      */

37     protected int externalizerFlags = ExternalizeManager.FINAL;
38
39     /**
40      * A buffer for temporal storage of the resource
41      */

42     protected transient LimitedBuffer buffer;
43     
44     /**
45      * The max size of the buffer
46      */

47     protected int maxBufferSize = -1;
48
49     /**
50      * The size of this resource. Initially, this will be '-1', but
51      * the value is updated, once the Resource is delivered.
52      */

53     protected int size = -1;
54
55     /**
56      * An ByteArrayOutputStream that buffers up to the limit
57      * MAX_SIZE_TO_BUFFER. Is able to write to an Device.
58      */

59     protected final static class LimitedBuffer extends ByteArrayOutputStream JavaDoc {
60         public static final int MAX_SIZE_TO_BUFFER = 8 * 1024; // 8 KByte
61

62         private boolean withinLimit;
63
64         private int maxSizeToBuffer = MAX_SIZE_TO_BUFFER;
65
66         /**
67          * creates a new buffer
68          */

69         LimitedBuffer() {
70             /*
71              * don't waste too much memory; most resources (like icons)
72              * are tiny, so we should start with a small initial size.
73              */

74             super(64);
75             withinLimit = true;
76
77             initMaxSizeToBuffer();
78         }
79         
80         /**
81          * creates a new buffer with the specified max buffer size
82          * @param maxSizeToBuffer the max size in bytes
83          */

84         LimitedBuffer(int maxSizeToBuffer) {
85             this();
86             this.maxSizeToBuffer = maxSizeToBuffer;
87         }
88
89         private void initMaxSizeToBuffer() {
90             if (SessionManager.getSession() == null)
91                 return;
92             Object JavaDoc prop =
93                     SessionManager.getSession().getProperty("Resource.MaxSizeToBuffer");
94
95             if (prop != null &&
96                     prop instanceof Number JavaDoc) {
97
98                 maxSizeToBuffer = ((Number JavaDoc) prop).intValue();
99             }
100         }
101
102         /**
103          * write to the stream. If the output size exceeds the limit,
104          * then set the stream to error state.
105          */

106         public void write(byte[] b, int off, int len) {
107             if (!withinLimit) return;
108             withinLimit = (count + len < maxSizeToBuffer);
109             if (withinLimit)
110                 super.write(b, off, len);
111             else
112                 reset(); // discard all input so far: it would become too large
113
}
114
115         // Don't use write(int b)! It does not check the size.
116

117         /**
118          * returns, whether the filled buffer is within the limits,
119          * and thus, its content is valid and can be used.
120          */

121         public boolean isValid() {
122             return withinLimit;
123         }
124
125         /**
126          * sets, whether this resource is valid.
127          */

128         public void setValid(boolean valid) {
129             withinLimit = valid;
130         }
131
132         /**
133          * returns the _raw_ buffer; i.e. the buffer may be larger than
134          * the current size().
135          */

136         public byte[] getBytes() {
137             return buf;
138         }
139
140         /**
141          * write to some output device.
142          */

143         public void writeTo(Device out) throws IOException JavaDoc {
144             out.write(buf, 0, size());
145         }
146     }
147
148     /**
149      * A static resource that is obtained from the specified class loader
150      */

151     protected StaticResource(String JavaDoc extension, String JavaDoc mimeType) {
152         super(extension, mimeType);
153     }
154
155     /**
156      * Get the id that identifies this resource as an externalized object.
157      * If the object has not been externalized yet, it will be externalized.
158      *
159      * @return the externalization id
160      */

161     public String JavaDoc getId() {
162         if (id == null && SessionManager.getSession() != null) {
163             ExternalizeManager ext = SessionManager.getSession().getExternalizeManager();
164             id = ext.getId(ext.externalize(this, externalizerFlags));
165             log.debug("new " + getClass().getName() + " with id " + id);
166         }
167         return id;
168     }
169
170     public void setMimeType(String JavaDoc mimeType) {
171         this.mimeType = mimeType;
172     }
173
174     /**
175      * Reads the resource into an LimitedBuffer and returns it. If the
176      * size of the resource is larger than
177      * {@link LimitedBuffer#MAX_SIZE_TO_BUFFER}, then the returned Buffer
178      * is empty and does not contain the Resource's content (and the
179      * isValid() flag is false).
180      *
181      * @return buffered resource as LimitedBuffer, that may be invalid,
182      * if the size of the resource is beyond MAX_SIZE_TO_BUFFER. It is
183      * null, if the Resource returned an invalid stream.
184      * @throws IOException
185      */

186     protected LimitedBuffer bufferResource() throws IOException JavaDoc {
187         if (buffer == null) {
188             if (maxBufferSize != -1) {
189                 buffer = new LimitedBuffer(maxBufferSize);
190             } else {
191                 buffer = new LimitedBuffer();
192             }
193             InputStream JavaDoc resource = getResourceStream();
194             if (resource != null) {
195                 byte[] copyBuffer = new byte[1024];
196                 int read;
197                 while (buffer.isValid()
198                         && (read = resource.read(copyBuffer)) > 0) {
199                     buffer.write(copyBuffer, 0, read);
200                 }
201                 resource.close();
202                 if (buffer.isValid()) {
203                     size = buffer.size();
204                 }
205             } else {
206                 log.fatal("Resource returned empty stream: " + this);
207                 buffer.setValid(false);
208             }
209         }
210         return buffer;
211     }
212
213     /**
214      * writes the Resource to the given Stream. If the resource
215      * is not larger than {@link LimitedBuffer#MAX_SIZE_TO_BUFFER}, then
216      * an internal buffer caches the content the first time, so that it
217      * is delivered as fast as possible at any subsequent calls.
218      *
219      * @param out the sink, the content of the resource should
220      * be written to.
221      */

222     public final void write(Device out) throws IOException JavaDoc {
223         /*
224          * if the buffer is null, then we are called the first time.
225          */

226         if (buffer == null) {
227             bufferResource();
228             if (buffer == null) // no valid bufferable resource available
229
return;
230         }
231
232         if (buffer.isValid()) { // buffered and small enough. buffer->out
233
buffer.writeTo(out);
234         } else { // too large to be buffered. res->out
235
InputStream JavaDoc resource = getResourceStream();
236             if (resource != null) {
237                 int deliverSize = 0;
238                 byte[] copyBuffer = new byte[1024];
239                 int read;
240                 while ((read = resource.read(copyBuffer)) > 0) {
241                     out.write(copyBuffer, 0, read);
242                     deliverSize += read;
243                 }
244                 resource.close();
245                 size = deliverSize;
246             }
247         }
248
249         out.flush();
250     }
251
252     /**
253      * Return the size in bytes of the resource, if known
254      */

255     public final int getLength() {
256         return size;
257     }
258
259     public SimpleURL getURL() {
260         String JavaDoc name = getId();
261
262         // append the sessionid, if not global
263
if ((externalizerFlags & ExternalizeManager.GLOBAL) > 0) {
264             return new SimpleURL(name);
265         } else {
266             RequestURL requestURL = (RequestURL) getPropertyService().getProperty("request.url");
267             requestURL = (RequestURL) requestURL.clone();
268             requestURL.setResource(name);
269             return requestURL;
270         }
271     }
272
273     private PropertyService propertyService;
274
275     protected PropertyService getPropertyService() {
276         if (propertyService == null)
277             propertyService = (PropertyService) SessionManager.getSession();
278         return propertyService;
279     }
280
281
282     public String JavaDoc toString() {
283         return getId();
284     }
285
286     /**
287      * set the externalizer flags as defined in
288      * {@link org.wings.externalizer.AbstractExternalizeManager}.
289      */

290     public void setExternalizerFlags(int flags) {
291         externalizerFlags = flags;
292     }
293
294     public int getExternalizerFlags() {
295         return externalizerFlags;
296     }
297
298     protected static String JavaDoc resolveName(Class JavaDoc baseClass, String JavaDoc fileName) {
299         if (fileName == null) {
300             return fileName;
301         }
302         if (!fileName.startsWith("/")) {
303             while (baseClass.isArray()) {
304                 baseClass = baseClass.getComponentType();
305             }
306             String JavaDoc baseName = baseClass.getName();
307             int index = baseName.lastIndexOf('.');
308             if (index != -1) {
309                 fileName = baseName.substring(0, index).replace('.', '/')
310                         + "/" + fileName;
311             }
312         } else {
313             fileName = fileName.substring(1);
314         }
315         return fileName;
316     }
317
318     protected abstract InputStream JavaDoc getResourceStream() throws IOException JavaDoc;
319
320     public int getMaxBufferSize() {
321         return maxBufferSize;
322     }
323     
324     public void setMaxBufferSize(int maxBufferSize) {
325         this.maxBufferSize = maxBufferSize;
326     }
327     
328 }
329
330
331
Popular Tags