001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.http.filter;
016:
017: import java.io.FileInputStream;
018: import java.io.FileNotFoundException;
019: import java.io.InputStream;
020: import java.io.OutputStream;
021: import java.net.URL;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.Map;
026: import javax.servlet.ServletConfig;
027: import javax.servlet.ServletContext;
028: import javax.servlet.http.HttpServletResponse;
029: import org.apache.commons.logging.Log;
030: import org.apache.commons.logging.LogFactory;
031: import org.araneaframework.InputData;
032: import org.araneaframework.OutputData;
033: import org.araneaframework.Path;
034: import org.araneaframework.framework.core.BaseFilterService;
035: import org.araneaframework.http.HttpInputData;
036: import org.araneaframework.http.extension.ExternalResource;
037: import org.araneaframework.http.extension.ExternalResourceInitializer;
038: import org.araneaframework.http.util.ServletUtil;
039: import org.araneaframework.http.util.URLUtil;
040:
041: /**
042: * @author "Toomas Römer" <toomas@webmedia.ee>
043: * @author Jevgeni Kabanov (ekabanov <i>at</i> araneaframework <i>dot</i> org)
044: */
045: public class StandardFileImportFilterService extends BaseFilterService {
046: private static final Log log = LogFactory
047: .getLog(StandardFileImportFilterService.class);
048: private static boolean isInitialized = false;
049: private static ExternalResource resources;
050: private long cacheHoldingTime = 3600000;
051:
052: public static final String IMPORTER_FILE_NAME = "FileImporterFileName";
053: public static final String IMPORTER_GROUP_NAME = "FileImporterGroupName";
054: public static final String OVERRIDE_PREFIX = "override";
055: public static final String FILE_IMPORTER_NAME = "fileimporter";
056:
057: synchronized static void initialize(ServletContext context) {
058: if (!isInitialized) {
059: ExternalResourceInitializer initializer = new ExternalResourceInitializer();
060: resources = initializer.getResources(context);
061: isInitialized = true;
062: }
063: }
064:
065: protected void action(Path path, InputData input, OutputData output)
066: throws Exception {
067: if (!isInitialized) {
068: ServletConfig config = (ServletConfig) getEnvironment()
069: .getEntry(ServletConfig.class);
070: initialize(config.getServletContext());
071: }
072:
073: String uri = URLUtil.normalizeURI(((HttpInputData) input)
074: .getPath());
075:
076: if (uri == null || URLUtil.splitURI(uri).length == 0
077: || !URLUtil.splitURI(uri)[0].equals(FILE_IMPORTER_NAME)) {
078: childService._getService().action(path, input, output);
079: return;
080: }
081:
082: String fileName = (String) input.getGlobalData().get(
083: IMPORTER_FILE_NAME);
084: String groupName = (String) input.getGlobalData().get(
085: IMPORTER_GROUP_NAME);
086:
087: if (fileName == null) {
088: fileName = uri.substring(FILE_IMPORTER_NAME.length() + 1);
089:
090: if (resources.getGroupByName(fileName) != null) {
091: groupName = fileName;
092: fileName = null;
093: }
094: } else if (groupName == null) {
095: groupName = fileName;
096: }
097:
098: HttpServletResponse response = ServletUtil.getResponse(output);
099:
100: List filesToLoad = new ArrayList();
101: OutputStream out = response.getOutputStream();
102: try {
103: if (fileName != null) {
104: if (resources.isAllowedFile(fileName)) {
105: setHeaders(response, resources
106: .getContentType(fileName));
107: filesToLoad.add(fileName);
108: loadFiles(filesToLoad, out);
109: }
110: } else if (groupName != null) {
111: Map group = resources.getGroupByName(groupName);
112: if (group != null && group.size() > 0) {
113: Map.Entry entry = (Map.Entry) (group.entrySet()
114: .iterator().next());
115: setHeaders(response, (String) entry.getValue());
116: filesToLoad.addAll(group.keySet());
117: loadFiles(filesToLoad, out);
118: } else {
119: log
120: .warn("Unexistent group specified for file importing, "
121: + groupName);
122: throw new FileNotFoundException();
123: }
124: }
125: } catch (FileNotFoundException e) {
126: String notFoundName = fileName == null ? groupName
127: : fileName;
128: response.sendError(HttpServletResponse.SC_NOT_FOUND,
129: "Imported file or group '" + notFoundName
130: + "' not found.");
131: }
132: }
133:
134: private void setHeaders(HttpServletResponse response,
135: String contentType) {
136: response.setHeader("Cache-Control", "max-age="
137: + (cacheHoldingTime / 1000));
138: response.setDateHeader("Expires", System.currentTimeMillis()
139: + cacheHoldingTime);
140: response.setContentType(contentType);
141: }
142:
143: private void loadFiles(List files, OutputStream out)
144: throws Exception {
145: ServletContext context = (ServletContext) getEnvironment()
146: .getEntry(ServletContext.class);
147: for (Iterator iter = files.iterator(); iter.hasNext();) {
148: String fileName = (String) iter.next();
149:
150: ClassLoader loader = getClass().getClassLoader();
151: // first we try load an override
152: URL fileURL = context.getResource("/" + OVERRIDE_PREFIX
153: + "/" + fileName);
154:
155: if (fileURL == null) {
156: // fallback to the original
157: fileURL = loader.getResource(fileName);
158: } else if (log.isDebugEnabled()) {
159: log.debug("Serving override of file '" + fileName + "'"
160: + " from context path resource '"
161: + fileURL.getFile() + "'.");
162: }
163:
164: FileInputStream fileInputStream = null;
165: // fallback to the filesystem
166: if (fileURL == null) {
167: try {
168: fileInputStream = new FileInputStream(fileName);
169: } catch (FileNotFoundException e) {
170: // not being able to load results in FileNotFoundException, see below
171: } catch (SecurityException e) {
172: // not being able to load results in FileNotFoundException, see below
173: }
174: }
175:
176: if (fileURL != null || fileInputStream != null) {
177: InputStream inputStream = null;
178:
179: try {
180: inputStream = fileInputStream != null ? fileInputStream
181: : fileURL.openStream();
182:
183: if (inputStream != null) {
184: int length = 0;
185: byte[] bytes = new byte[1024];
186: do {
187: length = inputStream.read(bytes);
188: if (length == -1)
189: break;
190: out.write(bytes, 0, length);
191: } while (length != -1);
192: }
193: } finally {
194: inputStream.close();
195: }
196:
197: } else {
198: if (log.isWarnEnabled())
199: log.warn("Unable to locate resource '" + fileName
200: + "'");
201: throw new FileNotFoundException(
202: "Unable to locate resource '" + fileName + "'");
203: }
204: }
205: }
206: }
|