1
2
3
4
5
6
7 package org.asyrinx.joey.gen.ant.task;
8
9 import java.io.BufferedReader;
10 import java.io.File;
11 import java.io.FileInputStream;
12 import java.io.FileNotFoundException;
13 import java.io.FileOutputStream;
14 import java.io.FileReader;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.util.ArrayList;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Properties;
22
23 import ognl.OgnlRuntime;
24
25 import org.apache.commons.io.CopyUtils;
26 import org.apache.commons.io.FileUtils;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.DirectoryScanner;
29 import org.apache.tools.ant.Project;
30 import org.apache.tools.ant.types.FileSet;
31 import org.apache.velocity.VelocityContext;
32 import org.apache.velocity.context.Context;
33 import org.apache.velocity.texen.Generator;
34 import org.asyrinx.brownie.core.lang.StringUtils;
35 import org.asyrinx.joey.gen.ant.ModelLoader;
36 import org.asyrinx.joey.gen.core.JoeyGenerateTarget;
37 import org.asyrinx.joey.gen.core.JoeyVelocityGenerator;
38 import org.asyrinx.joey.gen.core.VelocityHelper;
39 import org.asyrinx.joey.gen.core.VelocityOgnlAccessor;
40 import org.asyrinx.joey.gen.core.VelocityOgnlHelper;
41 import org.asyrinx.joey.gen.core.impl.S2ContainerLoader;
42 import org.asyrinx.joey.gen.hibernate.HibernateUtils;
43 import org.asyrinx.joey.gen.model.java.AppDomain;
44 import org.asyrinx.joey.gen.model.rdb.Databases;
45 import org.seasar.framework.container.S2Container;
46 import org.xml.sax.SAXException;
47
48 /***
49 * @author takeshi
50 */
51 public class JoeyGenerateTask extends MultiTargetTexenTask {
52
53 private S2Container container = S2ContainerLoader.getContainer();
54
55 public Context initControlContext() {
56 if (filesets.isEmpty())
57 throw new BuildException("There's no schema file. You must specify fileset of schema files!");
58 final Context result = new VelocityContext();
59 try {
60 loadModels(result);
61 } catch (Exception e) {
62 throw new BuildException(e);
63 }
64 return result;
65 }
66
67 private Generator generator = null;
68
69 protected Generator initGenerator() {
70 if (this.generator == null) {
71 final Object gen = container.getComponent(JoeyVelocityGenerator.class);
72 if (gen instanceof Generator)
73 this.generator = (Generator) gen;
74 else
75 throw new BuildException("JoeyVelocityGenerator object must extends " + Generator.class.getName());
76 }
77 return this.generator;
78 }
79
80 private SchemaBackup schemaBackup = new SchemaBackup();
81
82
83
84 private void loadModels(Context context) throws IOException, SAXException {
85 final ModelLoader modelLoader = (ModelLoader) container.getComponent(ModelLoader.class);
86 final Databases databases = modelLoader.loadDatabaseModels(filesets, this.project);
87 final AppDomain domain = modelLoader.loadAppDomainModel(databases, this.project);
88 final Map rdb2Java = modelLoader.getRdb2Java();
89
90 schemaBackup.execute(this.project, filesets, lastSchemaDir);
91
92 context.put("databases", databases);
93 context.put("domain", domain);
94 context.put("rdb2java", rdb2Java);
95 context.put("helper", new VelocityHelper(context));
96 context.put("ognl", new VelocityOgnlHelper(context));
97 context.put("stringUtils", new org.asyrinx.brownie.core.lang.StringUtils());
98 context.put("hibernateUtils", new HibernateUtils());
99 OgnlRuntime.setPropertyAccessor(Map.class, new VelocityOgnlAccessor(context));
100 }
101
102 private List loadTargetFile() {
103 final List result = new ArrayList();
104 try {
105 final BufferedReader reader = new BufferedReader(new FileReader(getTargetTextFile()));
106 for (String line = reader.readLine(); line != null; line = reader.readLine()) {
107 line = line.trim();
108 if (StringUtils.isEmpty(line))
109 continue;
110 if (line.startsWith("#"))
111 continue;
112 if (result.contains(line))
113 continue;
114 log.debug(getTargetTextFile() + " target: " + line);
115 result.add(line);
116 }
117 } catch (IOException e) {
118 throw new BuildException(e);
119 }
120 return result;
121 }
122
123 protected List initTargets() {
124 final Properties properties = getDefaultProperties();
125 final List source = loadTargetFile();
126 final List result = new ArrayList();
127 for (Iterator i = source.iterator(); i.hasNext();) {
128 final String line = (String) i.next();
129 final JoeyGenerateTarget target = createTarget(properties, line);
130 result.add(target);
131 }
132 return result;
133 }
134
135 /***
136 * @param properties
137 * @param line
138 * @return
139 */
140 private JoeyGenerateTarget createTarget(final Properties properties, final String line) {
141 final String controlKey = "joey-gen.template.control." + line;
142 final String destKey = "joey-gen.template.dest." + line;
143 final String controlTemplate = String.valueOf(properties.getProperty(controlKey));
144 final String targetStr = String.valueOf(properties.getProperty(destKey));
145 try {
146 final String destDir = getDestDir(targetStr);
147 return new JoeyGenerateTarget(line, destDir, controlTemplate);
148 } catch (BuildException e) {
149 throw new BuildException("no destDir in property for '" + destKey + "'", e);
150 }
151 }
152
153 private static final String DEFAULT_PROPERTIES_PATH = "org/asyrinx/joey/gen/ant/task/default.properties";
154
155 private Properties getDefaultProperties() {
156 final Properties properties = new Properties();
157 final InputStream stream = this.getClass().getClassLoader().getResourceAsStream(DEFAULT_PROPERTIES_PATH);
158 try {
159 properties.load(stream);
160 } catch (IOException e) {
161 throw new BuildException(e);
162 }
163 return properties;
164 }
165
166 private String getDestDir(String targetStr) {
167 if (targetStr == null)
168 return getJavaSrcDir();
169 if ("javasrc".equals(targetStr))
170 return getJavaSrcDir();
171 if ("testsrc".equals(targetStr))
172 return getTestSrcDir();
173 if ("proj".equals(targetStr))
174 return getProjDir();
175 if ("webapp".equals(targetStr))
176 return getWebappDir();
177 throw new BuildException("Illegal targetStr '" + targetStr + "'");
178 }
179
180 protected List filesets = new ArrayList();
181
182 public void addFileset(FileSet set) {
183 filesets.add(set);
184 }
185
186 public void setContextProperties(String file) {
187 super.setContextProperties(file);
188 final Map env = super.getProject().getProperties();
189 for (Iterator i = env.keySet().iterator(); i.hasNext();) {
190 final String key = (String) i.next();
191 if (key.startsWith("joey-gen.")) {
192 String newKey = toVelocityKey(key.substring("joey-gen.".length()));
193 contextProperties.setProperty(newKey, env.get(key));
194 log.debug("joey-gen property available: " + newKey + ":" + env.get(key));
195 }
196 }
197 for (Iterator i = env.keySet().iterator(); i.hasNext();) {
198 final String key = (String) i.next();
199 if (key.startsWith("proj.")) {
200 String newKey = toVelocityKey(key);
201 contextProperties.setProperty(newKey, env.get(key));
202 log.debug("project property available: " + newKey + ":" + env.get(key));
203 }
204 }
205 }
206
207 private String toVelocityKey(String newKey) {
208 int j = newKey.indexOf(".");
209 while (j != -1) {
210 newKey = newKey.substring(0, j) + StringUtils.capitalize(newKey.substring(j + 1));
211 j = newKey.indexOf(".");
212 }
213 return newKey;
214 }
215
216 private String targetTextFile = null;
217
218 public String getTargetTextFile() {
219 return targetTextFile;
220 }
221
222 public void setTargetTextFile(File targetTextFile) {
223 try {
224 this.targetTextFile = targetTextFile.getCanonicalPath();
225 } catch (IOException e) {
226 throw new BuildException(e);
227 }
228 }
229
230 private String projDir = null;
231
232 private String javaSrcDir = null;
233
234 private String testSrcDir = null;
235
236 private String webappDir = null;
237
238 public String getJavaSrcDir() {
239 return javaSrcDir;
240 }
241
242 public String getProjDir() {
243 return projDir;
244 }
245
246 public String getTestSrcDir() {
247 return testSrcDir;
248 }
249
250 public String getWebappDir() {
251 return webappDir;
252 }
253
254 public void setJavaSrcDir(File javaSrcDir) {
255 try {
256 this.javaSrcDir = javaSrcDir.getCanonicalPath();
257 } catch (IOException e) {
258 throw new BuildException(e);
259 }
260 }
261
262 public void setProjDir(File projDir) {
263 try {
264 this.projDir = projDir.getCanonicalPath();
265 } catch (IOException e) {
266 throw new BuildException(e);
267 }
268 }
269
270 public void setTestSrcDir(File testSrcDir) {
271 try {
272 this.testSrcDir = testSrcDir.getCanonicalPath();
273 } catch (IOException e) {
274 throw new BuildException(e);
275 }
276 }
277
278 public void setWebappDir(File webappDir) {
279 try {
280 this.webappDir = webappDir.getCanonicalPath();
281 } catch (IOException e) {
282 throw new BuildException(e);
283 }
284 }
285
286 private File lastSchemaDir = null;
287
288 public File getLastSchemaDir() {
289 return lastSchemaDir;
290 }
291
292 public void setLastSchemaDir(File lastSchemaDir) {
293 this.lastSchemaDir = lastSchemaDir;
294 }
295 }
296
297 class SchemaBackup {
298
299 public void execute(Project project, List sourceFileSets, File destDir) throws IOException {
300 if (destDir.exists()) {
301 FileUtils.cleanDirectory(destDir);
302 } else {
303 destDir.mkdirs();
304 }
305 copySchemaFiles(project, sourceFileSets, destDir);
306 }
307
308 /***
309 * @param project
310 * @param sourceFileSets
311 * @param destDir
312 * @throws IOException
313 * @throws FileNotFoundException
314 */
315 private void copySchemaFiles(Project project, List sourceFileSets, File destDir) throws IOException,
316 FileNotFoundException {
317 for (int i = 0; i < sourceFileSets.size(); i++) {
318 final FileSet fs = (FileSet) sourceFileSets.get(i);
319 final File dir = fs.getDir(project);
320 final DirectoryScanner ds = fs.getDirectoryScanner(project);
321 final String[] filenNmes = ds.getIncludedFiles();
322 for (int j = 0; j < filenNmes.length; j++) {
323 final File src = new File(dir, filenNmes[j]);
324 final File dest = new File(destDir, filenNmes[j]);
325 CopyUtils.copy(new FileInputStream(src), new FileOutputStream(dest));
326 }
327 }
328 }
329
330 }