blob: f33b6ce91854639c405b7db7a1d8f753be5bd0e1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016, 2017 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.qvtd.compiler.internal.utilities;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.examples.codegen.dynamic.ExplicitClassLoader;
import org.eclipse.ocl.examples.codegen.dynamic.JavaFileUtil;
import org.eclipse.ocl.examples.codegen.dynamic.OCL2JavaFileObject;
/**
* JavaSourceFileObject supports use of a File as a Java compilation unit.
*
* The compileClasses utility method support compilation of a source package and subpackages.
*/
public final class JavaSourceFileObject extends SimpleJavaFileObject
{
public static @Nullable String compileClass(@NonNull String sourcePath, @NonNull String javaCodeSource, @NonNull String objectPath, @Nullable List<@NonNull String> classpathProjects) throws IOException {
List<@NonNull JavaFileObject> compilationUnits = Collections.singletonList(new OCL2JavaFileObject(sourcePath, javaCodeSource));
return JavaFileUtil.compileClasses(compilationUnits, sourcePath, objectPath, classpathProjects);
}
/**
* Compile all *.java files on sourcePath to objectPath.
* e.g. from ../xyzzy/src/a/b/c to ../xyzzy/bin
*/
public static @Nullable String compileClasses(@NonNull String sourcePath, @NonNull String objectPath, @Nullable List<@NonNull String> classpathProjects) throws IOException {
try {
List<@NonNull JavaFileObject> compilationUnits = gatherCompilationUnits(new File(sourcePath), null);
return JavaFileUtil.compileClasses(compilationUnits, sourcePath, objectPath, classpathProjects);
}
catch (Throwable e) {
throw e;
}
}
public static @NonNull List<@NonNull String> createClasspathProjectList(@NonNull String... classpathProjects) {
List<@NonNull String> classpathProjectList = new ArrayList<@NonNull String>();
if (classpathProjects != null) {
for (@NonNull String classpathProject : classpathProjects) {
classpathProjectList.add(classpathProject);
}
}
return classpathProjectList;
}
/**
* Return a list comprisiing a JavaFileObject for each *.java file in or below folder.
* A non-null compilationUnits may be provided for use as the returned list.
*/
private static @NonNull List<@NonNull JavaFileObject> gatherCompilationUnits(@NonNull File folder, @Nullable List<@NonNull JavaFileObject> compilationUnits) throws IOException {
if (compilationUnits == null) {
compilationUnits = new ArrayList<@NonNull JavaFileObject>();
}
File[] listFiles = folder.listFiles();
if (listFiles != null) {
for (File file : listFiles) {
if (file.isDirectory()) {
gatherCompilationUnits(file, compilationUnits);
}
else if (file.isFile() && file.getName().endsWith(".java")) {
java.net.URI uri = file.getCanonicalFile().toURI();
compilationUnits.add(new JavaSourceFileObject(uri));
}
}
}
return compilationUnits;
}
/**
* Load the class whose Java name is qualifiedClassName and whose class file can be found below explicitClassPath.
* Subsequent loads of classes such as nested classes whose names are prefixed by qualifiedClassName are also loaded from explicitClassPath.
* This method always uses a new ClassLoader to load the class and so ignores any previously cached loads.
*/
public static Class<?> loadExplicitClass(@NonNull File explicitClassPath, @NonNull String qualifiedClassName) throws ClassNotFoundException, IOException {
ClassLoader thisClassLoader = JavaSourceFileObject.class.getClassLoader();
assert thisClassLoader != null;
ExplicitClassLoader classLoader = new ExplicitClassLoader(explicitClassPath, qualifiedClassName, thisClassLoader);
return classLoader.loadClass(qualifiedClassName);
}
private JavaSourceFileObject(java.net.@NonNull URI uri) {
super(uri, Kind.SOURCE);
}
@Override
public @NonNull CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
char[] buf = new char[4096];
StringBuilder s = new StringBuilder();
Reader reader = new FileReader(new File(uri));
try {
int len;
while ((len = reader.read(buf)) > 0) {
s.append(buf, 0, len);
}
}
finally {
reader.close();
}
return s.toString();
}
}