/**
* Speedo: an implementation of JDO compliant personality on top of JORM generic
* I/O sub-system.
* Copyright (C) 2001-2005 France Telecom R&D
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
*
* Contact: speedo@objectweb.org
*
* Authors: S.Chassande-Barrioz.
*
*/
package org.objectweb.speedo.generation.compiler;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.taskdefs.Javac;
import org.apache.tools.ant.types.Path;
import org.objectweb.speedo.generation.lib.AbstractGeneratorComponent;
import org.objectweb.speedo.generation.lib.NamingRules;
import org.objectweb.speedo.lib.Personality;
import org.objectweb.speedo.metadata.SpeedoClass;
import org.objectweb.speedo.metadata.SpeedoPackage;
import org.objectweb.speedo.metadata.SpeedoXMLDescriptor;
import org.objectweb.speedo.metadata.SpeedoIdentity;
import org.objectweb.speedo.api.SpeedoException;
import org.objectweb.speedo.api.SpeedoProperties;
import org.objectweb.util.monolog.api.BasicLevel;
import org.objectweb.util.monolog.wrapper.ant.MonologBuildListener;
import java.io.File;
import java.util.Iterator;
/**
* Compiles all generated <code>.java</code> files.
* <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>
* @author S.Chassande-Barrioz
*/
public class Compiler extends AbstractGeneratorComponent {
public final static String LOGGER_NAME
= SpeedoProperties.LOGGER_NAME + ".generation.compiler";
/**
* System separator character (e.g '/' under Unix systems)
*/
public final static char SEPARATOR = File.separatorChar;
/**
* Ant Task intended to java compilation
*/
protected Javac compiler;
private int toCompil;
public Compiler(Personality p) {
super(p);
}
public String getTitle() {
return "Compiling Java files...";
}
public String getSummary() {
return toCompil + " classes compiled (" + memInfo() + ")";
}
/**
* Initializes this Compiler.
* <ul><li>Initializes the Ant Task Javac so that it could compiles all generated classes.</li>
* <li>Sets the classpath, the source files, the destination directory and the other parameters.</li></ul>
*/
public boolean init() {
logger = scp.loggerFactory.getLogger(LOGGER_NAME);
if (scp.getXmldescriptor().isEmpty())
return false;
// Sets the owning Project
compiler = new Javac();
Project projectCompiler = new Project();
if (scp.javac != null) {
String c = scp.javac.getProject().getProperty("build.compiler");
if (c != null && c.length() >0) {
projectCompiler.setProperty("build.compiler", c);
if (c.indexOf("eclipse") != -1) {
projectCompiler.addBuildListener(new MonologBuildListener(logger));
}
}
}
projectCompiler.init();
compiler.setProject(projectCompiler);
// Sets the classpath
compiler.setClasspath(scp.classpath);
// Sets the destination directory
File destDirs = new File(scp.output);
destDirs.mkdirs();
compiler.setDebug(true);
//compiler.setDebugLevel("-g:lines,vars,source");
compiler.setDestdir(destDirs);
boolean javacdebug = scp.loggerFactory.getLogger(LOGGER_NAME + ".javac")
.isLoggable(BasicLevel.DEBUG);
compiler.setVerbose(javacdebug);
compiler.setNowarn(!javacdebug);
compiler.setDeprecation(javacdebug);
compiler.setClasspath(scp.speedoclasspath);
// Sets the source files
Path srcCompiler = new Path(compiler.getProject());
srcCompiler.setLocation(new File(scp.output));
logger.log(BasicLevel.DEBUG, "input: " + scp.input);
logger.log(BasicLevel.DEBUG, "output: " + scp.output);
toCompil = 0;
for (Iterator itDesc = scp.getXmldescriptor().values().iterator(); itDesc.hasNext();) {
SpeedoXMLDescriptor desc = (SpeedoXMLDescriptor) itDesc.next();
for (Iterator itPack = desc.packages.values().iterator(); itPack.hasNext();) {
SpeedoPackage sp = (SpeedoPackage) itPack.next();
for (Iterator itclass = sp.classes.values().iterator(); itclass.hasNext();) {
SpeedoClass sc = (SpeedoClass) itclass.next();
String className = sc.getFQName();
String c;
c = toJavaFileName(NamingRules.fieldsName(className));
compiler.createInclude().setName(c);
logger.log(BasicLevel.DEBUG, c);
c = toJavaFileName(NamingRules.homeName(className));
compiler.createInclude().setName(c);
logger.log(BasicLevel.DEBUG, c);
/*
c = toJavaFileName(NamingRules.fpncName(className));
compiler.createInclude().setName(c);
logger.log(BasicLevel.DEBUG, c);
*/
c = toJavaFileName(NamingRules.kfpncName(className));
compiler.createInclude().setName(c);
logger.log(BasicLevel.DEBUG, c);
c = toJavaFileName(NamingRules.fqMappingName(className));
compiler.createInclude().setName(c);
logger.log(BasicLevel.DEBUG, c);
toCompil += 2; //field + mapping
if (sc.jormclass.getSubClasses().isEmpty()) {
toCompil += 1; // [ + (fpnc | kfpnc)]
}
if (sc.getIdentityType() == SpeedoIdentity.USER_ID
&& sc.generateObjectId()) {
c = NamingRules.generatedObjectIdName(sc.getFQName())
.replace('.', '/') + ".java";
compiler.createInclude().setName(c);
logger.log(BasicLevel.DEBUG, c);
toCompil += 1;
}
}
}
}
compiler.setSrcdir(srcCompiler);
scp.clean();
System.gc();
return true;
}
private String toJavaFileName(String f) {
return f.replace('.', '/') + ".java";
}
/**
* Tries to process the compilation internally.
*
* @exception SpeedoException if compilation fails
*/
public void process() throws SpeedoException {
logger.log(BasicLevel.DEBUG, "Compiling classes (" + memInfo() + ").");
try {
compiler.execute();
} catch (Error e) {
logger.log(BasicLevel.WARN, "Compilation finished (" + memInfo() + ").");
} catch (BuildException e) {
throw new SpeedoException("Error during the compilation", e);
}
logger.log(BasicLevel.INFO, "Compilation finished (" + memInfo() + ").");
}
private String memInfo() {
return "free mem: " +
(Runtime.getRuntime().freeMemory() / (1024 * 1024))
+ "Mo, max mem: "
+ (Runtime.getRuntime().maxMemory() / (1024 * 1024))+ "Mo";
}
}