1   package com.trendmicro.grid.acl.ds.cifs;
2   
3   import net.sf.tinyjee.config.PropertySection;
4   import net.sf.tinyjee.util.FileUtils;
5   import org.slf4j.Logger;
6   import org.slf4j.LoggerFactory;
7   import org.springframework.stereotype.Repository;
8   
9   import java.io.*;
10  import java.security.NoSuchAlgorithmException;
11  import java.util.Date;
12  
13  /**
14   * Implements AbstractStructuredFileRepository as local file repository.
15   *
16   * @author juergen_kellerer, 2010-05-06
17   * @version 1.0
18   */
19  @Repository
20  public class LocalFileRepository extends AbstractStructuredFileRepository {
21  
22  	private static final Logger log = LoggerFactory.getLogger(LocalFileRepository.class);
23  
24  	private File repositoryPath;
25  	private String repositoryBaseURI;
26  
27  	public LocalFileRepository() {
28  	}
29  
30  	public LocalFileRepository(String path) {
31  		PropertySection s = CIFSPropertySection.getPropertySection();
32  		s.setProperty(CIFSPropertySection.KEY_LOCAL_REPOSITORY_PATH, path);
33  	}
34  
35  	/**
36  	 * {@inheritDoc}
37  	 */
38  	@Override
39  	protected void initialize(PropertySection section) throws NoSuchAlgorithmException {
40  		super.initialize(section);
41  
42  		String path = section.getPropertyValue(
43  				CIFSPropertySection.KEY_LOCAL_REPOSITORY_PATH, "#local-repository-is-not-set#");
44  
45  		if (path.isEmpty())
46  			return;
47  
48  		repositoryPath = new File(path);
49  		repositoryBaseURI = repositoryPath.toURI().toString();
50  		if (!repositoryBaseURI.endsWith("/"))
51  			repositoryBaseURI += "/";
52  
53  		if (!repositoryPath.isDirectory()) {
54  			log.error("TMACL-00310: The local repository path {} does not exist. " +
55  					"Using the local repository will cause failures.", repositoryPath);
56  			repositoryPath = null;
57  		}
58  	}
59  
60  	File toTargetFile(String path, boolean createPathIfMissing) throws FileNotFoundException {
61  		if (repositoryPath == null)
62  			throw new FileNotFoundException("The local file repository does not exist!");
63  
64  		File file = new File(repositoryPath, path);
65  
66  		if (createPathIfMissing) {
67  			File parent = file.getParentFile();
68  			if (!parent.isDirectory()) {
69  				if (!parent.mkdirs())
70  					throw new FileNotFoundException("Failed to create the target path: " + parent);
71  			}
72  		}
73  
74  		return file;
75  	}
76  
77  	/**
78  	 * {@inheritDoc}
79  	 */
80  	@Override
81  	protected String getBaseURI(String baseURI) {
82  		return baseURI.isEmpty() ? repositoryBaseURI : baseURI;
83  	}
84  
85  	/**
86  	 * {@inheritDoc}
87  	 */
88  	protected boolean isExisting(String path) {
89  		try {
90  			return toTargetFile(path, false).exists();
91  		} catch (FileNotFoundException e) {
92  			if (log.isTraceEnabled())
93  				log.trace("Failed to check path '" + path + "' for existence, returning: 'does not exist'.", e);
94  			return false;
95  		}
96  	}
97  
98  	/**
99  	 * {@inheritDoc}
100 	 */
101 	protected Date getLastModified(String path) {
102 		try {
103 			long lm = toTargetFile(path, false).lastModified();
104 			return lm == 0L ? null : new Date(lm);
105 		} catch (FileNotFoundException e) {
106 			if (log.isTraceEnabled())
107 				log.trace("Failed to get the last modification date on path '" + path + "', returning: 'null'.", e);
108 			return null;
109 		}
110 	}
111 
112 	/**
113 	 * {@inheritDoc}
114 	 */
115 	protected OutputStream openForWrite(String path)
116 			throws FileNotFoundException, IllegalStateException {
117 		File file = null;
118 		try {
119 			file = toTargetFile(path, true);
120 			return new BufferedOutputStream(new FileOutputStream(file));
121 		} catch (FileNotFoundException e) {
122 			if (log.isDebugEnabled())
123 				log.debug("Failed opening file '" + (file == null ? "PATH:" + path : file) + "' for writing.", e);
124 			throw e;
125 		}
126 	}
127 
128 	/**
129 	 * {@inheritDoc}
130 	 */
131 	protected InputStream openForRead(String path) throws FileNotFoundException {
132 		File file = null;
133 		try {
134 			file = toTargetFile(path, false);
135 			return new BufferedInputStream(new FileInputStream(file));
136 		} catch (FileNotFoundException e) {
137 			if (log.isDebugEnabled())
138 				log.debug("Failed opening file '" + (file == null ? "PATH:" + path : file) + "' for reading.", e);
139 			throw e;
140 		}
141 	}
142 
143 	/**
144 	 * {@inheritDoc}
145 	 */
146 	protected void rename(String fromPath, String toPath)
147 			throws FileNotFoundException, IllegalArgumentException {
148 		File from = toTargetFile(fromPath, false);
149 		File to = toTargetFile(toPath, true);
150 		if (!from.renameTo(to)) {
151 			if (log.isDebugEnabled())
152 				log.debug("Failed renaming file '{}' to '{}', falling back to file copy.", from, to);
153 
154 			try {
155 				FileUtils.copy(from, to);
156 
157 				if (log.isDebugEnabled())
158 					log.debug("Successfully copied file '{}' to '{}', deleting the source now.", from, to);
159 
160 				if (!from.delete())
161 					log.warn("TMACL-01930:Failed deleting temporary source '{}'. Disk space may get wasted.", from);
162 
163 			} catch (IOException e) {
164 				log.error("TMACL-01830:Failed renaming file '" + from + "' to '" + to +
165 						"', neither move nor copy could be applied.", e);
166 
167 				final FileNotFoundException fnf = new FileNotFoundException(
168 						"Failed renaming file '" + from + "' to '" + to + "'");
169 				fnf.initCause(e);
170 				throw fnf;
171 			}
172 		}
173 	}
174 }