/*
* Copyright 2003-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package jetbrains.mps.classloading;
import jetbrains.mps.compiler.CompilationResultAdapter;
import jetbrains.mps.compiler.EclipseJavaCompiler;
import jetbrains.mps.make.ClassFileWriter;
import jetbrains.mps.project.facets.JavaModuleOperations;
import jetbrains.mps.reloading.CommonPaths;
import jetbrains.mps.util.NameUtil;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.eclipse.jdt.core.compiler.CategorizedProblem;
import org.eclipse.jdt.internal.compiler.ClassFile;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOError;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
// FIXME Reuse make package, remove duplication
public class TestClassFileCreator {
private static final Logger LOG = LogManager.getLogger(TestClassFileCreator.class);
private final String myClassDir;
private final String myTestClassName;
private final String myTestSourceCode;
public TestClassFileCreator(String testClassFqName, String classDir) {
this(testClassFqName, classDir, "public class " + testClassFqName + "{}");
}
public TestClassFileCreator(String testClassFqName, String classDir, String sourceCode) {
myClassDir = classDir;
myTestClassName = testClassFqName;
myTestSourceCode = sourceCode;
}
public void create() {
EclipseJavaCompiler compiler = new EclipseJavaCompiler();
compiler.addSource(myTestClassName, myTestSourceCode);
MyCompilationResultListener listener = new MyCompilationResultListener();
compiler.addCompilationResultListener(listener);
compiler.compile(JavaModuleOperations.createClassPathItem(CommonPaths.getJDKPath(), Object.class.getName()));
compiler.removeCompilationResultListener(listener);
Collection<? extends String> classPaths = listener.getClassPaths();
assert classPaths.size() == 1;
}
private class MyCompilationResultListener extends CompilationResultAdapter {
private Collection<String> myClassPaths = new ArrayList<String>();
public Collection<? extends String> getClassPaths() {
return myClassPaths;
}
@Override
public void onCompilationResult(CompilationResult result) {
if (result.hasErrors()) {
for (final CategorizedProblem cp : result.getErrors()) {
String messageString = new String(cp.getOriginatingFileName()) + " : " + cp.getMessage();
String errMsg = messageString + " (line: " + cp.getSourceLineNumber() + ")";
LOG.error("Compilation problems : " + errMsg);
}
}
}
@Override
public void onClass(ClassFile cf) {
String fqName = ClassFileWriter.convertCompoundToFqName(cf.getCompoundName());
String packageName = NameUtil.namespaceFromLongName(fqName);
File outputDir = new File(myClassDir + File.separator + NameUtil.pathFromNamespace(packageName));
if (!outputDir.exists() && !outputDir.mkdirs()) {
throw new RuntimeException("Can't create " + outputDir.getPath() + " directory");
}
String className = NameUtil.shortNameFromLongName(fqName);
File output = new File(outputDir, className + ".class");
FileOutputStream os = null;
try {
os = new FileOutputStream(output);
os.write(cf.getBytes());
} catch (IOException e) {
throw new IOError(e);
} finally {
if (os != null) {
try {
os.close();
} catch (IOException ignored) {
}
}
}
try {
myClassPaths.add(outputDir.getCanonicalPath());
} catch (IOException e) {
throw new IOError(e);
}
}
}
}