001: /**
002: * Speedo: an implementation of JDO compliant personality on top of JORM generic
003: * I/O sub-system.
004: * Copyright (C) 2001-2005 France Telecom R&D
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation; either
009: * version 2 of the License, or (at your option) any later version.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: * You should have received a copy of the GNU Lesser General Public
017: * License along with this library; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019: *
020: *
021: *
022: * Contact: speedo@objectweb.org
023: *
024: */package org.objectweb.speedo.ant;
025:
026: import org.apache.tools.ant.Project;
027: import org.apache.tools.ant.taskdefs.UpToDate;
028: import org.objectweb.jorm.mapper.rdb.lib.PMapperRdb;
029: import org.objectweb.jorm.util.lib.AntScriptGenerator;
030: import org.objectweb.speedo.api.SpeedoRuntimeException;
031: import org.objectweb.speedo.mapper.lib.Object2StringSerializer;
032: import org.objectweb.speedo.metadata.SpeedoIndex;
033: import org.objectweb.speedo.mim.api.HomeItf;
034: import org.objectweb.speedo.sequence.api.SpeedoSequenceItf;
035: import org.objectweb.speedo.sequence.lib.SpeedoSequence;
036:
037: import java.io.IOException;
038: import java.util.ArrayList;
039: import java.util.Iterator;
040: import java.util.List;
041: import java.util.Properties;
042: import java.util.Set;
043:
044: /**
045: * This ant task extends the AntScriptGenerator ant task provided by JORM.
046: * It enables to generate sql statements related to sequences and indexes.
047: *
048: * @author Y.Bersihand
049: */
050: public class AntSpeedoScriptGenerator extends AntScriptGenerator {
051:
052: //the list of SpeedoSequence(s)
053: protected List sequences = new ArrayList(1);
054:
055: //the list of SpeedoIndexe(s)
056: protected List indexes = new ArrayList(1);
057:
058: public static void main(String[] args) {
059: new AntScriptGenerator().execute(args);
060: }
061:
062: public void execute() {
063: log("[INFO] Generating script for database creation...",
064: Project.MSG_INFO);
065: long timeSpent = System.currentTimeMillis();
066: //execute the jorm ant task
067: super .execute();
068: UpToDate u = new UpToDate();
069: u.setProject(getProject());
070: u.addSrcfiles(fileset);
071: u.setTargetFile(destFile);
072: if (u.eval()) {
073: return;
074: }
075:
076: //then the speedo part
077: //1- sequence (if any)
078: try {
079: //get the class loader
080: ClassLoader classLoader = getClass().getClassLoader();
081: //list of jmi files already deserialized
082: List fileNames = new ArrayList(1);
083: //for each class to process selected by the super.execute() method
084: for (int i = 0; i < classesToProcess.size(); i++) {
085: try {
086: //get the class name
087: String classMapping = (String) classesToProcess
088: .get(i);
089: //get the class properties
090: Properties classProperties = getClassProperties(
091: classMapping, classLoader);
092: //get the file to deserialize
093: String fileName = classProperties
094: .getProperty(Object2StringSerializer.DESC_FILE_NAME_PROP);
095: //if the file has not already been processed
096: if (!fileNames.contains(fileName)) {
097: //add it to the list
098: fileNames.add(fileName);
099: //and get the sequences and indexes defined
100: addSequencesAndIndexes(fileName,
101: classProperties, classLoader);
102: }
103: } catch (Exception pe) {
104: pe.printStackTrace();
105: log(
106: "[ERROR] Cannot generate sequence statements : "
107: + pe.getMessage(), Project.MSG_ERR);
108: }
109: }
110: //get the index sql statements
111: writeIndexesStatements();
112: //then the sequence sql statements
113: writeSequencesStatements();
114:
115: //then close the file writer
116: if (msm != null) {
117: msm.getFileWriter().close();
118: }
119: log("[INFO] File generated: " + destFile.getAbsolutePath(),
120: Project.MSG_INFO);
121:
122: } catch (Exception e) {
123: e.printStackTrace();
124: }
125: timeSpent = System.currentTimeMillis() - timeSpent;
126: log("[INFO] All done in " + duration2str(timeSpent),
127: Project.MSG_INFO);
128: }
129:
130: /**
131: * Write the sequences sql statements to add to the script.
132: */
133: private void writeSequencesStatements() throws IOException {
134: if (!sequences.isEmpty()) {
135: PMapperRdb mapper = (PMapperRdb) msm.getPMapper();
136: msm.getFileWriter().write(
137: "----------- SEQUENCES ---------\n");
138: for (Iterator it = sequences.iterator(); it.hasNext();) {
139: SpeedoSequence s = (SpeedoSequence) it.next();
140: log("[DEBUG] Sequence " + s.datastoreName,
141: Project.MSG_DEBUG);
142: //just write the sql sequences
143: if (s.datastoreName != null && s.datastoreName != "") {
144: if (isGenerateDrop()) {
145: msm.getFileWriter().write(
146: mapper.getRdbAdapter().getDropSequence(
147: s.datastoreName)
148: + "\n");
149: }
150: if (isGenerateCreate()) {
151: msm.getFileWriter().write(
152: mapper.getRdbAdapter()
153: .getCreateSequence(
154: s.datastoreName,
155: s.start, s.increment,
156: s.cache)
157: + "\n");
158: }
159: }
160: }
161: }
162: }
163:
164: /**
165: * Write the indexes sql statements to add to the script.
166: */
167: private void writeIndexesStatements() throws IOException {
168: if (!indexes.isEmpty()) {
169: PMapperRdb mapper = (PMapperRdb) msm.getPMapper();
170: msm.getFileWriter()
171: .write("----------- INDEXES ---------\n");
172: for (Iterator it = indexes.iterator(); it.hasNext();) {
173: SpeedoIndex si = (SpeedoIndex) it.next();
174: log("[DEBUG] SpeedoIndex " + si.name, Project.MSG_DEBUG);
175: if (isGenerateDrop()) {
176: msm.getFileWriter().write(
177: mapper.getRdbAdapter().getDropIndex(
178: si.name, si.table)
179: + "\n");
180: }
181: if (isGenerateCreate()) {
182: if (si.columnNames != null
183: && si.columnNames.size() != 0) {
184: msm.getFileWriter().write(
185: mapper.getRdbAdapter().getCreateIndex(
186: si.name, si.table,
187: si.columnNames, si.unique)
188: + "\n");
189: } else {
190: log("[INFO] Index " + si.name
191: + " has not been processed.",
192: Project.MSG_INFO);
193: }
194: }
195: }
196: }
197: }
198:
199: /**
200: * Get the class properties.
201: */
202: private Properties getClassProperties(String className,
203: ClassLoader classLoader) {
204: try {
205: //load the PClassMapping
206: java.lang.Class currentClass = classLoader
207: .loadClass(className);
208: //create a new instance
209: Object o = currentClass.newInstance();
210: return ((HomeItf) o).getClassProperties();
211: } catch (ClassNotFoundException e) {
212: log("[ERROR] Impossible to load the persistent class '"
213: + className + "' from the classpath: "
214: + e.getMessage(), Project.MSG_ERR);
215: } catch (IllegalAccessException iae) {
216: log(
217: "[ERROR] Impossible to have access to a new instance of the class '"
218: + className + ": " + iae.getMessage(),
219: Project.MSG_ERR);
220: } catch (InstantiationException ie) {
221: log(
222: "[ERROR] Impossible to get a new instance of the class '"
223: + className + ": " + ie.getMessage(),
224: Project.MSG_ERR);
225: }
226: return null;
227: }
228:
229: /**
230: * Complete the list of sequences and indexes deserialized from the fn file.
231: */
232: private void addSequencesAndIndexes(String fileName,
233: Properties classProperties, ClassLoader classLoader) {
234: // deserialize the JMI from the file
235: Set mos = null;
236: try {
237: mos = (Set) Object2StringSerializer.deserialize(fileName,
238: classLoader, null);
239: } catch (Exception e) {
240: throw new SpeedoRuntimeException(
241: "Impossible to load the jorm meta "
242: + "information from the file "
243: + fileName
244: + "' (You must use the same Speedo version for the"
245: + " enhancement and for the runtime): ", e);
246: }
247: //select only the sequences and indexes and deserialize them
248: for (Iterator it = mos.iterator(); it.hasNext();) {
249: Object o = it.next();
250: if (o instanceof SpeedoSequenceItf) {
251: // add the sequence to the list of sequences
252: sequences.add(o);
253: } else if (o instanceof SpeedoIndex) {
254: // add the index to the list of indexes
255: indexes.add(o);
256: }
257: }
258: }
259:
260: //---------------- UTIL METHOD ---------------------------//
261:
262: public static String duration2str(final long t) {
263: long time = t;
264: StringBuffer sb = new StringBuffer();
265: sb.insert(0, "ms");
266: sb.insert(0, time % 1000);
267:
268: time = time / 1000;
269: if (time > 0) {
270: sb.insert(0, "s ");
271: sb.insert(0, time % 60);
272:
273: time = time / 60;
274: if (time > 0) {
275: sb.insert(0, "m ");
276: sb.insert(0, time % 60);
277: }
278: }
279: return sb.toString();
280: }
281:
282: }
|