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: * Authors: S.Chassande-Barrioz.
025: *
026: */package org.objectweb.speedo.generation.compiler;
027:
028: import org.apache.tools.ant.BuildException;
029: import org.apache.tools.ant.Project;
030: import org.apache.tools.ant.taskdefs.Javac;
031: import org.apache.tools.ant.types.Path;
032: import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
033: import org.objectweb.speedo.generation.lib.NamingRules;
034: import org.objectweb.speedo.lib.Personality;
035: import org.objectweb.speedo.metadata.SpeedoClass;
036: import org.objectweb.speedo.metadata.SpeedoPackage;
037: import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
038: import org.objectweb.speedo.metadata.SpeedoIdentity;
039: import org.objectweb.speedo.api.SpeedoException;
040: import org.objectweb.speedo.api.SpeedoProperties;
041: import org.objectweb.util.monolog.api.BasicLevel;
042: import org.objectweb.util.monolog.wrapper.ant.MonologBuildListener;
043:
044: import java.io.File;
045: import java.util.Iterator;
046:
047: /**
048: * Compiles all generated <code>.java</code> files.
049: * <p>This class is based on <b>Ant</b> that is a Java-based build tool (see <a href="http://jakarta.apache.org/ant">http://jakarta.apache.org/ant</a> for more information).</p>
050: * @author S.Chassande-Barrioz
051: */
052: public class Compiler extends AbstractGeneratorComponent {
053:
054: public final static String LOGGER_NAME = SpeedoProperties.LOGGER_NAME
055: + ".generation.compiler";
056:
057: /**
058: * System separator character (e.g '/' under Unix systems)
059: */
060: public final static char SEPARATOR = File.separatorChar;
061:
062: /**
063: * Ant Task intended to java compilation
064: */
065: protected Javac compiler;
066:
067: private int toCompil;
068:
069: public Compiler(Personality p) {
070: super (p);
071: }
072:
073: public String getTitle() {
074: return "Compiling Java files...";
075: }
076:
077: public String getSummary() {
078: return toCompil + " classes compiled (" + memInfo() + ")";
079: }
080:
081: /**
082: * Initializes this Compiler.
083: * <ul><li>Initializes the Ant Task Javac so that it could compiles all generated classes.</li>
084: * <li>Sets the classpath, the source files, the destination directory and the other parameters.</li></ul>
085: */
086: public boolean init() {
087: logger = scp.loggerFactory.getLogger(LOGGER_NAME);
088: if (scp.getXmldescriptor().isEmpty())
089: return false;
090:
091: // Sets the owning Project
092: compiler = new Javac();
093: Project projectCompiler = new Project();
094: if (scp.javac != null) {
095: String c = scp.javac.getProject().getProperty(
096: "build.compiler");
097: if (c != null && c.length() > 0) {
098: projectCompiler.setProperty("build.compiler", c);
099: if (c.indexOf("eclipse") != -1) {
100: projectCompiler
101: .addBuildListener(new MonologBuildListener(
102: logger));
103: }
104: }
105: }
106: projectCompiler.init();
107: compiler.setProject(projectCompiler);
108:
109: // Sets the classpath
110: compiler.setClasspath(scp.classpath);
111:
112: // Sets the destination directory
113: File destDirs = new File(scp.output);
114: destDirs.mkdirs();
115: compiler.setDebug(true);
116: //compiler.setDebugLevel("-g:lines,vars,source");
117: compiler.setDestdir(destDirs);
118: boolean javacdebug = scp.loggerFactory.getLogger(
119: LOGGER_NAME + ".javac").isLoggable(BasicLevel.DEBUG);
120: compiler.setVerbose(javacdebug);
121: compiler.setNowarn(!javacdebug);
122: compiler.setDeprecation(javacdebug);
123: compiler.setClasspath(scp.speedoclasspath);
124:
125: // Sets the source files
126: Path srcCompiler = new Path(compiler.getProject());
127: srcCompiler.setLocation(new File(scp.output));
128:
129: logger.log(BasicLevel.DEBUG, "input: " + scp.input);
130: logger.log(BasicLevel.DEBUG, "output: " + scp.output);
131: toCompil = 0;
132: for (Iterator itDesc = scp.getXmldescriptor().values()
133: .iterator(); itDesc.hasNext();) {
134: SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc
135: .next();
136: for (Iterator itPack = desc.packages.values().iterator(); itPack
137: .hasNext();) {
138: SpeedoPackage sp = (SpeedoPackage) itPack.next();
139:
140: for (Iterator itclass = sp.classes.values().iterator(); itclass
141: .hasNext();) {
142: SpeedoClass sc = (SpeedoClass) itclass.next();
143: String className = sc.getFQName();
144:
145: String c;
146:
147: c = toJavaFileName(NamingRules
148: .fieldsName(className));
149: compiler.createInclude().setName(c);
150: logger.log(BasicLevel.DEBUG, c);
151:
152: c = toJavaFileName(NamingRules.homeName(className));
153: compiler.createInclude().setName(c);
154: logger.log(BasicLevel.DEBUG, c);
155: /*
156: c = toJavaFileName(NamingRules.fpncName(className));
157: compiler.createInclude().setName(c);
158: logger.log(BasicLevel.DEBUG, c);
159: */
160: c = toJavaFileName(NamingRules.kfpncName(className));
161: compiler.createInclude().setName(c);
162: logger.log(BasicLevel.DEBUG, c);
163:
164: c = toJavaFileName(NamingRules
165: .fqMappingName(className));
166: compiler.createInclude().setName(c);
167: logger.log(BasicLevel.DEBUG, c);
168:
169: toCompil += 2; //field + mapping
170: if (sc.jormclass.getSubClasses().isEmpty()) {
171: toCompil += 1; // [ + (fpnc | kfpnc)]
172: }
173:
174: if (sc.getIdentityType() == SpeedoIdentity.USER_ID
175: && sc.generateObjectId()) {
176: c = NamingRules.generatedObjectIdName(
177: sc.getFQName()).replace('.', '/')
178: + ".java";
179: compiler.createInclude().setName(c);
180: logger.log(BasicLevel.DEBUG, c);
181: toCompil += 1;
182: }
183: }
184: }
185: }
186: compiler.setSrcdir(srcCompiler);
187: scp.clean();
188: System.gc();
189: return true;
190: }
191:
192: private String toJavaFileName(String f) {
193: return f.replace('.', '/') + ".java";
194: }
195:
196: /**
197: * Tries to process the compilation internally.
198: *
199: * @exception SpeedoException if compilation fails
200: */
201: public void process() throws SpeedoException {
202: logger.log(BasicLevel.DEBUG, "Compiling classes (" + memInfo()
203: + ").");
204: try {
205: compiler.execute();
206: } catch (Error e) {
207: logger.log(BasicLevel.WARN, "Compilation finished ("
208: + memInfo() + ").");
209: } catch (BuildException e) {
210: throw new SpeedoException("Error during the compilation", e);
211: }
212: logger.log(BasicLevel.INFO, "Compilation finished ("
213: + memInfo() + ").");
214: }
215:
216: private String memInfo() {
217: return "free mem: "
218: + (Runtime.getRuntime().freeMemory() / (1024 * 1024))
219: + "Mo, max mem: "
220: + (Runtime.getRuntime().maxMemory() / (1024 * 1024))
221: + "Mo";
222: }
223: }
|