1 /***
2 * Copyright (C) 2009 TM-Search Community.
3 *
4 * This file is part of TM-Search Services.
5 *
6 * Foobar is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Foobar is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Foobar. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 package eu.europa.tmsearch.services.dao;
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.OutputStream;
26 import java.util.Date;
27
28 import org.apache.log4j.Logger;
29 import org.springframework.beans.BeansException;
30 import org.springframework.context.ApplicationContext;
31 import org.springframework.context.ApplicationContextAware;
32 import org.springframework.core.io.Resource;
33 import org.springframework.util.StringUtils;
34
35 import eu.europa.tmsearch.services.Cacheable;
36 import eu.europa.tmsearch.services.resources.exceptions.ResourceNotFoundException;
37
38 /***
39 * A DAO implementation for file system resources.
40 *
41 *
42 */
43 public abstract class ResourceDAOSupport implements ResourceDAO, Cacheable, ApplicationContextAware {
44
45 private final static int BUFFER_SIZE = 1024;
46 private static Logger log = Logger.getLogger(ResourceDAOSupport.class);
47
48 private ApplicationContext ctx;
49
50 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
51 ctx = applicationContext;
52 }
53
54 /***
55 * Gets a resource from the underlying data store given a URI
56 *
57 * @param resourcePath
58 * @return A byte[] containing the file resource
59 * @throws ResourceNotFoundException
60 */
61 public byte[] getResource(String resourcePath) throws ResourceNotFoundException {
62 if (!isValidPath(resourcePath)) {
63 throw new IllegalArgumentException("File path must not be null or empty");
64 }
65
66 Resource resource = ctx.getResource(resourcePath);
67 if (!resource.exists() || !resource.isReadable())
68 throw new ResourceNotFoundException();
69
70 InputStream is = null;
71 ByteArrayOutputStream os = new ByteArrayOutputStream();
72 try {
73 is = resource.getInputStream();
74
75 byte[] buffer = new byte[BUFFER_SIZE];
76 while (true) {
77 int noOfBytesRead = is.read(buffer, 0, buffer.length);
78 if (noOfBytesRead == -1) {
79 break;
80 }
81 os.write(buffer, 0, noOfBytesRead);
82 }
83 } catch (IOException exc) {
84 log.error("Caught exception while reading resource from '" + resourcePath + "'. Details: "
85 + exc.getMessage());
86 throw new ResourceNotFoundException();
87 } finally {
88 safeClose(is);
89 safeClose(os);
90 }
91 return os.toByteArray();
92 }
93
94 @Override
95 public Date getLastModified(String resourcePath) throws ResourceNotFoundException {
96 if (!isValidPath(resourcePath)) {
97 throw new IllegalArgumentException("File path must not be null or empty");
98 }
99 if (log.isDebugEnabled())
100 log.debug("Checking last modified time for " + resourcePath);
101
102 Date lastModified = new Date(Long.MAX_VALUE);
103 Resource resource = ctx.getResource(resourcePath);
104 if (!resource.exists() || !resource.isReadable())
105 throw new ResourceNotFoundException();
106
107 try {
108 lastModified = new Date(resource.lastModified());
109 if (log.isDebugEnabled())
110 log.debug("Resource " + resourcePath + " has been last modified at " + lastModified);
111 return lastModified;
112 } catch (IOException e) {
113 log.error("Caught exception while getting last modified value from '" + resourcePath
114 + "'. Details: " + e.getMessage());
115 log.error("Returning "+lastModified+" as last-modified header.");
116 return lastModified;
117 }
118 }
119
120 @Override
121 public Date getExpires(String applicationNumber) {
122 return new Date(0);
123 }
124
125 private void safeClose(InputStream is) {
126 if (is != null) {
127 try {
128 is.close();
129 is = null;
130 } catch (Exception ignored) {
131
132 }
133 }
134 }
135
136 private void safeClose(OutputStream is) {
137 if (is != null) {
138 try {
139 is.close();
140 is = null;
141 } catch (Exception ignored) {
142
143 }
144 }
145 }
146
147 private boolean isValidPath(String resourcePath) {
148 if (!StringUtils.hasLength(resourcePath))
149 return false;
150 else
151 return true;
152
153 }
154 }