1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package tinlizard.dao.io;
20
21 import freemarker.template.Configuration;
22 import freemarker.template.DefaultObjectWrapper;
23 import freemarker.template.Template;
24
25 import tinlizard.dao.MashDao;
26
27 import tinlizard.util.Messages;
28
29 import java.io.File;
30 import java.io.FileNotFoundException;
31 import java.io.FileOutputStream;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.Writer;
35 import java.util.HashMap;
36 import java.util.Locale;
37 import java.util.Map;
38
39 import org.apache.commons.lang.StringUtils;
40 import org.apache.log4j.Logger;
41
42 /***
43 * Freemarker implementation of MashDao.
44 */
45 public final class MashDaoImpl implements MashDao {
46 private static final Logger LOG = Logger.getLogger(MashDaoImpl.class);
47 private static final int BUFFER_SIZE = 128;
48 private String mashFilesDirectory;
49 private File mashDir = new File("/tmp");
50 private File resourcesDir = new File("/tmp");
51 private Configuration cfg = null;
52 private static final int SECONDS_PER_MINUTE = 60;
53 private int delayMinutes = 5;
54
55 public String getMashFilesDirectory() {
56 return mashFilesDirectory;
57 }
58
59 public void setMashFilesDirectory(final String mashFilesDirectory) {
60 this.mashFilesDirectory = mashFilesDirectory;
61
62 mashDir = new File(mashFilesDirectory);
63 resourcesDir = new File(mashDir, "resources");
64
65 if (!mashDir.isDirectory()) {
66 mashDir.mkdirs();
67 }
68
69 if (!resourcesDir.isDirectory()) {
70 resourcesDir.mkdir();
71 }
72
73 try {
74 cfg = new Configuration();
75 cfg.setDirectoryForTemplateLoading(mashDir);
76 cfg.setObjectWrapper(new DefaultObjectWrapper());
77 cfg.setTemplateUpdateDelay(delayMinutes * SECONDS_PER_MINUTE);
78 } catch (Exception e) {
79 throw new RuntimeException(Messages.error_0300(), e);
80 }
81 }
82
83 public File getResourcesFile(final String path) {
84 if (path.indexOf("..") != -1) {
85
86 return null;
87 }
88
89 File resFile = new File(resourcesDir, path);
90
91 if (!resFile.getParentFile().exists()) {
92 return null;
93 }
94
95 if (!resFile.exists()) {
96 String resourceClassPath = "/mash-files/resources" + path;
97
98 if (copyFromClasspath(resFile, resourceClassPath)) {
99 return resFile;
100 }
101 }
102
103 return null;
104 }
105
106 private boolean copyFromClasspath(final File resFile, final String resourceClassPath) {
107 InputStream is = getClass().getResourceAsStream(resourceClassPath);
108
109 if (is == null) {
110 return false;
111 }
112
113 if (!resFile.getParentFile().isDirectory()) {
114 resFile.getParentFile().mkdirs();
115 }
116
117 FileOutputStream os = null;
118
119 try {
120 os = new FileOutputStream(resFile);
121
122 byte[] buffer = new byte[BUFFER_SIZE];
123 int nRead = -1;
124
125 while ((nRead = is.read(buffer)) > -1) {
126 os.write(buffer, 0, nRead);
127 }
128
129 return true;
130 } catch (FileNotFoundException e) {
131 return false;
132 } catch (IOException e) {
133 return false;
134 } finally {
135 try {
136 is.close();
137 } catch (IOException e) {
138 LOG.trace("Ignore, nothing to do.");
139 }
140
141 if (os != null) {
142 try {
143 os.close();
144 } catch (IOException e) {
145 LOG.trace("Ignore, nothing to do.");
146 }
147 }
148 }
149 }
150
151 public void applyTemplate(final Object it, final String template, final Writer out, final Locale locale, final String username) {
152 try {
153 boolean foundTemplate = false;
154
155 String resourcePath = null;
156
157 Class<?> clazz = it.getClass();
158
159 while (!foundTemplate && !Object.class.equals(clazz)) {
160 if (LOG.isDebugEnabled()) {
161 LOG.debug("Class:" + clazz);
162 }
163
164 File classMashDir = getClassMashDir(clazz);
165 resourcePath = getResourcePath(clazz);
166
167 File templateFile = new File(classMashDir, template);
168 foundTemplate = templateFile.exists();
169
170 if (!foundTemplate) {
171 String resourceClassPath = "/mash-files/" + resourcePath + "/" + template;
172
173 if (LOG.isDebugEnabled()) {
174 LOG.debug("Check:" + resourceClassPath);
175 }
176
177 foundTemplate = copyFromClasspath(templateFile, resourceClassPath);
178 }
179
180 clazz = clazz.getSuperclass();
181 }
182
183 if (foundTemplate) {
184 if (LOG.isDebugEnabled()) {
185 LOG.debug("Found:" + resourcePath + "/" + template);
186 }
187
188 Map<Object, Object> root = new HashMap<Object, Object>();
189 root.put("it", it);
190
191 if (StringUtils.isNotBlank(username)) {
192 root.put("username", username);
193 }
194
195 Template temp = cfg.getTemplate(resourcePath + "/" + template, locale);
196 temp.process(root, out);
197 }
198 } catch (Exception e) {
199 LOG.info("Problems Applying template:" + template, e);
200 }
201 }
202
203 private String getResourcePath(final Class<?extends Object> clazz) {
204 String clazzName = clazz.getName();
205 String clazzDir = clazzName.replaceAll("//.", "/");
206
207 return clazzDir;
208 }
209
210 private File getClassMashDir(final Class<?extends Object> clazz) {
211 String clazzName = clazz.getName();
212 String clazzDir = clazzName.replaceAll("//.", "/");
213
214 return new File(mashDir, clazzDir);
215 }
216 }