1
2
3
4 package org.rcfaces.core.internal.content;
5
6 import java.io.ByteArrayInputStream;
7 import java.io.IOException;
8 import java.io.InputStream;
9
10 import javax.faces.context.ExternalContext;
11 import javax.faces.context.FacesContext;
12 import javax.servlet.ServletContext;
13 import javax.servlet.http.HttpServletRequest;
14 import javax.servlet.http.HttpServletResponse;
15
16 import org.apache.commons.logging.Log;
17 import org.apache.commons.logging.LogFactory;
18 import org.rcfaces.core.internal.RcfacesContext;
19 import org.rcfaces.core.internal.contentStorage.GZipedResolvedContent;
20 import org.rcfaces.core.internal.contentStorage.IResolvedContent;
21 import org.rcfaces.core.internal.lang.ByteBufferOutputStream;
22 import org.rcfaces.core.internal.resource.IResourceLoaderFactory;
23 import org.rcfaces.core.internal.resource.IResourceLoaderFactory.IResourceLoader;
24
25
26
27
28
29
30 public abstract class AbstractBufferOperationContentModel extends
31 AbstractOperationContentModel implements IOperationContentLoader {
32
33 private static final String REVISION = "$Revision: 1.5 $";
34
35 private static final long serialVersionUID = -7085466442454979874L;
36
37 private static final Log LOG = LogFactory
38 .getLog(AbstractBufferOperationContentModel.class);
39
40 private static final int INITIAL_BUFFER_SIZE = 8 * 1024;
41
42 public AbstractBufferOperationContentModel(String resourceURL,
43 String versionId, String operationId,
44 String filterParametersToParse, IBufferOperation styleOperation,
45 String specifiedResourceKey) {
46 super(resourceURL, versionId, operationId, filterParametersToParse,
47 styleOperation, specifiedResourceKey);
48 }
49
50 protected IResourceLoaderFactory getResourceLoaderFactory(
51 FacesContext facesContext) {
52
53 RcfacesContext rcfacesContext = RcfacesContext
54 .getInstance(facesContext);
55
56 IResourceLoaderFactory resourceLoaderFactory;
57 if (rcfacesContext.isDesignerMode()) {
58 resourceLoaderFactory = Constants.getDesignerImageLoaderFactory();
59
60 } else {
61 resourceLoaderFactory = Constants.getImageLoaderFactory();
62 }
63
64 return resourceLoaderFactory;
65 }
66
67 protected IResolvedContent getResolvedContent() {
68 return new GZipedResolvedContent(this);
69 }
70
71 protected abstract String getCharsetFromStream(InputStream inputStream);
72
73 protected abstract String getDefaultMimeType();
74
75 protected abstract boolean isMimeTypeValid(String downloadedContentType);
76
77
78
79
80
81
82 public static class ContentInformation {
83 private String charSet;
84
85 private long lastModified;
86
87 private long length;
88
89 public final String getCharSet() {
90 return charSet;
91 }
92
93 public final long getLastModified() {
94 return lastModified;
95 }
96
97 public final long getLength() {
98 return length;
99 }
100
101 public void merge(ContentInformation newContentInformation) {
102 if (newContentInformation.lastModified > lastModified) {
103 lastModified = newContentInformation.lastModified;
104 }
105
106 length += newContentInformation.getLength();
107 }
108 }
109
110 public String loadContent(FacesContext facesContext,
111 IResourceLoaderFactory resourceLoaderFactory, String path,
112 String defaultCharset, ContentInformation contentInfoRef[]) {
113
114 if (facesContext == null) {
115 facesContext = FacesContext.getCurrentInstance();
116 }
117
118 ExternalContext externalContext = facesContext.getExternalContext();
119
120 HttpServletRequest request = (HttpServletRequest) externalContext
121 .getRequest();
122 HttpServletResponse response = (HttpServletResponse) externalContext
123 .getResponse();
124 ServletContext context = (ServletContext) externalContext.getContext();
125
126 IResourceLoader resourceLoader = resourceLoaderFactory.loadResource(
127 context, request, response, path);
128
129 String downloadedContentType = resourceLoader.getContentType();
130
131 if (downloadedContentType != null) {
132 int idx = downloadedContentType.indexOf(';');
133 if (idx > 0) {
134 downloadedContentType = downloadedContentType.substring(0, idx);
135 }
136 }
137
138 if (downloadedContentType == null
139 || isMimeTypeValid(downloadedContentType) == false) {
140 LOG.error("Different content types requested='"
141 + getDefaultMimeType() + "' loaded='"
142 + downloadedContentType + "' for path '" + path + "'.");
143
144 return null;
145 }
146
147 InputStream inputStream = resourceLoader.openStream();
148
149 if (inputStream == null) {
150 LOG.error("Can not get resource specified by path '" + path + "'.");
151
152 return null;
153 }
154
155 ContentInformation contentInfo = new ContentInformation();
156
157 if (contentInfoRef != null) {
158 contentInfoRef[0] = contentInfo;
159 }
160
161 try {
162 int size = INITIAL_BUFFER_SIZE;
163 long originalSize = resourceLoader.getContentLength();
164 contentInfo.length = originalSize;
165
166 if (originalSize > 0 && originalSize < INITIAL_BUFFER_SIZE) {
167 size = (int) originalSize + 256;
168 }
169
170 ByteBufferOutputStream bous = new ByteBufferOutputStream(size);
171
172 byte b[] = new byte[size];
173 for (;;) {
174 int ret = inputStream.read(b);
175 if (ret <= 0) {
176 break;
177 }
178
179 bous.write(b, 0, ret);
180 }
181
182 bous.close();
183
184 byte buffer[] = bous.toByteArray();
185
186 String charSet = getCharsetFromStream(new ByteArrayInputStream(
187 buffer));
188
189 if (charSet == null) {
190 charSet = defaultCharset;
191 }
192
193 contentInfo.charSet = charSet;
194 contentInfo.lastModified = resourceLoader.getLastModified();
195
196 return new String(buffer, charSet);
197
198 } catch (IOException ex) {
199 LOG.error("Can not make buffer", ex);
200 return null;
201
202 } finally {
203 try {
204 inputStream.close();
205
206 } catch (IOException ex) {
207 LOG.debug("Can not close resource '" + path + "'.", ex);
208 }
209 }
210 }
211
212 }