View Javadoc
1   /*
2    * Copyright (C) 2007-2012 Argeo GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *         http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.argeo.slc.core.attachment;
17  
18  import java.io.File;
19  import java.io.FileInputStream;
20  import java.io.FileOutputStream;
21  import java.io.FileWriter;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.text.DateFormat;
26  import java.text.SimpleDateFormat;
27  import java.util.Date;
28  
29  import org.apache.commons.io.IOUtils;
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.argeo.slc.SlcException;
33  import org.springframework.beans.factory.InitializingBean;
34  import org.springframework.core.io.Resource;
35  
36  public class FileAttachmentsStorage implements AttachmentsStorage,
37  		AttachmentUploader, InitializingBean {
38  	private final static Log log = LogFactory
39  			.getLog(FileAttachmentsStorage.class);
40  
41  	private File attachmentsDirectory;
42  
43  	private String attachmentsTocFileName = "attachmentsToc.csv";
44  
45  	private DateFormat dateFormatDay = new SimpleDateFormat("yyyy-MM-dd");
46  	private DateFormat dateFormatTime = new SimpleDateFormat("HH:mm:ss");
47  
48  	public void afterPropertiesSet() {
49  		if (attachmentsDirectory == null) {
50  
51  			String osgiInstanceArea = System.getProperty("osgi.instance.area");
52  			if (osgiInstanceArea != null) {
53  				if (osgiInstanceArea.startsWith("file:"))
54  					osgiInstanceArea = osgiInstanceArea.substring("file:"
55  							.length());
56  				attachmentsDirectory = new File(osgiInstanceArea
57  						+ File.separator + "slcAttachments");
58  			}
59  
60  			if (attachmentsDirectory == null) {
61  				String tempDir = System.getProperty("java.io.tmpdir");
62  				attachmentsDirectory = new File(tempDir + File.separator
63  						+ "slcAttachments");
64  			}
65  		}
66  		if (!attachmentsDirectory.exists())
67  			attachmentsDirectory.mkdirs();
68  		if (log.isDebugEnabled())
69  			log.debug("File attachment storage initialized in directory "
70  					+ attachmentsDirectory);
71  	}
72  
73  	public void retrieveAttachment(Attachment attachment,
74  			OutputStream outputStream) {
75  		File file = getFile(attachment);
76  		InputStream in = null;
77  		try {
78  			byte[] buffer = new byte[1024 * 1024];
79  			in = new FileInputStream(file);
80  			int read = -1;
81  			while ((read = in.read(buffer)) >= 0) {
82  				outputStream.write(buffer, 0, read);
83  			}
84  			if (log.isTraceEnabled())
85  				log.trace("Read " + attachment + " from " + file);
86  		} catch (IOException e) {
87  			throw new SlcException("Cannot write attachment " + attachment
88  					+ " to " + file, e);
89  		} finally {
90  			IOUtils.closeQuietly(in);
91  		}
92  	}
93  
94  	public void storeAttachment(Attachment attachment, InputStream inputStream) {
95  		File file = getFile(attachment);
96  		FileOutputStream out = null;
97  		try {
98  			byte[] buffer = new byte[1024 * 1024];
99  			out = new FileOutputStream(file);
100 			int read = -1;
101 			while ((read = inputStream.read(buffer)) >= 0) {
102 				out.write(buffer, 0, read);
103 			}
104 			if (log.isTraceEnabled())
105 				log.trace("Wrote " + attachment + " to " + file);
106 			updateAttachmentToc(attachment, file);
107 		} catch (IOException e) {
108 			throw new SlcException("Cannot write attachment " + attachment
109 					+ " to " + file, e);
110 		} finally {
111 			IOUtils.closeQuietly(out);
112 		}
113 
114 	}
115 
116 	public void upload(Attachment attachment, Resource resource) {
117 		try {
118 			storeAttachment(attachment, resource.getInputStream());
119 		} catch (IOException e) {
120 			throw new SlcException("Cannot upload attachment " + attachment, e);
121 		}
122 	}
123 
124 	/** For monitoring purposes only */
125 	protected void updateAttachmentToc(Attachment attachment, File file) {
126 		Date date = new Date(file.lastModified());
127 		FileWriter writer = null;
128 		try {
129 			writer = new FileWriter(attachmentsDirectory + File.separator
130 					+ attachmentsTocFileName, true);
131 			writer.append(dateFormatDay.format(date));
132 			writer.append(',');
133 			writer.append(dateFormatTime.format(date));
134 			writer.append(',');
135 			writer.append(attachment.getUuid());
136 			writer.append(',');
137 			writer.append(attachment.getName());
138 			writer.append(',');
139 			writer.append(attachment.getContentType());
140 			writer.append(',');
141 			writer.append(Long.toString(file.length()));
142 			writer.append(',');
143 			writer.append(file.getCanonicalPath());
144 			writer.append('\n');
145 		} catch (IOException e) {
146 			log.warn("Could not update attachments TOC for " + attachment
147 					+ " and file " + file, e);
148 		} finally {
149 			IOUtils.closeQuietly(writer);
150 		}
151 
152 	}
153 
154 	protected File getFile(Attachment attachment) {
155 		File file = new File(attachmentsDirectory + File.separator
156 				+ attachment.getUuid());
157 		return file;
158 	}
159 
160 	public void setAttachmentsDirectory(File attachmentsDirectory) {
161 		this.attachmentsDirectory = attachmentsDirectory;
162 	}
163 
164 	public void setAttachmentsTocFileName(String attachmentsTocFileName) {
165 		this.attachmentsTocFileName = attachmentsTocFileName;
166 	}
167 
168 	public void setDateFormatDay(DateFormat dateFormatDay) {
169 		this.dateFormatDay = dateFormatDay;
170 	}
171 
172 	public void setDateFormatTime(DateFormat dateFormatTime) {
173 		this.dateFormatTime = dateFormatTime;
174 	}
175 
176 }