View Javadoc
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 		// ignored
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 		// ignored
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 }