1 package org.appfuse.mojo.exporter;
2
3
4 import org.apache.commons.io.FileUtils;
5 import org.apache.maven.artifact.Artifact;
6 import org.apache.maven.plugin.MojoExecutionException;
7 import org.apache.maven.plugin.MojoFailureException;
8 import org.appfuse.mojo.HibernateExporterMojo;
9 import org.appfuse.tool.AppFuseExporter;
10 import org.appfuse.tool.ArtifactInstaller;
11 import org.codehaus.plexus.components.interactivity.Prompter;
12 import org.codehaus.plexus.components.interactivity.PrompterException;
13 import org.hibernate.tool.hbm2x.Exporter;
14 import org.xml.sax.Attributes;
15 import org.xml.sax.InputSource;
16 import org.xml.sax.SAXException;
17 import org.xml.sax.helpers.DefaultHandler;
18
19 import javax.xml.parsers.SAXParser;
20 import javax.xml.parsers.SAXParserFactory;
21 import java.io.BufferedReader;
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import java.io.InputStreamReader;
26 import java.io.StringReader;
27 import java.util.Collection;
28
29
30
31
32
33
34
35
36
37
38
39 public class AppFuseGeneratorMojo extends HibernateExporterMojo {
40 boolean generateCoreOnly;
41 boolean generateWebOnly;
42 String pojoName;
43
44
45
46
47
48
49 Prompter prompter;
50
51
52
53
54
55
56
57
58
59
60
61
62
63 private String destinationDirectory;
64
65
66
67
68
69
70
71 private String sourceDirectory;
72
73
74
75
76
77
78 private boolean disableInstallation;
79
80
81
82
83
84 private boolean genericCore;
85
86
87
88
89
90 private String templateDirectory;
91
92
93
94
95
96 private String fullPath = null;
97
98
99
100
101 public AppFuseGeneratorMojo() {
102 addDefaultComponent("target/appfuse/generated-sources", "configuration", false);
103 addDefaultComponent("target/appfuse/generated-sources", "annotationconfiguration", true);
104 }
105
106
107
108
109
110
111
112
113 public String getName() {
114 return "gen";
115 }
116
117 @Override
118 public void execute() throws MojoExecutionException, MojoFailureException {
119
120 if (getProject().getPackaging().equalsIgnoreCase("pom")) {
121 String errorMsg = "[ERROR] This plugin cannot be run from a pom project, please run it from a jar or war project (i.e. core or web).";
122
123 throw new MojoFailureException(errorMsg);
124 }
125
126 pojoName = System.getProperty("entity");
127
128 if (pojoName == null) {
129 try {
130 pojoName = prompter.prompt("What is the name of your pojo (i.e. Person)?");
131 } catch (PrompterException pe) {
132 pe.printStackTrace();
133 }
134 }
135
136 if (pojoName == null || "".equals(pojoName.trim())) {
137 throw new MojoExecutionException("You must specify an entity name to continue.");
138 }
139
140
141 if (pojoName.contains(".")) {
142 if (pojoName.indexOf("model") == -1) {
143 throw new MojoExecutionException("You must specify 'model' as the last package in your entity name.");
144 }
145 fullPath = pojoName.substring(0, pojoName.indexOf(".model"));
146
147 fullPath = fullPath.replace("~", getProject().getGroupId());
148
149 pojoName = pojoName.substring(pojoName.lastIndexOf(".") + 1);
150 log("Package name set to: " + fullPath);
151 }
152
153 String daoFramework = getProject().getProperties().getProperty("dao.framework");
154
155
156
157 if (daoFramework.indexOf("jpa") > -1) {
158 getComponentProperties().put("implementation", "jpaconfiguration");
159 checkEntityExists();
160 }
161
162
163
164 if (getProject().getPackaging().equals("war") && getProject().hasParent()) {
165
166 String moduleName = (String) getProject().getParent().getModules().get(0);
167 String pathToParent = getProject().getOriginalModel().getParent().getRelativePath();
168 pathToParent = pathToParent.substring(0, pathToParent.lastIndexOf('/') + 1);
169 log("Assuming '" + moduleName + "' has hibernate.cfg.xml in its src/main/resources directory");
170 getComponentProperties().put("configurationfile",
171 getProject().getBasedir() + "/" + pathToParent + moduleName + "/src/main/resources/hibernate.cfg.xml");
172 }
173
174 if (getComponentProperty("configurationfile") == null) {
175 getComponentProperties().put("configurationfile", "src/main/resources/hibernate.cfg.xml");
176 }
177
178
179 String hibernateConfig = getComponentProperty("configurationfile");
180
181 if (daoFramework.equals("hibernate")) {
182 try {
183 String hibernateCfgXml = FileUtils.readFileToString(new File(hibernateConfig));
184 addEntityToHibernateCfgXml(hibernateCfgXml);
185 } catch (IOException io) {
186 throw new MojoFailureException(io.getMessage());
187 }
188 }
189
190
191 if (daoFramework.equalsIgnoreCase("ibatis")) {
192 try {
193 String pomAsString = FileUtils.readFileToString(new File("pom.xml"));
194 if (pomAsString.contains("<implementation>annotationconfiguration</implementation>")) {
195
196 log("Creating hibernate.cfg.xml from template...");
197 String hibernateCfgXml;
198 File existingConfig = new File(hibernateConfig);
199 if (!existingConfig.exists()) {
200 InputStream in = this.getClass().getResourceAsStream("/appfuse/dao/ibatis/hibernate.cfg.ftl");
201 StringBuffer configFile = new StringBuffer();
202 try {
203 InputStreamReader isr = new InputStreamReader(in);
204 BufferedReader reader = new BufferedReader(isr);
205 String line;
206 while ((line = reader.readLine()) != null) {
207 configFile.append(line).append("\n");
208 }
209 reader.close();
210 } catch (IOException io) {
211 throw new MojoFailureException(io.getMessage());
212 }
213
214 hibernateCfgXml = configFile.toString();
215 } else {
216 hibernateCfgXml = FileUtils.readFileToString(existingConfig);
217 }
218
219 addEntityToHibernateCfgXml(hibernateCfgXml);
220 } else {
221 log("[WARN] Detected JPA configuration");
222 }
223 } catch (IOException io) {
224 io.printStackTrace();
225 getLog().error(io.getMessage());
226 }
227 }
228
229 super.execute();
230 }
231
232
233
234
235 protected Exporter configureExporter(Exporter exp) throws MojoExecutionException {
236
237 System.setProperty("appfuse.entity", pojoName);
238
239
240 getProject().addCompileSourceRoot(new File(getComponent().getOutputDirectory()).getPath());
241
242
243 AppFuseExporter exporter = (AppFuseExporter) super.configureExporter(exp);
244 exporter.getProperties().setProperty("ejb3", getComponentProperty("ejb3", "true"));
245 exporter.getProperties().setProperty("jdk5", getComponentProperty("jdk5", "true"));
246
247 if (generateCoreOnly) {
248 exporter.getProperties().setProperty("generate-core", "true");
249 } else if (generateWebOnly) {
250 exporter.getProperties().setProperty("generate-web", "true");
251 }
252
253 String rootPackage = (fullPath != null) ? fullPath : getProject().getGroupId();
254
255
256 exporter.getProperties().setProperty("basepackage", rootPackage);
257 exporter.getProperties().setProperty("daoframework", getProject().getProperties().getProperty("dao.framework"));
258
259 String webFramework = (getProject().getProperties().containsKey("web.framework")) ?
260 getProject().getProperties().getProperty("web.framework") : "";
261
262 exporter.getProperties().setProperty("webframework", webFramework);
263
264 exporter.getProperties().setProperty("packaging", getProject().getPackaging());
265 exporter.getProperties().setProperty("genericcore", String.valueOf(genericCore));
266
267 if (templateDirectory != null) {
268 exporter.getProperties().setProperty("templatedirectory", templateDirectory);
269 }
270
271 if (isFullSource())
272 exporter.getProperties().setProperty("appfusepackage", rootPackage);
273 else {
274 exporter.getProperties().setProperty("appfusepackage", "org.appfuse");
275 }
276
277
278 boolean hasSecurity = false;
279 if (getProject().getPackaging().equals("war")) {
280 Collection<File> sourceFiles = FileUtils.listFiles(getProject().getBasedir(),new String[]{"xml"}, true);
281 for (File file : sourceFiles) {
282 if (file.getPath().contains("security.xml")) {
283 hasSecurity = true;
284 break;
285 }
286 }
287 }
288
289 exporter.getProperties().setProperty("hasSecurity", String.valueOf(hasSecurity));
290
291
292 if (webFramework.equals("tapestry")) {
293 boolean useMainMenu = true;
294 Collection<File> sourceFiles = FileUtils.listFiles(getProject().getBasedir(),new String[]{"java"}, true);
295 for (File file : sourceFiles) {
296 if (file.getPath().contains("Home.java")) {
297 useMainMenu = false;
298 break;
299 }
300 }
301 exporter.getProperties().setProperty("useMainMenu", String.valueOf(useMainMenu));
302 }
303
304 return exporter;
305 }
306
307
308
309
310
311
312 @Override
313 protected void doExecute() throws MojoExecutionException {
314 super.doExecute();
315
316 if (System.getProperty("disableInstallation") != null) {
317 disableInstallation = Boolean.valueOf(System.getProperty("disableInstallation"));
318 }
319
320
321 if (!disableInstallation) {
322 ArtifactInstaller installer = new ArtifactInstaller(getProject(), pojoName, sourceDirectory, destinationDirectory, genericCore);
323 installer.execute();
324 }
325 }
326
327
328
329
330
331
332 protected Exporter createExporter() {
333 return new AppFuseExporter();
334 }
335
336 protected void setGenerateCoreOnly(boolean generateCoreOnly) {
337 this.generateCoreOnly = generateCoreOnly;
338 }
339
340 protected void setGenerateWebOnly(boolean generateWebOnly) {
341 this.generateWebOnly = generateWebOnly;
342 }
343
344 private void log(String msg) {
345 getLog().info("[AppFuse] " + msg);
346 }
347
348 private void addEntityToHibernateCfgXml(String hibernateCfgXml) throws MojoFailureException {
349 String className = (fullPath != null) ? fullPath : getProject().getGroupId();
350
351 className += ".model." + pojoName;
352 log("Constructed class name : " + className);
353
354 POJOSearcher pojoSearcher = new POJOSearcher(hibernateCfgXml);
355 if (!pojoSearcher.searchForPojo(pojoName)) {
356
357 checkEntityExists();
358
359 hibernateCfgXml = hibernateCfgXml.replace("</session-factory>",
360 " <mapping class=\"" + className + "\"/>"
361 + "\n </session-factory>");
362 log("Adding '" + pojoName + "' to hibernate.cfg.xml...");
363 }
364
365 hibernateCfgXml = hibernateCfgXml.replaceAll("\\$\\{appfusepackage}",
366 (isFullSource()) ? getProject().getGroupId() : "org.appfuse");
367
368 try {
369 FileUtils.writeStringToFile(new File(
370 getComponentProperty("configurationfile", "src/main/resources/hibernate.cfg.xml")), hibernateCfgXml);
371 } catch (IOException io) {
372 throw new MojoFailureException(io.getMessage());
373 }
374 }
375
376 private void checkEntityExists() throws MojoFailureException {
377
378 if (!"false".equals(System.getProperty("entity.check"))) {
379 final String FILE_SEP = System.getProperty("file.separator");
380 String pathToModelPackage = "src" + FILE_SEP + "main" + FILE_SEP + "java" + FILE_SEP;
381 if (getProject().getPackaging().equals("war") && getProject().hasParent()) {
382 String moduleName = (String) getProject().getParent().getModules().get(0);
383 String pathToParent = getProject().getOriginalModel().getParent().getRelativePath();
384 pathToParent = pathToParent.substring(0, pathToParent.lastIndexOf('/') + 1);
385 pathToParent = pathToParent.replaceAll("/", FILE_SEP);
386 pathToModelPackage = getProject().getBasedir() + FILE_SEP + pathToParent + moduleName + "/" + pathToModelPackage;
387 }
388
389
390 String groupIdAsPath = getProject().getGroupId().replace(".", FILE_SEP);
391
392 String fullPathPackage = pathToModelPackage + groupIdAsPath;
393 if (fullPath != null) {
394 fullPathPackage += FILE_SEP + fullPath.replace(".", FILE_SEP);
395 } else {
396 fullPathPackage += FILE_SEP + "model";
397 }
398 log("Looking for entity in " + fullPathPackage);
399
400 File modelPackage = new File(fullPathPackage);
401 boolean entityExists = false;
402
403 if (modelPackage.exists()) {
404 String[] entities = modelPackage.list();
405 for (String entity : entities) {
406 log("Found '" + entity + "' in model package...");
407 if (entity.contains(pojoName + ".java")) {
408 entityExists = true;
409 break;
410 }
411 }
412 } else {
413 getLog().error("The path '" + fullPathPackage + groupIdAsPath + FILE_SEP + "model' does not exist!");
414 }
415
416 if (!entityExists) {
417 throw new MojoFailureException("[ERROR] The '" + pojoName + "' entity does not exist in '" + modelPackage + "'.");
418 } else {
419
420 try {
421 File pojoFile = new File(modelPackage + FILE_SEP + pojoName + ".java");
422 String entityAsString = FileUtils.readFileToString(pojoFile);
423 if (!entityAsString.contains("@Entity")) {
424 String msg = "Entity '" + pojoName + "' found, but it doesn't contain an @Entity annotation. Please add one.";
425 throw new MojoFailureException(msg);
426 }
427 } catch (IOException io) {
428 throw new MojoFailureException("[ERROR] Class '" + pojoName + ".java' not found in '" + modelPackage + "'");
429 }
430 }
431 }
432 }
433
434 public class POJOSearcher extends DefaultHandler {
435 private String pojoName;
436 private boolean foundPojo;
437 private String xmlString;
438
439 public POJOSearcher(String xmlString) {
440 this.xmlString = xmlString;
441 }
442
443 public boolean searchForPojo(String pojoName) {
444 this.pojoName = pojoName;
445 this.foundPojo = false;
446
447 SAXParserFactory spf = SAXParserFactory.newInstance();
448 try {
449 SAXParser sp = spf.newSAXParser();
450
451
452 sp.parse(new InputSource(new StringReader(xmlString)), this);
453 } catch (Exception ex) {
454 System.out.println(ex.getMessage());
455 ex.printStackTrace();
456 }
457
458 return foundPojo;
459 }
460
461 @Override
462 public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
463 super.startElement(uri, localName, name, attributes);
464 if (name.equals("mapping")) {
465 String classValue = attributes.getValue("class");
466 if (classValue != null) {
467 if (classValue.endsWith(pojoName)) {
468 foundPojo = true;
469 }
470 }
471 }
472 }
473 }
474 }