KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > jorm > util > lib > AntScriptGenerator


1 /**
2  * Speedo: an implementation of JDO compliant personality on top of JORM generic
3  * I/O sub-system.
4  * Copyright (C) 2001-2004 France Telecom R&D
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  *
21  *
22  * Contact: speedo@objectweb.org
23  *
24  */

25
26 package org.objectweb.jorm.util.lib;
27
28 import java.io.File JavaDoc;
29 import java.util.ArrayList JavaDoc;
30 import java.util.Arrays JavaDoc;
31 import java.util.Collection JavaDoc;
32 import java.util.Iterator JavaDoc;
33 import java.util.List JavaDoc;
34
35 import org.apache.tools.ant.DirectoryScanner;
36 import org.apache.tools.ant.Project;
37 import org.apache.tools.ant.taskdefs.MatchingTask;
38 import org.apache.tools.ant.taskdefs.UpToDate;
39 import org.apache.tools.ant.types.Path;
40 import org.apache.tools.ant.types.Reference;
41 import org.objectweb.jorm.api.PClassMapping;
42 import org.objectweb.jorm.api.PException;
43 import org.objectweb.jorm.api.PMapCluster;
44 import org.objectweb.jorm.api.PMapper;
45 import org.objectweb.jorm.mapper.rdb.lib.MapperJDBC;
46 import org.objectweb.jorm.mapper.rdb.lib.RdbScriptPMSM;
47
48 /**
49  * Generate the database creation script and write it into a file.
50  * Example of a build.xml file for the invoice example:
51  * <target name="generate.script" depends="compile">
52  * <taskdef name="generate" classname="org.objectweb.jorm.util.lib.AntScriptGenerator">
53  * <classpath refid="classpath"/>
54  * </taskdef>
55  * <generate destFile="dbCreation.sql" mapperName="rdb.postgres"
56  * SRC="${build}" classpathref="classpath"/>
57  * </target>
58  *
59  *
60  * @author Y.Bersihand
61  */

62 public class AntScriptGenerator extends MatchingTask {
63     public static final String JavaDoc SCRIPT_FILE_NAME = "script.fileName";
64     public static final String JavaDoc SCRIPT_MAPPER_NAME = "script.mapperName";
65     public static final String JavaDoc SCRIPT_DELETE_STATEMENT = "script.generate.delete";
66     public static final String JavaDoc SCRIPT_DROP_STATEMENT = "script.generate.drop";
67     public static final String JavaDoc SCRIPT_CREATE_STATEMENT = "script.generate.create";
68     public static final String JavaDoc SCRIPT_CLASS_DIR = "script.class.dir";
69     public static final String JavaDoc SCRIPT_JAR_DIR = "script.jar.dir";
70     
71     //the classpath
72
private Path classpath = null;
73     //the base directory for classes to process
74
private File JavaDoc src = null;
75     //the file in which the script is written
76
private File JavaDoc destFile = null;
77     //the mapper name
78
private String JavaDoc mapperName;
79     //if true(default value), generate sql statements
80
private boolean generateDrop = true;
81     private boolean generateDelete = true;
82     private boolean generateCreate = true;
83     
84     private boolean userDefinedIncludes = false;
85     
86     public static void main(String JavaDoc[] args) {
87         new AntScriptGenerator().execute(args);
88     }
89     
90     public void setClasspath(Path cp) {
91         if (classpath == null)
92             classpath = cp;
93         else
94             classpath.append(cp);
95     }
96     public Path getClasspath() {
97         return classpath;
98     }
99     public Path createClasspath() {
100         if (classpath == null)
101             classpath = new Path(getProject());
102         return classpath.createPath();
103     }
104     public void setClasspathRef(Reference r) {
105         createClasspath().setRefid(r);
106     }
107     
108     public void setSrc(File JavaDoc src) {
109         this.src = src;
110     }
111     public File JavaDoc getSrc() {
112         return src;
113     }
114     
115     public void setDestFile(File JavaDoc destFile) {
116         this.destFile = destFile;
117     }
118     public File JavaDoc getDestFile() {
119         return destFile;
120     }
121     
122     public void setGenerateDrop(boolean generate) {
123         this.generateDrop = generate;
124     }
125     public boolean isGenerateDrop() {
126         return generateDrop;
127     }
128     
129     public void setGenerateDelete(boolean generate) {
130         this.generateDelete = generate;
131     }
132     public boolean isGenerateDelete() {
133         return generateDelete;
134     }
135     
136     public void setGenerateCreate(boolean generate) {
137         this.generateCreate = generate;
138     }
139     public boolean isGenerateCreate() {
140         return generateCreate;
141     }
142     
143     public String JavaDoc getMapperName() {
144         return mapperName;
145     }
146     public void setMapperName(String JavaDoc mapperName) {
147         this.mapperName = mapperName;
148     }
149     
150     public DirectoryScanner getDirectoryScanner() {
151         return super.getDirectoryScanner(src);
152     }
153     
154     public void setIncludes(String JavaDoc s) {
155         super.setIncludes(s);
156         userDefinedIncludes = true;
157     }
158     
159     public void execute() {
160         //get the classes to process
161
if (!userDefinedIncludes) {
162             super.setIncludes("**/*Mapping.class");
163         }
164         List JavaDoc classesToProcess = Arrays.asList(getDirectoryScanner().getIncludedFiles());
165         if (classesToProcess == null || classesToProcess.isEmpty()) {
166             project.log("[WARN] No class files found in "
167                     + src.getAbsolutePath() + ".", Project.MSG_WARN);
168             return;
169         }
170
171         UpToDate u = new UpToDate();
172         u.setProject(project);
173         u.addSrcfiles(fileset);
174         u.setTargetFile(destFile);
175         if (u.eval()) {
176             return;
177         }
178         project.log("[INFO] Generating script for database creation...", Project.MSG_INFO);
179
180         List JavaDoc tmpClasses = new ArrayList JavaDoc(classesToProcess.size());
181         for (int i=0; i<classesToProcess.size(); i++) {
182             //format the string
183
tmpClasses.add(formatElement((String JavaDoc) classesToProcess.get(i)));
184         }
185         
186
187         RdbScriptPMSM msm = new RdbScriptPMSM(destFile.getAbsolutePath(), true);
188         try {
189             //create a mapper
190
MapperJDBC mapper = new MapperJDBC();
191             //assign a name
192
mapper.setMapperName(mapperName);
193             //start it
194
mapper.start();
195             //assign it to the msm
196
msm.setPMapper(mapper);
197             //create the file
198
msm.init();
199         } catch (PException pe) {
200             project.log(
201                     "[ERROR] Impossible to init the PMappingStructuresManager :"
202                     + pe.getMessage(), Project.MSG_ERR);
203         }
204         //get the class loader
205
ClassLoader JavaDoc cl = getClass().getClassLoader();
206
207         //make the copy
208
classesToProcess = new ArrayList JavaDoc(tmpClasses);
209         //init all the classes
210
for (int i=0; i<classesToProcess.size(); i++) {
211             //if the init is not ok,
212
//then remove the class from the list to process in the second stage
213
if(initClass((String JavaDoc)classesToProcess.get(i), msm, cl) == -1) {
214                 tmpClasses.remove(classesToProcess.get(i));
215             }
216         }
217         //copy the classes to process in the second stage in the list
218
classesToProcess = new ArrayList JavaDoc(tmpClasses);
219         //keep a list of clusters already processed
220
Collection JavaDoc clusterList = new ArrayList JavaDoc(1);
221         //generate sql statements
222
for (int i=0; i<classesToProcess.size(); i++) {
223             try {
224                 //get the class name
225
String JavaDoc classMapping = (String JavaDoc)classesToProcess.get(i);
226                 String JavaDoc className = classMapping;
227                 int index = classMapping.indexOf(PMapper.PCLASSMAPPINGAPPENDER);
228                 if (index != -1) {
229                     className = classMapping.substring(0, index);
230                 }
231                 //get the cluster
232
PMapCluster cluster = msm.getPMapCluster(className);
233                 if (cluster == null) {
234                     project.log(
235                             "[ERROR] JORM cluster is null for class: " + className,
236                             Project.MSG_ERR);
237                 }
238                 //to avoid writting the same statements many times
239
if (clusterList.contains(cluster)) {
240                     continue;
241                 } else {
242                     clusterList.add(cluster);
243                 }
244                 if (!cluster.isDefined()) {
245                     Iterator JavaDoc it = cluster.getUnResolvedDependencies().iterator();
246                     while( it.hasNext()) {
247                         String JavaDoc classUnresolved = (String JavaDoc) it.next();
248                         if (className.equals(classUnresolved)) {
249                             cluster.classDefined(className);
250                         } else {
251                             project.log(
252                                     "[INFO] Cluster for class: " + className + " is not ready : " +
253                                     cluster.getUnResolvedDependencies().toString(),
254                                     Project.MSG_INFO);
255                             initClass(classUnresolved + PMapper.PCLASSMAPPINGAPPENDER , msm, cl);
256                         }
257                     }
258                 }
259                 
260                 if (generateDrop) {
261                     cluster.deleteMappingStructures();
262                 }
263                 if (generateCreate) {
264                     cluster.createMappingStructures(true);
265                 }
266                 if (generateDelete) {
267                     cluster.deleteData();
268                 }
269             } catch(Exception JavaDoc pe) {
270                 project.log(
271                         "[ERROR] Cannot generate sql statements : " + pe.getMessage(),
272                         Project.MSG_ERR);
273             }
274         }
275         project.log("[INFO] File generated: " + destFile.getAbsolutePath(), Project.MSG_INFO);
276     }
277     
278     public void execute(String JavaDoc[] args){
279         //Check parameter
280
if (args.length == 0) {
281             usage("You must specify classes to generate script for.");
282         }
283         //get the fileName
284
destFile = new File JavaDoc(System.getProperty(SCRIPT_FILE_NAME));
285         if (destFile == null) {
286             usage("You must specify a destination file.");
287         }
288         //get the mapperName
289
mapperName = System.getProperty(SCRIPT_MAPPER_NAME);
290         if (mapperName == null) {
291             usage("You must specify a mapper name.");
292         }
293         //get the delete
294
String JavaDoc deleteString = System.getProperty(SCRIPT_DELETE_STATEMENT);
295         if (deleteString != null) {
296             generateDelete = new Boolean JavaDoc(deleteString).booleanValue();
297         }
298         //get the drop
299
String JavaDoc dropString = System.getProperty(SCRIPT_DROP_STATEMENT);
300         if (dropString != null) {
301             generateDrop = new Boolean JavaDoc(dropString).booleanValue();
302         }
303         //get the create
304
String JavaDoc createString = System.getProperty(SCRIPT_CREATE_STATEMENT);
305         if (createString != null) {
306             generateCreate = new Boolean JavaDoc(createString).booleanValue();
307         }
308     }
309     
310     private int initClass(String JavaDoc className,
311             RdbScriptPMSM msm,
312             ClassLoader JavaDoc classLoader) {
313         java.lang.Class JavaDoc currentClass = null;
314         try {
315             //load the PClassMapping
316
currentClass = classLoader.loadClass(className);
317             //create a new instance
318
Object JavaDoc o = currentClass.newInstance();
319             //init the PClassMapping
320
PClassMapping pcm = (PClassMapping) o;
321             pcm.init(msm);
322         } catch (ClassNotFoundException JavaDoc e) {
323             project.log(
324                     "[ERROR] Impossible to load the persistent class '"
325                     + className + "' from the classpath: " + e.getMessage(), Project.MSG_ERR);
326             return -1;
327         } catch (IllegalAccessException JavaDoc iae) {
328             project.log("[ERROR] Impossible to have access to a new instance of the class '"
329                     + className + ": " + iae.getMessage(), Project.MSG_ERR);
330             return -1;
331         } catch (InstantiationException JavaDoc ie) {
332             project.log("[ERROR] Impossible to get a new instance of the class '"
333                     + className + ": " + ie.getMessage(), Project.MSG_ERR);
334             return -1;
335         } catch (PException pe) {
336             project.log("[ERROR] Impossible to init the PClassMapping class '"
337                     + className + ": " + pe.getMessage(), Project.MSG_ERR);
338             return -1;
339         }
340         return 1;
341     }
342     
343     private void usage(String JavaDoc msg) {
344         project.log(msg, Project.MSG_ERR);
345         project.log("Usage: ", Project.MSG_ERR);
346         project.log("\tRdbScriptGeneration (<class name to generate>)*", Project.MSG_ERR);
347         project.log("\t\t-D"+SCRIPT_CLASS_DIR+"=<generated classes directory>", Project.MSG_ERR);
348         project.log("\t\t-D"+SCRIPT_JAR_DIR+"=<added jar directory>", Project.MSG_ERR);
349         project.log("\t\t[-D"+SCRIPT_FILE_NAME+"=<file name>]", Project.MSG_ERR);
350         project.log("\t\t[-D"+SCRIPT_MAPPER_NAME+"=<mapper name>]", Project.MSG_ERR);
351         project.log("\t\t[-D"+SCRIPT_DELETE_STATEMENT+"=<true|false>]", Project.MSG_ERR);
352         project.log("\t\t[-D"+SCRIPT_DROP_STATEMENT+"=<true|false>]", Project.MSG_ERR);
353         project.log("\t\t[-D"+SCRIPT_CREATE_STATEMENT+"=<true|false>]", Project.MSG_ERR);
354         System.exit(1);
355     }
356     
357     /**
358      * Remove the file extension
359      * and replace the separator / or \ by .
360      * for element i of the list
361      */

362     public static String JavaDoc formatElement(String JavaDoc element) {
363         int index = element.lastIndexOf(".");
364         if (index != -1) {
365             // remove the file extension
366
element = element.substring(0, index);
367         }
368         if (element.indexOf("\\") != -1) {
369             //for windows path
370
element = replaceString("\\", ".", element);
371         } else {
372             //for unix path
373
element = replaceString("/", ".", element);
374         }
375         return element;
376     }
377     
378     public static String JavaDoc replaceString(String JavaDoc old, String JavaDoc neo, String JavaDoc str) {
379         if (str == null || str.length() == 0) {
380             return str;
381         }
382         int i = 0;
383         int oldSize = old.length();
384         int neoSize = neo.length();
385         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(str);
386         int begin = 0;
387         int idx = sb.indexOf(old, begin);
388         while(idx != -1) {
389             sb.delete(idx, idx + oldSize);
390             sb.insert(idx, neo);
391             begin = idx + neoSize;
392             if (begin < sb.length()) {
393                 idx = sb.indexOf(old, begin);
394             } else {
395                 idx = -1;
396             }
397         }
398         
399         return sb.toString();
400     }
401 }
402
Popular Tags