1 package com.trendmicro.grid.acl.ds.dummy;
2
3 import com.trendmicro.grid.acl.commons.Paths;
4 import com.trendmicro.grid.acl.ds.FileContentRepository;
5 import net.sf.tinyjee.util.Assert;
6 import net.sf.tinyjee.util.Hex;
7 import net.sf.tinyjee.util.FileUtils;
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.springframework.stereotype.Repository;
11
12 import javax.annotation.PreDestroy;
13 import java.io.*;
14 import java.net.URI;
15 import java.security.DigestOutputStream;
16 import java.security.MessageDigest;
17 import java.security.NoSuchAlgorithmException;
18 import java.util.UUID;
19 import java.util.Map;
20 import java.util.Properties;
21 import java.util.Date;
22
23
24
25
26
27
28
29 @Repository
30 public class DummyFileRepository implements FileContentRepository {
31
32 private static final Logger log = LoggerFactory.getLogger(DummyFileRepository.class);
33 private static String URI_SCHEME = "dummy-repository";
34
35 File repositoryPath;
36 final int digestLength = newHashKeyDigest().getDigestLength();
37
38 public DummyFileRepository() {
39 try {
40 repositoryPath = new File(Paths.getResourcePath(), "/dummy-file-repository").getCanonicalFile();
41 if (!repositoryPath.isDirectory() && !repositoryPath.mkdirs())
42 throw new IllegalArgumentException("Failed");
43 cleanup();
44 } catch (IOException e) {
45 log.error("TMACL-00070: Failed to initialize the dummy file repository.", e);
46 }
47 }
48
49 @PreDestroy
50 void cleanup() {
51 FileUtils.removeFiles(repositoryPath);
52 }
53
54 public String getHashKeyAlgorithm() {
55 return newHashKeyDigest().getAlgorithm();
56 }
57
58 public MessageDigest newHashKeyDigest() {
59 try {
60 return MessageDigest.getInstance("SHA1");
61 } catch (NoSuchAlgorithmException e) {
62 throw new RuntimeException(e);
63 }
64 }
65
66 File toFile(byte[] hashKey, boolean isProperties) {
67 return new File(repositoryPath, encodeHashKey(hashKey) + (isProperties ? ".properties" : ".data"));
68 }
69
70 public void attachProperties(byte[] hashKey, Map<String, String> properties) throws IOException {
71 if (!isExisting(hashKey))
72 throw new FileNotFoundException(Hex.encode(hashKey));
73
74 File propertiesFile = toFile(hashKey, true);
75 Properties p = new Properties();
76 p.putAll(properties);
77 p.store(new FileOutputStream(propertiesFile), "");
78 }
79
80 @SuppressWarnings("unchecked")
81 public Map<String, String> readProperties(byte[] hashKey) throws IOException {
82 if (!isExisting(hashKey))
83 throw new FileNotFoundException(Hex.encode(hashKey));
84
85 File propertiesFile = toFile(hashKey, true);
86 if (propertiesFile.isFile()) {
87 Properties p = new Properties();
88 p.load(new FileInputStream(propertiesFile));
89 return (Map) p;
90 }
91
92 return null;
93 }
94
95 public boolean isExisting(byte[] hashKey) {
96 return toFile(hashKey, false).exists();
97 }
98
99 public Date getLastModified(byte[] hashKey) {
100 long lm = toFile(hashKey, false).lastModified();
101 return lm == 0L ? null : new Date(lm);
102 }
103
104 public DigestOutputStream openForWrite(byte[] hashKey) throws IllegalStateException, FileNotFoundException {
105 return new DigestOutputStream(new BufferedOutputStream(
106 new FileOutputStream(toFile(hashKey, false))), newHashKeyDigest());
107 }
108
109 public InputStream openForRead(byte[] hashKey) throws FileNotFoundException {
110 return new BufferedInputStream(new FileInputStream(toFile(hashKey, false)));
111 }
112
113 public void rename(byte[] fromHashKey, byte[] toHashKey) throws FileNotFoundException, IllegalArgumentException {
114 File from = toFile(fromHashKey, false);
115 if (!from.exists())
116 throw new FileNotFoundException("The file '" + from + "' does not exist.");
117 File to = toFile(toHashKey, false);
118 if (to.exists())
119 throw new FileNotFoundException("The target file '" + to + "' is in the way.");
120 from.renameTo(to);
121 }
122
123 public byte[] createTemporaryHashKey() {
124 return newHashKeyDigest().digest(UUID.randomUUID().toString().getBytes());
125 }
126
127 public URI encodeToInternalURI(byte[] hashKey) {
128 String key = encodeHashKey(hashKey);
129 return URI.create(URI_SCHEME + ":" + key);
130 }
131
132 public byte[] decodeFromInternalURI(URI internalURI) {
133 if (!internalURI.getScheme().equals(URI_SCHEME))
134 return null;
135 return decodeHashKey(internalURI.toString().substring(URI_SCHEME.length() + 1));
136 }
137
138 public String encodeHashKey(byte[] hashKey) {
139 return Hex.encode(hashKey);
140 }
141
142 public byte[] decodeHashKey(String hashKey) {
143 byte[] hash = Hex.decode(hashKey);
144 Assert.assertEquals("hashKeyLength", digestLength, hash.length);
145 return hash;
146 }
147 }