1 package info.magnolia.cms.servlets; 2 3 import info.magnolia.cms.util.ClasspathResourcesUtil; 4 5 import java.io.IOException ; 6 import java.io.InputStream ; 7 import java.net.URL ; 8 import java.net.URLConnection ; 9 import java.util.Hashtable ; 10 import java.util.Map ; 11 12 import javax.servlet.ServletException ; 13 import javax.servlet.ServletOutputStream ; 14 import javax.servlet.http.HttpServlet ; 15 import javax.servlet.http.HttpServletRequest ; 16 import javax.servlet.http.HttpServletResponse ; 17 18 import org.apache.commons.io.IOUtils; 19 import org.apache.commons.lang.StringUtils; 20 import org.slf4j.Logger; 21 import org.slf4j.LoggerFactory; 22 23 24 33 public class ClasspathSpool extends HttpServlet { 34 35 38 public static final String MGNL_RESOURCES_ROOT = "/mgnl-resources"; 39 40 43 private static final long serialVersionUID = 222L; 44 45 48 private static Logger log = LoggerFactory.getLogger(Spool.class); 49 50 protected long getLastModified(HttpServletRequest req) { 51 String filePath = this.getFilePath(req); 52 try { 53 URL url = ClasspathResourcesUtil.getResource(MGNL_RESOURCES_ROOT + filePath); 54 if(url != null){ 55 URLConnection connection = url.openConnection(); 56 return connection.getLastModified(); 57 } 58 } 59 catch (IOException e) { 60 } 62 63 return -1; 64 } 65 66 72 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { 73 74 String filePath = getFilePath(request); 75 76 if (StringUtils.contains(filePath, "*")) { 77 streamMultipleFile(response, filePath); 78 } 79 else if (StringUtils.contains(filePath, "|")) { 80 String [] paths = StringUtils.split(filePath, "|"); 81 streamMultipleFile(response, paths); 82 } 83 else { 84 streamSingleFile(response, filePath); 85 } 86 } 87 88 protected String getFilePath(HttpServletRequest request) { 89 String filePath = (String ) request.getAttribute("javax.servlet.include.path_info"); 91 92 if (StringUtils.isEmpty(filePath)) { 94 filePath = (String ) request.getAttribute("javax.servlet.forward.path_info"); 95 } 96 97 if (StringUtils.isEmpty(filePath)) { 99 filePath = request.getPathInfo(); 100 } 101 return filePath; 102 } 103 104 private Map multipleFilePathsCache; 105 106 109 public void init() throws ServletException { 110 super.init(); 111 multipleFilePathsCache = new Hashtable (); 112 } 113 114 117 public void destroy() { 118 super.destroy(); 119 multipleFilePathsCache.clear(); 120 } 121 122 129 private void streamMultipleFile(HttpServletResponse response, String filePath) throws IOException { 130 if (log.isDebugEnabled()) { 131 log.debug("aggregating files for request {}", filePath); 132 } 133 134 String [] paths = (String []) multipleFilePathsCache.get(filePath); 135 if (paths == null) { 136 final String startsWith = MGNL_RESOURCES_ROOT + StringUtils.substringBefore(filePath, "*"); 137 final String endssWith = StringUtils.substringAfterLast(filePath, "*"); 138 139 paths = ClasspathResourcesUtil.findResources(new ClasspathResourcesUtil.Filter() { 140 141 public boolean accept(String name) { 142 return name.startsWith(startsWith) && name.endsWith(endssWith); 143 } 144 }); 145 } 146 multipleFilePathsCache.put(filePath, paths); 147 148 if (paths.length == 0) { 149 response.sendError(HttpServletResponse.SC_NOT_FOUND); 150 return; 151 } 152 153 streamMultipleFile(response, paths); 154 } 155 156 161 private void streamMultipleFile(HttpServletResponse response, String [] paths) throws IOException { 162 ServletOutputStream out = response.getOutputStream(); 163 InputStream in = null; 164 165 for (int j = 0; j < paths.length; j++) { 166 try { 167 String path = paths[j]; 168 if (!path.startsWith(MGNL_RESOURCES_ROOT)) { 169 path = MGNL_RESOURCES_ROOT + path; 170 } 171 in = ClasspathResourcesUtil.getStream(path); 172 if (in != null) { 173 IOUtils.copy(in, out); 174 } 175 } 176 finally { 177 IOUtils.closeQuietly(in); 178 } 179 } 180 181 out.flush(); 182 IOUtils.closeQuietly(out); 183 } 184 185 190 private void streamSingleFile(HttpServletResponse response, String filePath) throws IOException { 191 InputStream in = null; 192 try { 195 in = ClasspathResourcesUtil.getStream(MGNL_RESOURCES_ROOT + filePath); 196 } 197 catch (IOException e) { 198 IOUtils.closeQuietly(in); 199 } 200 201 if (in == null) { 202 if (!response.isCommitted()) { 203 response.sendError(HttpServletResponse.SC_NOT_FOUND); 204 } 205 return; 206 } 207 208 try { 209 ServletOutputStream out = response.getOutputStream(); 210 IOUtils.copy(in, out); 211 out.flush(); 212 IOUtils.closeQuietly(out); 213 } 214 catch (IOException e) { 215 if (log.isDebugEnabled()) { 218 log.debug("Unable to spool resource due to a {} exception", e.getClass().getName()); } 220 if (!response.isCommitted()) { 221 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 222 } 223 } 224 finally { 225 IOUtils.closeQuietly(in); 226 } 227 } 228 229 } 230 | Popular Tags |