Added more license types, changed file names to make more sense, cleaned up code
This commit is contained in:
parent
4dcc693551
commit
dd9a04756d
|
@ -13,7 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.util.FileUtil;
|
||||
|
||||
public class BuildStrings {
|
||||
|
@ -24,11 +24,11 @@ public class BuildStrings {
|
|||
public static final String STAGING = "staging";
|
||||
|
||||
public static class ProjectPath {
|
||||
public static final String Resources = Build.path("..", "..", "resources");
|
||||
public static final String GitHub = Build.path("..", "..", "github_projects");
|
||||
public static final String Resources = Builder.path("..", "..", "resources");
|
||||
public static final String GitHub = Builder.path("..", "..", "github_projects");
|
||||
}
|
||||
|
||||
static String path(String... path) {
|
||||
return FileUtil.normalizeAsFile(Build.path(path));
|
||||
return FileUtil.normalizeAsFile(Builder.path(path));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,21 +13,21 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
|
||||
// setup source directories
|
||||
public class Dirs {
|
||||
public static final String Dependencies = Build.path(BuildStrings.ProjectPath.Resources, "Dependencies");
|
||||
public static final String Dependencies = Builder.path(BuildStrings.ProjectPath.Resources, "Dependencies");
|
||||
|
||||
public static final String JavaTar = mkDir("javatar");
|
||||
public static final String YAML = mkDir("yaml");
|
||||
public static final String WildCard = mkDir("wildcard");
|
||||
public static final String LzmaJava = mkDir("lzma-java");
|
||||
|
||||
public static final String Java_Redist = Build.path(BuildStrings.ProjectPath.Resources, "Java_Redist");
|
||||
public static final String OpenJDK_Runtime = Build.path(Java_Redist, "openJDK_runtime");
|
||||
public static final String Java_Redist = Builder.path(BuildStrings.ProjectPath.Resources, "Java_Redist");
|
||||
public static final String OpenJDK_Runtime = Builder.path(Java_Redist, "openJDK_runtime");
|
||||
|
||||
public static String mkDir(String dir) {
|
||||
return Build.path(Dependencies, dir);
|
||||
return Builder.path(Dependencies, dir);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
*/
|
||||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.BuildOptions;
|
||||
import dorkbox.Oak;
|
||||
import dorkbox.Build;
|
||||
import dorkbox.build.Project;
|
||||
import dorkbox.build.ProjectJava;
|
||||
import dorkbox.build.util.BuildLog;
|
||||
|
@ -31,7 +31,7 @@ import java.util.List;
|
|||
|
||||
|
||||
// @formatter:off
|
||||
@Build.Builder
|
||||
@Builder.Builder
|
||||
public class JavaBuilder {
|
||||
|
||||
// ALSO copied over to JavaBuilder build dir (as an example), so make sure to update in both locations
|
||||
|
@ -68,38 +68,38 @@ public class JavaBuilder {
|
|||
buildOptions.compiler.targetJavaVersion = 6;
|
||||
|
||||
// if we are running from a jar, DO NOT try to do certain things
|
||||
String utilSourcePath = Oak.get().getAbsolutePath();
|
||||
String utilSourcePath = Build.get().getAbsolutePath();
|
||||
|
||||
String distDir = FileUtil.normalizeAsFile(Build.path(root, "dist"));
|
||||
String distDir = FileUtil.normalizeAsFile(Builder.path(root, "dist"));
|
||||
File dists = new File(distDir);
|
||||
dists.mkdirs();
|
||||
|
||||
String libsPath = FileUtil.normalizeAsFile(Build.path(root, "libs"));
|
||||
String libsPath = FileUtil.normalizeAsFile(Builder.path(root, "libs"));
|
||||
|
||||
BuildLog log = Build.log();
|
||||
BuildLog log = Builder.log();
|
||||
|
||||
PreJarAction preJarAction = new PreJarAction() {
|
||||
@Override
|
||||
public void executeBeforeJarHappens(File outputDir) throws IOException {
|
||||
Build.log().println("Installing license files...");
|
||||
File targetLocation = new File(outputDir, Build.path("dorkbox", "license"));
|
||||
Builder.log().println("Installing license files...");
|
||||
File targetLocation = new File(outputDir, Builder.path("dorkbox", "license"));
|
||||
License.install(targetLocation);
|
||||
}
|
||||
};
|
||||
|
||||
// now build the project
|
||||
ProjectJava project = ProjectJava.create(name)
|
||||
.classPath(new Paths(Build.path(root, "libs"), Project.Jar_Pattern, "!jdkRuntimes"))
|
||||
.classPath(new Paths(Builder.path(root, "libs"), Project.Jar_Pattern, "!jdkRuntimes"))
|
||||
.license(license)
|
||||
.version(version)
|
||||
.extraFiles(new Paths(root, "README.md"))
|
||||
.sourcePath(src, Project.Java_Pattern)
|
||||
.options(buildOptions)
|
||||
.jar().overrideDate(Build.buildDate)
|
||||
.mainClass(Oak.class)
|
||||
.jar().overrideDate(Builder.buildDate)
|
||||
.mainClass(Build.class)
|
||||
.preJarAction(preJarAction)
|
||||
.includeSourceAsSeparate()
|
||||
.outputFile(Build.path(distDir, name + Project.JAR_EXTENSION));
|
||||
.outputFile(Builder.path(distDir, name + Project.JAR_EXTENSION));
|
||||
project.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,887 +1,113 @@
|
|||
/*
|
||||
* Copyright 2012 dorkbox, llc
|
||||
*
|
||||
* 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 dorkbox;
|
||||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
import dorkbox.build.Project;
|
||||
import dorkbox.build.ProjectJava;
|
||||
import dorkbox.build.SimpleArgs;
|
||||
import dorkbox.build.util.BuildLog;
|
||||
import dorkbox.build.util.BuildParser;
|
||||
import dorkbox.build.util.classloader.ByteClassloader;
|
||||
import dorkbox.build.util.classloader.ClassByteIterator;
|
||||
import dorkbox.build.util.jar.Pack200Util;
|
||||
import dorkbox.util.FileUtil;
|
||||
import dorkbox.util.LZMA;
|
||||
import dorkbox.util.Sys;
|
||||
import dorkbox.util.annotation.AnnotationDefaults;
|
||||
import dorkbox.util.annotation.AnnotationDetector;
|
||||
import dorkbox.util.properties.PropertiesProvider;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.CodeSource;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
|
||||
public
|
||||
class Build {
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public
|
||||
@interface Builder {}
|
||||
|
||||
// ALSO copied over to javabuilder build dir (as an example), so make sure to update in both locations
|
||||
// ~/dorkbox/eclipse/jre/bin/java -jar dist/JavaBuilder_v1.3.jar build javabuilder
|
||||
// ~/dorkbox/eclipse/jre/bin/java -Xrunjdwp:transport=dt_socket,server=y,address=1044 -jar dist/JavaBuilder_v1.3.jar build javabuilder
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public
|
||||
@interface Configure {}
|
||||
|
||||
|
||||
public static final String BUILD_MODE = "build";
|
||||
|
||||
private static final ConcurrentHashMap<String, File> moduleCache = new ConcurrentHashMap<String, File>();
|
||||
|
||||
private static final long startDate = System.currentTimeMillis();
|
||||
public static long buildDate = startDate;
|
||||
|
||||
private static final File tempDir;
|
||||
|
||||
/**
|
||||
* Location where settings are stored
|
||||
*/
|
||||
public static final PropertiesProvider settings = new PropertiesProvider(new File("settings.ini"));
|
||||
|
||||
public static final boolean isJar;
|
||||
|
||||
public static final TimeZone defaultTimeZone;
|
||||
public static int offset;
|
||||
|
||||
static {
|
||||
// get the local time zone for use later
|
||||
defaultTimeZone = TimeZone.getDefault();
|
||||
offset = defaultTimeZone.getRawOffset();
|
||||
if (defaultTimeZone.inDaylightTime(new Date())) {
|
||||
offset = offset + defaultTimeZone.getDSTSavings();
|
||||
}
|
||||
|
||||
// have to set our default timezone to UTC. EVERYTHING will be UTC, and if we want local, we must explicitly ask for it.
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||
// System.out.println("UTC Time: " + new Date());
|
||||
|
||||
try {
|
||||
tempDir = new File(FileUtil.tempDirectory("Builder"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Paths.setDefaultGlobExcludes("**/.svn/**, **/.git/**");
|
||||
// are we building from a jar, or a project (from an IDE?)
|
||||
String sourceName = Oak.get().getName();
|
||||
isJar = sourceName.endsWith(Project.JAR_EXTENSION);
|
||||
}
|
||||
|
||||
static
|
||||
void start(String... _args) throws Exception {
|
||||
for (int i = 0; i < _args.length; i++) {
|
||||
_args[i] = _args[i].toLowerCase();
|
||||
}
|
||||
|
||||
if (_args.length < 2) {
|
||||
System.err.println("You must specify an action, followed by what you want done.");
|
||||
System.err.println("For example: build myProject , which will then find and build your project");
|
||||
System.err.println(" : see example for more specific details");
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleArgs args = new SimpleArgs(_args);
|
||||
make(new BuildOptions(), args);
|
||||
}
|
||||
|
||||
public static
|
||||
void build(String projectName, String... arguments) throws Exception {
|
||||
build(new BuildOptions(), projectName, arguments);
|
||||
}
|
||||
|
||||
public static
|
||||
void build(BuildOptions buildOptions, String projectName, String... arguments) throws Exception {
|
||||
String[] _args = new String[2 + arguments.length];
|
||||
_args[0] = "build";
|
||||
_args[1] = projectName;
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
_args[i + 2] = arguments[i];
|
||||
}
|
||||
|
||||
SimpleArgs args = new SimpleArgs(_args);
|
||||
Project.reset();
|
||||
make(buildOptions, args);
|
||||
}
|
||||
|
||||
public static
|
||||
void make(BuildOptions buildOptions, SimpleArgs args) throws Exception {
|
||||
String title = "JavaBuilder";
|
||||
BuildLog log = BuildLog.start();
|
||||
log.title(title).println(args);
|
||||
|
||||
Date buildDate = args.getBuildDate();
|
||||
if (buildDate != null) {
|
||||
Build.buildDate = buildDate.getTime();
|
||||
|
||||
Calendar c = Calendar.getInstance(defaultTimeZone);
|
||||
c.setTime(buildDate);
|
||||
c.add(Calendar.HOUR_OF_DAY, offset / 1000 / 60 / 60);
|
||||
c.add(Calendar.MINUTE, offset / 1000 / 60 % 60);
|
||||
|
||||
log.title("Forced Date").println(buildDate, c.getTime().toString().replace("UTC", defaultTimeZone.getID()));
|
||||
}
|
||||
|
||||
Build build = new Build();
|
||||
Exception e = null;
|
||||
try {
|
||||
Build.prepareXcompile();
|
||||
log.println();
|
||||
|
||||
if (Build.isJar) {
|
||||
// when from eclipse, we want to run it directly (in case it changes significantly)
|
||||
build.compileBuildInstructions(args);
|
||||
log.println();
|
||||
}
|
||||
|
||||
build.start(buildOptions, args);
|
||||
|
||||
log.println();
|
||||
|
||||
Calendar c = Calendar.getInstance(defaultTimeZone);
|
||||
c.setTime(new Date());
|
||||
c.add(Calendar.HOUR_OF_DAY, offset / 1000 / 60 / 60);
|
||||
c.add(Calendar.MINUTE, offset / 1000 / 60 % 60);
|
||||
String localDateString = c.getTime().toString().replace("UTC", defaultTimeZone.getID());
|
||||
|
||||
if (!BuildLog.wasNested || BuildLog.TITLE_WIDTH != BuildLog.STOCK_TITLE_WIDTH) {
|
||||
log.title(title).println(args, localDateString, "Completed in: " + getRuntime(build.startTime) + " seconds.");
|
||||
}
|
||||
else {
|
||||
log.title(title).println(args, localDateString, "Completed in: " + getRuntime(Build.startDate) + " seconds.",
|
||||
"Date code: " + Build.buildDate);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e = e1;
|
||||
|
||||
log.title("ERROR").println(e.getMessage());
|
||||
StackTraceElement[] stackTrace = e.getStackTrace();
|
||||
if (stackTrace.length > 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
BuildLog.finish();
|
||||
if (e != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static
|
||||
String getRuntime(long startTime) {
|
||||
String time = Double.toString((System.currentTimeMillis() - startTime) / 1000D);
|
||||
int index = time.indexOf('.');
|
||||
if (index > -1 && index < time.length() - 2) {
|
||||
return time.substring(0, index + 2);
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
public static
|
||||
BuildLog log() {
|
||||
return new BuildLog();
|
||||
}
|
||||
|
||||
public static
|
||||
BuildLog log(PrintStream printer) {
|
||||
return new BuildLog(printer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final long startTime = System.currentTimeMillis();
|
||||
private ByteClassloader classloader = null;
|
||||
|
||||
private
|
||||
Build() {
|
||||
Project.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see if our jdk files have been decompressed (necessary for cross target builds)
|
||||
*/
|
||||
private static
|
||||
void prepareXcompile() throws IOException {
|
||||
String jdkDist = FileUtil.normalizeAsFile(Build.path("libs", "jdkRuntimes"));
|
||||
List<File> jdkFiles = FileUtil.parseDir(jdkDist);
|
||||
boolean first = true;
|
||||
BuildLog log = log();
|
||||
|
||||
for (File f : jdkFiles) {
|
||||
// unLZMA + unpack200
|
||||
String name = f.getName();
|
||||
String suffix = ".pack.lzma";
|
||||
|
||||
if (name.endsWith(suffix)) {
|
||||
int nameLength = f.getAbsolutePath().length();
|
||||
String fixedName = f.getAbsolutePath().substring(0, nameLength - suffix.length());
|
||||
File file = new File(fixedName);
|
||||
|
||||
if (!file.canRead() || file.length() == 0) {
|
||||
if (first) {
|
||||
first = false;
|
||||
log.println("******************************");
|
||||
log.println("Preparing environment");
|
||||
log.println("******************************");
|
||||
}
|
||||
|
||||
log.println(" Decompressing: " + f.getAbsolutePath());
|
||||
InputStream inputStream = new FileInputStream(f);
|
||||
// now uncompress
|
||||
ByteArrayOutputStream outputStream = LZMA.decode(inputStream);
|
||||
|
||||
// now unpack
|
||||
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
|
||||
outputStream = Pack200Util.Java.unpack200((ByteArrayInputStream) inputStream);
|
||||
|
||||
// now write to disk
|
||||
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
|
||||
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(new File(fixedName));
|
||||
Sys.copyStream(inputStream, fileOutputStream);
|
||||
Sys.close(fileOutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
log.println("Finished Preparing environment");
|
||||
log.println("******************************");
|
||||
log.println();
|
||||
log.println();
|
||||
}
|
||||
}
|
||||
|
||||
// loads the build.oak file information
|
||||
private
|
||||
void compileBuildInstructions(SimpleArgs args) throws Exception {
|
||||
ByteClassloader bytesClassloader = new ByteClassloader(Thread.currentThread().getContextClassLoader());
|
||||
HashMap<String, HashMap<String, Object>> data = BuildParser.parse(args);
|
||||
|
||||
// each entry is a build, that can have dependencies.
|
||||
for (Entry<String, HashMap<String, Object>> entry : data.entrySet()) {
|
||||
String projectName = entry.getKey();
|
||||
HashMap<String, Object> projectData = entry.getValue();
|
||||
|
||||
// will always have libs jars (minus runtime jars)
|
||||
Paths classPaths = BuildParser.getPathsFromMap(projectData, "classpath");
|
||||
|
||||
// BY DEFAULT, will use build/**/*.java path
|
||||
Paths sourcePaths = BuildParser.getPathsFromMap(projectData, "source");
|
||||
|
||||
ProjectJava project = ProjectJava.create(projectName).classPath(classPaths).compilerClassloader(bytesClassloader).sourcePath(
|
||||
sourcePaths);
|
||||
|
||||
|
||||
List<String> dependencies = BuildParser.getStringsFromMap(projectData, "depends");
|
||||
for (String dep : dependencies) {
|
||||
project.depends(dep);
|
||||
}
|
||||
}
|
||||
|
||||
// only if we have data, should we build
|
||||
if (!data.isEmpty()) {
|
||||
File oak = get();
|
||||
if (oak != null) {
|
||||
// we want to look for the libraries, because they are OFTEN going to be in the incorrect path.
|
||||
// this is only necessary if they aren't correctly loaded.
|
||||
try {
|
||||
BuildLog.disable();
|
||||
BuildOptions buildOptions = new BuildOptions();
|
||||
buildOptions.compiler.forceRebuild = true;
|
||||
|
||||
// this automatically takes care of build dependency ordering
|
||||
Project.buildAll();
|
||||
Project.reset();
|
||||
BuildLog.enable();
|
||||
Class.forName("com.esotericsoftware.wildcard.Paths");
|
||||
} catch (Exception e) {
|
||||
BuildLog.enable();
|
||||
throw e;
|
||||
}
|
||||
// whoops. can't find it on the path
|
||||
|
||||
this.classloader = bytesClassloader;
|
||||
}
|
||||
}
|
||||
File libDir = new File(oak.getParentFile(), "libs");
|
||||
if (!libDir.isDirectory()) {
|
||||
libDir = new File(oak.getParentFile().getParentFile(), "libs");
|
||||
}
|
||||
|
||||
if (!libDir.isDirectory()) {
|
||||
throw new RuntimeException("Unable to find the libs directory for execution: " + oak);
|
||||
}
|
||||
|
||||
private
|
||||
void start(BuildOptions buildOptions, SimpleArgs args) throws Exception {
|
||||
Class<?>[] parameters = new Class[] {URL.class};
|
||||
Class<URLClassLoader> sysclass = URLClassLoader.class;
|
||||
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
dorkbox.util.annotation.Builder detector;
|
||||
|
||||
if (this.classloader != null) {
|
||||
detector = AnnotationDetector.scan(this.classloader, new ClassByteIterator(this.classloader, null));
|
||||
}
|
||||
else {
|
||||
detector = AnnotationDetector.scanClassPath();
|
||||
}
|
||||
|
||||
List<Class<?>> controllers = detector.forAnnotations(Build.Configure.class).collect(AnnotationDefaults.getType);
|
||||
|
||||
if (controllers != null) {
|
||||
// do we have something to control the build process??
|
||||
// now we want to update/search for all project builders if we didn't already run our specific builder
|
||||
for (Class<?> c : controllers) {
|
||||
Class<?>[] params = new Class<?>[] {SimpleArgs.class};
|
||||
Method buildTargeted = null;
|
||||
|
||||
// setup(Args)
|
||||
try {
|
||||
buildTargeted = c.getMethod("setup", params);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
Method method = sysclass.getDeclaredMethod("addURL", parameters);
|
||||
method.setAccessible(true);
|
||||
|
||||
if (buildTargeted != null) {
|
||||
Object newInstance = c.newInstance();
|
||||
// see if we can build a targeted build
|
||||
buildOptions = (BuildOptions) buildTargeted.invoke(newInstance, args);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
|
||||
|
||||
// setup(BuildOptions, Args)
|
||||
try {
|
||||
buildTargeted = c.getMethod("setup", params);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (buildTargeted != null) {
|
||||
Object newInstance = c.newInstance();
|
||||
// see if we can build a targeted build
|
||||
buildTargeted.invoke(newInstance, buildOptions, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BuildLog log = log();
|
||||
log.title("Debug info").println(buildOptions.compiler.debugEnabled ? "Enabled" : "Disabled");
|
||||
log.title("Release status").println(buildOptions.compiler.release ? "Enabled" : "Disabled");
|
||||
log.println();
|
||||
|
||||
// now we want to update/search for all project builders.
|
||||
boolean found;
|
||||
if (this.classloader != null) {
|
||||
detector = AnnotationDetector.scan(this.classloader, new ClassByteIterator(this.classloader, null));
|
||||
}
|
||||
else {
|
||||
detector = AnnotationDetector.scanClassPath();
|
||||
}
|
||||
List<Class<?>> builders = detector.forAnnotations(Build.Builder.class).collect(AnnotationDefaults.getType);
|
||||
|
||||
if (args.getMode().equals(Build.BUILD_MODE)) {
|
||||
String projectToBuild = args.get(1);
|
||||
String methodNameToCall = args.get(2);
|
||||
if (methodNameToCall == null) {
|
||||
log.title("Warning").println("No build method specified. Using default: '" + Build.BUILD_MODE + "'");
|
||||
methodNameToCall = Build.BUILD_MODE;
|
||||
}
|
||||
|
||||
found = runBuild(buildOptions, args, builders, methodNameToCall, projectToBuild);
|
||||
|
||||
if (controllers != null && !found) {
|
||||
final IOException ioException = new IOException("Unable to find a builder for: " + args.getParameters());
|
||||
ioException.setStackTrace(new StackTraceElement[0]);
|
||||
throw ioException;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (controllers != null) {
|
||||
// do we have something to control the build process??
|
||||
// now we want to update/search for all project builders if we didn't already run our specific builder
|
||||
for (Class<?> c : controllers) {
|
||||
Class<?>[] params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
|
||||
Method buildTargeted = null;
|
||||
|
||||
// finish(BuildOptions, Args)
|
||||
try {
|
||||
buildTargeted = c.getMethod("takedown", params);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (buildTargeted != null) {
|
||||
Object newInstance = c.newInstance();
|
||||
// see if we can build a targeted build
|
||||
buildTargeted.invoke(newInstance, buildOptions, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static
|
||||
boolean runBuild(BuildOptions buildOptions, SimpleArgs args, List<Class<?>> builders, String methodNameToCall, String projectToBuild)
|
||||
throws Exception {
|
||||
if (builders == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (Class<?> c : builders) {
|
||||
String simpleName = c.getSimpleName().toLowerCase();
|
||||
|
||||
if (projectToBuild.equals(simpleName)) {
|
||||
Method[] methods = c.getMethods();
|
||||
|
||||
for (Method m : methods) {
|
||||
if (m.getName().equals(methodNameToCall)) {
|
||||
Class<?>[] p = m.getParameterTypes();
|
||||
|
||||
switch (p.length) {
|
||||
case 0: {
|
||||
// build()
|
||||
try {
|
||||
m.invoke(c);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
if (p[0].equals(SimpleArgs.class)) {
|
||||
// build(Args)
|
||||
try {
|
||||
m.invoke(c, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (p[0].equals(BuildOptions.class)) {
|
||||
// build(BuildOptions)
|
||||
try {
|
||||
m.invoke(c, buildOptions);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// build(BuildOptions, Args)
|
||||
try {
|
||||
m.invoke(c, buildOptions, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
// add lib dir jars
|
||||
for (File f : libDir.listFiles()) {
|
||||
if (!f.isDirectory() && f.canRead() && f.getName().endsWith(".jar")) {
|
||||
method.invoke(sysloader, new Object[] {f.toURI().toURL()});
|
||||
}
|
||||
}
|
||||
|
||||
// now have to add fastMD5 sum jars
|
||||
libDir = new File(libDir, "fast-md5");
|
||||
for (File f : libDir.listFiles()) {
|
||||
if (!f.isDirectory() && f.canRead() && f.getName().endsWith(".jar")) {
|
||||
// System.err.println("adding url " + f.getAbsolutePath());
|
||||
method.invoke(sysloader, new Object[] {f.toURI().toURL()});
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
throw new RuntimeException("Unable to load the libs directory for execution: " + libDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public static
|
||||
String path(String... paths) {
|
||||
StringBuilder buffer = new StringBuilder(128);
|
||||
|
||||
for (String p : paths) {
|
||||
buffer.append(p).append(File.separator);
|
||||
}
|
||||
|
||||
int length = buffer.length();
|
||||
buffer.delete(length - 1, length);
|
||||
|
||||
return buffer.toString();
|
||||
File get() {
|
||||
return get(Build.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the java file (from class file) when running from an IDE.
|
||||
* Retrieve the location that this classfile was loaded from, or possibly null if the class was compiled on the fly
|
||||
*/
|
||||
public static
|
||||
File getJavaFileIDE(File rootFile) throws IOException {
|
||||
String rootPath = rootFile.getAbsolutePath();
|
||||
File get(Class<?> clazz) {
|
||||
// Get the location of this class
|
||||
ProtectionDomain pDomain = clazz.getProtectionDomain();
|
||||
CodeSource cSource = pDomain.getCodeSource();
|
||||
|
||||
if (rootFile.isDirectory()) {
|
||||
final File eclipseSrc = new File(rootFile.getParentFile(), "src");
|
||||
// file:/X:/workspace/XYZ/classes/ when it's in ide/flat
|
||||
// jar:/X:/workspace/XYZ/jarname.jar when it's jar
|
||||
URL loc = cSource.getLocation();
|
||||
|
||||
if (eclipseSrc.exists()) {
|
||||
// eclipse (default)
|
||||
return eclipseSrc.getAbsoluteFile();
|
||||
}
|
||||
else {
|
||||
// intellij (default)
|
||||
String moduleName = rootPath.substring(rootPath.lastIndexOf(File.separatorChar) + 1);
|
||||
File parent = rootFile.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
|
||||
// our src directory is always under the module dir
|
||||
final File dir = getModuleDir(parent, moduleName);
|
||||
|
||||
return new File(dir, "src").getAbsoluteFile();
|
||||
}
|
||||
// we don't always have a protection domain (for example, when we compile classes on the fly, from memory)
|
||||
if (loc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a class to it's .java file.
|
||||
*/
|
||||
public static
|
||||
Paths getJavaFile(Class<?> clazz) throws IOException {
|
||||
File rootFile = Oak.get(clazz);
|
||||
assert rootFile != null;
|
||||
|
||||
String rootPath = rootFile.getAbsolutePath();
|
||||
String fileName = clazz.getCanonicalName();
|
||||
|
||||
final File javaFile = getJavaFileIDE(rootFile);
|
||||
|
||||
if (javaFile != null) {
|
||||
String convertJava = fileName.replace('.', File.separatorChar) + ".java";
|
||||
return new Paths(javaFile.getAbsolutePath(), convertJava);
|
||||
}
|
||||
else if (rootPath.endsWith(Project.JAR_EXTENSION) && isZipFile(rootFile)) {
|
||||
// check to see if it's a zip file
|
||||
|
||||
// have to go digging for it!
|
||||
// the sources can be IN THE FILE, or they are my sources, and are in the src file.
|
||||
String nameAsFile = fileName.replace('.', File.separatorChar) + ".java";
|
||||
|
||||
boolean found = extractFilesFromZip(rootFile, nameAsFile);
|
||||
|
||||
if (found) {
|
||||
return new Paths(tempDir.getAbsolutePath(), nameAsFile);
|
||||
}
|
||||
|
||||
// try the source file
|
||||
rootPath = rootPath.replace(".jar", "_src.zip");
|
||||
rootFile = new File(rootPath);
|
||||
|
||||
found = extractFilesFromZip(rootFile, nameAsFile);
|
||||
|
||||
if (found) {
|
||||
return new Paths(tempDir.getAbsolutePath(), nameAsFile);
|
||||
}
|
||||
}
|
||||
// not found
|
||||
throw new IOException("Cannot find source file: '" + fileName + "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the .java files accessible which belong to the
|
||||
* package (but NOT subpackages) of the given class
|
||||
*/
|
||||
public static
|
||||
Paths getJavaFilesInPackage(Class<?> clazz) throws IOException {
|
||||
File rootFile = Oak.get(clazz);
|
||||
assert rootFile != null;
|
||||
|
||||
String rootPath = rootFile.getAbsolutePath();
|
||||
String fileName = clazz.getCanonicalName();
|
||||
String directoryName = fileName.replace('.', File.separatorChar).substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
final File javaFile = getJavaFileIDE(rootFile);
|
||||
|
||||
if (javaFile != null) {
|
||||
return new Paths(javaFile.getAbsolutePath(), directoryName + "/*.java");
|
||||
}
|
||||
else if (rootPath.endsWith(Project.JAR_EXTENSION) && isZipFile(rootFile)) {
|
||||
// check to see if it's a zip file
|
||||
|
||||
// have to go digging for it!
|
||||
// the sources can be IN THE FILE, or they are my sources, and are in the src file.
|
||||
|
||||
Paths paths = extractPackageFilesFromZip(rootFile, directoryName);
|
||||
if (paths != null) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
|
||||
// try the source file
|
||||
rootPath = rootPath.replace(".jar", "_src.zip");
|
||||
rootFile = new File(rootPath);
|
||||
|
||||
paths = extractPackageFilesFromZip(rootFile, directoryName);
|
||||
if (paths != null) {
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// not found
|
||||
throw new IOException("Cannot find source file location: '" + fileName + "'");
|
||||
}
|
||||
|
||||
private static
|
||||
boolean extractFilesFromZip(final File rootFile, final String nameAsFile) throws IOException {
|
||||
boolean found = false;
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(rootFile));
|
||||
ZipEntry entry;
|
||||
// Can have %20 as spaces (in winxp at least). need to convert to proper path from URL
|
||||
try {
|
||||
while ((entry = zipInputStream.getNextEntry()) != null) {
|
||||
String name = entry.getName();
|
||||
|
||||
if (name.equals(nameAsFile)) {
|
||||
// read out bytes!
|
||||
final File file = new File(tempDir, nameAsFile);
|
||||
if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
|
||||
throw new IOException("Unable to create temp dir: " + file.getParentFile());
|
||||
}
|
||||
|
||||
final FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||
try {
|
||||
copyStream(zipInputStream, fileOutputStream);
|
||||
found = true;
|
||||
} finally {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
|
||||
zipInputStream.closeEntry();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all of the directoryName files found in the zip file to temp dir. Only extracts the SAME LEVEL, not subdirs.
|
||||
*/
|
||||
private static
|
||||
Paths extractPackageFilesFromZip(final File rootFile, final String directoryName) throws IOException {
|
||||
final int length = directoryName.length();
|
||||
boolean found = false;
|
||||
Paths paths = new Paths();
|
||||
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(rootFile));
|
||||
ZipEntry entry;
|
||||
try {
|
||||
while ((entry = zipInputStream.getNextEntry()) != null) {
|
||||
String name = entry.getName();
|
||||
|
||||
if (name.startsWith(directoryName) && !entry.isDirectory() && name.lastIndexOf('/') <= length && name.endsWith(".java")) {
|
||||
// read out bytes!
|
||||
final File file = new File(tempDir, directoryName);
|
||||
if (!file.exists() && !file.mkdirs()) {
|
||||
throw new IOException("Unable to create temp dir: " + file);
|
||||
}
|
||||
|
||||
final FileOutputStream fileOutputStream = new FileOutputStream(new File(tempDir, name));
|
||||
try {
|
||||
copyStream(zipInputStream, fileOutputStream);
|
||||
paths.add(tempDir.getAbsolutePath(), name);
|
||||
found = true;
|
||||
} finally {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
|
||||
zipInputStream.closeEntry();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return paths;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static
|
||||
File getModuleDir(final File parent, final String moduleName) {
|
||||
final File file = moduleCache.get(moduleName);
|
||||
if (file != null) {
|
||||
String fileName = URLDecoder.decode(loc.getFile(), "UTF-8");
|
||||
File file = new File(fileName).getAbsoluteFile().getCanonicalFile();
|
||||
return file;
|
||||
}
|
||||
|
||||
ArrayList<File> candidates = new ArrayList<File>();
|
||||
|
||||
getDirs(0, candidates, parent, moduleName);
|
||||
|
||||
for (File candidate : candidates) {
|
||||
// our src directory is always under the module dir
|
||||
if (new File(candidate, "src").isDirectory()) {
|
||||
// we also want to CACHE the module dir, as the search can take a while.
|
||||
moduleCache.put(moduleName, candidate);
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static
|
||||
void getDirs(final int i, ArrayList<File> candidates, final File parent, final String moduleName) {
|
||||
if (i > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File file : parent.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
if (file.getName().equals(moduleName)) {
|
||||
candidates.add(file);
|
||||
}
|
||||
else {
|
||||
getDirs(i + 1, candidates, file, moduleName);
|
||||
}
|
||||
}
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Unable to decode file path!", e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unable to get canonical file path!", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the contents of the input stream to the output stream.
|
||||
* <p/>
|
||||
* DOES NOT CLOSE THE STEAMS!
|
||||
*/
|
||||
public static
|
||||
<T extends OutputStream> T copyStream(InputStream inputStream, T outputStream) throws IOException {
|
||||
byte[] buffer = new byte[4096];
|
||||
int read;
|
||||
while ((read = inputStream.read(buffer)) > 0) {
|
||||
outputStream.write(buffer, 0, read);
|
||||
}
|
||||
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the file is a zip/jar file
|
||||
*/
|
||||
public static
|
||||
boolean isZipFile(File file) {
|
||||
byte[] ZIP_HEADER = {'P', 'K', 0x3, 0x4};
|
||||
boolean isZip = true;
|
||||
byte[] buffer = new byte[ZIP_HEADER.length];
|
||||
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(file, "r");
|
||||
raf.readFully(buffer);
|
||||
for (int i = 0; i < ZIP_HEADER.length; i++) {
|
||||
if (buffer[i] != ZIP_HEADER[i]) {
|
||||
isZip = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
isZip = false;
|
||||
} finally {
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return isZip;
|
||||
}
|
||||
|
||||
|
||||
public static
|
||||
boolean deleteFile(String target) {
|
||||
return deleteFile(new File(FileUtil.normalizeAsFile(target)));
|
||||
}
|
||||
|
||||
public static
|
||||
boolean deleteFile(File target) {
|
||||
target = FileUtil.normalize(target);
|
||||
|
||||
log().title("Deleting file").println(target.getAbsolutePath());
|
||||
|
||||
return target.delete();
|
||||
}
|
||||
|
||||
public static
|
||||
File moveFile(String source, String target) throws IOException {
|
||||
source = FileUtil.normalizeAsFile(source);
|
||||
target = FileUtil.normalizeAsFile(target);
|
||||
|
||||
|
||||
log().title("Moving file").println(" ╭─ " + source, "╰─> " + target);
|
||||
|
||||
return FileUtil.moveFile(source, target);
|
||||
}
|
||||
|
||||
public static
|
||||
File copyFile(File source, File target) throws IOException {
|
||||
source = FileUtil.normalize(source);
|
||||
target = FileUtil.normalize(target);
|
||||
|
||||
|
||||
log().title("Copying file").println(" ╭─ " + source.getAbsolutePath(), "╰─> " + target.getAbsolutePath());
|
||||
|
||||
return FileUtil.copyFile(source, target);
|
||||
}
|
||||
|
||||
public static
|
||||
void copyFile(String source, String target) throws IOException {
|
||||
source = FileUtil.normalizeAsFile(source);
|
||||
target = FileUtil.normalizeAsFile(target);
|
||||
|
||||
log().title("Copying file").println(" ╭─ " + source, "╰─> " + target);
|
||||
|
||||
FileUtil.copyFile(source, target);
|
||||
}
|
||||
|
||||
public static
|
||||
void copyDirectory(String source, String target, String... dirNamesToIgnore) throws IOException {
|
||||
source = FileUtil.normalizeAsFile(source);
|
||||
target = FileUtil.normalizeAsFile(target);
|
||||
|
||||
log().title("Copying dir").println(" ╭─ " + source, "╰─> " + target);
|
||||
FileUtil.copyDirectory(source, target, dirNamesToIgnore);
|
||||
void main(String... _args) throws Exception {
|
||||
// now startup like normal
|
||||
Builder.start(_args);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,7 @@ public class BuildOptions {
|
|||
|
||||
/** Please note that the binary release is GLPv2 + Classpath Exception, giving us permission to use it to compile binaries */
|
||||
public String getCrossCompileLibraryLocation(int targetVersion) {
|
||||
return Build.path("libs", "jdkRuntimes", "openJdk" + targetVersion + "_rt.jar");
|
||||
return Builder.path("libs", "jdkRuntimes", "openJdk" + targetVersion + "_rt.jar");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,873 @@
|
|||
/*
|
||||
* Copyright 2012 dorkbox, llc
|
||||
*
|
||||
* 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 dorkbox;
|
||||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
import dorkbox.build.Project;
|
||||
import dorkbox.build.ProjectJava;
|
||||
import dorkbox.build.SimpleArgs;
|
||||
import dorkbox.build.util.BuildLog;
|
||||
import dorkbox.build.util.BuildParser;
|
||||
import dorkbox.build.util.classloader.ByteClassloader;
|
||||
import dorkbox.build.util.classloader.ClassByteIterator;
|
||||
import dorkbox.build.util.jar.Pack200Util;
|
||||
import dorkbox.util.FileUtil;
|
||||
import dorkbox.util.LZMA;
|
||||
import dorkbox.util.Sys;
|
||||
import dorkbox.util.annotation.AnnotationDefaults;
|
||||
import dorkbox.util.annotation.AnnotationDetector;
|
||||
import dorkbox.util.properties.PropertiesProvider;
|
||||
|
||||
import java.io.*;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public
|
||||
class Builder {
|
||||
public static final String BUILD_MODE = "build";
|
||||
|
||||
private static final ConcurrentHashMap<String, File> moduleCache = new ConcurrentHashMap<String, File>();
|
||||
|
||||
private static final long startDate = System.currentTimeMillis();
|
||||
public static long buildDate = startDate;
|
||||
|
||||
private static final File tempDir;
|
||||
|
||||
/**
|
||||
* Location where settings are stored
|
||||
*/
|
||||
public static final PropertiesProvider settings = new PropertiesProvider(new File("settings.ini"));
|
||||
|
||||
public static final boolean isJar;
|
||||
|
||||
public static final TimeZone defaultTimeZone;
|
||||
public static int offset;
|
||||
|
||||
static {
|
||||
// get the local time zone for use later
|
||||
defaultTimeZone = TimeZone.getDefault();
|
||||
offset = defaultTimeZone.getRawOffset();
|
||||
if (defaultTimeZone.inDaylightTime(new Date())) {
|
||||
offset = offset + defaultTimeZone.getDSTSavings();
|
||||
}
|
||||
|
||||
// have to set our default timezone to UTC. EVERYTHING will be UTC, and if we want local, we must explicitly ask for it.
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
|
||||
// System.out.println("UTC Time: " + new Date());
|
||||
|
||||
try {
|
||||
tempDir = new File(FileUtil.tempDirectory("Builder"));
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
Paths.setDefaultGlobExcludes("**/.svn/**, **/.git/**");
|
||||
// are we building from a jar, or a project (from an IDE?)
|
||||
String sourceName = Build.get().getName();
|
||||
isJar = sourceName.endsWith(Project.JAR_EXTENSION);
|
||||
}
|
||||
|
||||
static
|
||||
void start(String... _args) throws Exception {
|
||||
for (int i = 0; i < _args.length; i++) {
|
||||
_args[i] = _args[i].toLowerCase();
|
||||
}
|
||||
|
||||
if (_args.length < 2) {
|
||||
System.err.println("You must specify an action, followed by what you want done.");
|
||||
System.err.println("For example: build myProject , which will then find and build your project");
|
||||
System.err.println(" : see example for more specific details");
|
||||
return;
|
||||
}
|
||||
|
||||
SimpleArgs args = new SimpleArgs(_args);
|
||||
make(new BuildOptions(), args);
|
||||
}
|
||||
|
||||
public static
|
||||
void build(String projectName, String... arguments) throws Exception {
|
||||
build(new BuildOptions(), projectName, arguments);
|
||||
}
|
||||
|
||||
public static
|
||||
void build(BuildOptions buildOptions, String projectName, String... arguments) throws Exception {
|
||||
String[] _args = new String[2 + arguments.length];
|
||||
_args[0] = "build";
|
||||
_args[1] = projectName;
|
||||
for (int i = 0; i < arguments.length; i++) {
|
||||
_args[i + 2] = arguments[i];
|
||||
}
|
||||
|
||||
SimpleArgs args = new SimpleArgs(_args);
|
||||
Project.reset();
|
||||
make(buildOptions, args);
|
||||
}
|
||||
|
||||
public static
|
||||
void make(BuildOptions buildOptions, SimpleArgs args) throws Exception {
|
||||
String title = "JavaBuilder";
|
||||
BuildLog log = BuildLog.start();
|
||||
log.title(title).println(args);
|
||||
|
||||
Date buildDate = args.getBuildDate();
|
||||
if (buildDate != null) {
|
||||
Builder.buildDate = buildDate.getTime();
|
||||
|
||||
Calendar c = Calendar.getInstance(defaultTimeZone);
|
||||
c.setTime(buildDate);
|
||||
c.add(Calendar.HOUR_OF_DAY, offset / 1000 / 60 / 60);
|
||||
c.add(Calendar.MINUTE, offset / 1000 / 60 % 60);
|
||||
|
||||
log.title("Forced Date").println(buildDate, c.getTime().toString().replace("UTC", defaultTimeZone.getID()));
|
||||
}
|
||||
|
||||
Builder builder = new Builder();
|
||||
Exception e = null;
|
||||
try {
|
||||
Builder.prepareXcompile();
|
||||
log.println();
|
||||
|
||||
if (Builder.isJar) {
|
||||
// when from eclipse, we want to run it directly (in case it changes significantly)
|
||||
builder.compileBuildInstructions(args);
|
||||
log.println();
|
||||
}
|
||||
|
||||
builder.start(buildOptions, args);
|
||||
|
||||
log.println();
|
||||
|
||||
Calendar c = Calendar.getInstance(defaultTimeZone);
|
||||
c.setTime(new Date());
|
||||
c.add(Calendar.HOUR_OF_DAY, offset / 1000 / 60 / 60);
|
||||
c.add(Calendar.MINUTE, offset / 1000 / 60 % 60);
|
||||
String localDateString = c.getTime().toString().replace("UTC", defaultTimeZone.getID());
|
||||
|
||||
if (!BuildLog.wasNested || BuildLog.TITLE_WIDTH != BuildLog.STOCK_TITLE_WIDTH) {
|
||||
log.title(title).println(args, localDateString, "Completed in: " + getRuntime(builder.startTime) + " seconds.");
|
||||
}
|
||||
else {
|
||||
log.title(title).println(args, localDateString, "Completed in: " + getRuntime(Builder.startDate) + " seconds.",
|
||||
"Date code: " + Builder.buildDate);
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
e = e1;
|
||||
|
||||
log.title("ERROR").println(e.getMessage());
|
||||
StackTraceElement[] stackTrace = e.getStackTrace();
|
||||
if (stackTrace.length > 0) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
BuildLog.finish();
|
||||
if (e != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private static
|
||||
String getRuntime(long startTime) {
|
||||
String time = Double.toString((System.currentTimeMillis() - startTime) / 1000D);
|
||||
int index = time.indexOf('.');
|
||||
if (index > -1 && index < time.length() - 2) {
|
||||
return time.substring(0, index + 2);
|
||||
}
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
public static
|
||||
BuildLog log() {
|
||||
return new BuildLog();
|
||||
}
|
||||
|
||||
public static
|
||||
BuildLog log(PrintStream printer) {
|
||||
return new BuildLog(printer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private final long startTime = System.currentTimeMillis();
|
||||
private ByteClassloader classloader = null;
|
||||
|
||||
private
|
||||
Builder() {
|
||||
Project.reset();
|
||||
}
|
||||
|
||||
/**
|
||||
* check to see if our jdk files have been decompressed (necessary for cross target builds)
|
||||
*/
|
||||
private static
|
||||
void prepareXcompile() throws IOException {
|
||||
String jdkDist = FileUtil.normalizeAsFile(Builder.path("libs", "jdkRuntimes"));
|
||||
List<File> jdkFiles = FileUtil.parseDir(jdkDist);
|
||||
boolean first = true;
|
||||
BuildLog log = log();
|
||||
|
||||
for (File f : jdkFiles) {
|
||||
// unLZMA + unpack200
|
||||
String name = f.getName();
|
||||
String suffix = ".pack.lzma";
|
||||
|
||||
if (name.endsWith(suffix)) {
|
||||
int nameLength = f.getAbsolutePath().length();
|
||||
String fixedName = f.getAbsolutePath().substring(0, nameLength - suffix.length());
|
||||
File file = new File(fixedName);
|
||||
|
||||
if (!file.canRead() || file.length() == 0) {
|
||||
if (first) {
|
||||
first = false;
|
||||
log.println("******************************");
|
||||
log.println("Preparing environment");
|
||||
log.println("******************************");
|
||||
}
|
||||
|
||||
log.println(" Decompressing: " + f.getAbsolutePath());
|
||||
InputStream inputStream = new FileInputStream(f);
|
||||
// now uncompress
|
||||
ByteArrayOutputStream outputStream = LZMA.decode(inputStream);
|
||||
|
||||
// now unpack
|
||||
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
|
||||
outputStream = Pack200Util.Java.unpack200((ByteArrayInputStream) inputStream);
|
||||
|
||||
// now write to disk
|
||||
inputStream = new ByteArrayInputStream(outputStream.toByteArray());
|
||||
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(new File(fixedName));
|
||||
Sys.copyStream(inputStream, fileOutputStream);
|
||||
Sys.close(fileOutputStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!first) {
|
||||
log.println("Finished Preparing environment");
|
||||
log.println("******************************");
|
||||
log.println();
|
||||
log.println();
|
||||
}
|
||||
}
|
||||
|
||||
// loads the build.oak file information
|
||||
private
|
||||
void compileBuildInstructions(SimpleArgs args) throws Exception {
|
||||
ByteClassloader bytesClassloader = new ByteClassloader(Thread.currentThread().getContextClassLoader());
|
||||
HashMap<String, HashMap<String, Object>> data = BuildParser.parse(args);
|
||||
|
||||
// each entry is a build, that can have dependencies.
|
||||
for (Entry<String, HashMap<String, Object>> entry : data.entrySet()) {
|
||||
String projectName = entry.getKey();
|
||||
HashMap<String, Object> projectData = entry.getValue();
|
||||
|
||||
// will always have libs jars (minus runtime jars)
|
||||
Paths classPaths = BuildParser.getPathsFromMap(projectData, "classpath");
|
||||
|
||||
// BY DEFAULT, will use build/**/*.java path
|
||||
Paths sourcePaths = BuildParser.getPathsFromMap(projectData, "source");
|
||||
|
||||
ProjectJava project = ProjectJava.create(projectName).classPath(classPaths).compilerClassloader(bytesClassloader).sourcePath(
|
||||
sourcePaths);
|
||||
|
||||
|
||||
List<String> dependencies = BuildParser.getStringsFromMap(projectData, "depends");
|
||||
for (String dep : dependencies) {
|
||||
project.depends(dep);
|
||||
}
|
||||
}
|
||||
|
||||
// only if we have data, should we build
|
||||
if (!data.isEmpty()) {
|
||||
try {
|
||||
BuildLog.disable();
|
||||
BuildOptions buildOptions = new BuildOptions();
|
||||
buildOptions.compiler.forceRebuild = true;
|
||||
|
||||
// this automatically takes care of build dependency ordering
|
||||
Project.buildAll();
|
||||
Project.reset();
|
||||
BuildLog.enable();
|
||||
} catch (Exception e) {
|
||||
BuildLog.enable();
|
||||
throw e;
|
||||
}
|
||||
|
||||
this.classloader = bytesClassloader;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private
|
||||
void start(BuildOptions buildOptions, SimpleArgs args) throws Exception {
|
||||
|
||||
dorkbox.util.annotation.Builder detector;
|
||||
|
||||
if (this.classloader != null) {
|
||||
detector = AnnotationDetector.scan(this.classloader, new ClassByteIterator(this.classloader, null));
|
||||
}
|
||||
else {
|
||||
detector = AnnotationDetector.scanClassPath();
|
||||
}
|
||||
|
||||
List<Class<?>> controllers = detector.forAnnotations(Config.class).collect(AnnotationDefaults.getType);
|
||||
|
||||
if (controllers != null) {
|
||||
// do we have something to control the build process??
|
||||
// now we want to update/search for all project builders if we didn't already run our specific builder
|
||||
for (Class<?> c : controllers) {
|
||||
Class<?>[] params = new Class<?>[] {SimpleArgs.class};
|
||||
Method buildTargeted = null;
|
||||
|
||||
// setup(Args)
|
||||
try {
|
||||
buildTargeted = c.getMethod("setup", params);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (buildTargeted != null) {
|
||||
Object newInstance = c.newInstance();
|
||||
// see if we can build a targeted build
|
||||
buildOptions = (BuildOptions) buildTargeted.invoke(newInstance, args);
|
||||
break;
|
||||
}
|
||||
else {
|
||||
params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
|
||||
|
||||
// setup(BuildOptions, Args)
|
||||
try {
|
||||
buildTargeted = c.getMethod("setup", params);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (buildTargeted != null) {
|
||||
Object newInstance = c.newInstance();
|
||||
// see if we can build a targeted build
|
||||
buildTargeted.invoke(newInstance, buildOptions, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BuildLog log = log();
|
||||
log.title("Debug info").println(buildOptions.compiler.debugEnabled ? "Enabled" : "Disabled");
|
||||
log.title("Release status").println(buildOptions.compiler.release ? "Enabled" : "Disabled");
|
||||
log.println();
|
||||
|
||||
// now we want to update/search for all project builders.
|
||||
boolean found;
|
||||
if (this.classloader != null) {
|
||||
detector = AnnotationDetector.scan(this.classloader, new ClassByteIterator(this.classloader, null));
|
||||
}
|
||||
else {
|
||||
detector = AnnotationDetector.scanClassPath();
|
||||
}
|
||||
List<Class<?>> builders = detector.forAnnotations(Instructions.class).collect(AnnotationDefaults.getType);
|
||||
|
||||
if (args.getMode().equals(Builder.BUILD_MODE)) {
|
||||
String projectToBuild = args.get(1);
|
||||
String methodNameToCall = args.get(2);
|
||||
if (methodNameToCall == null) {
|
||||
log.title("Warning").println("No build method specified. Using default: '" + Builder.BUILD_MODE + "'");
|
||||
methodNameToCall = Builder.BUILD_MODE;
|
||||
}
|
||||
|
||||
log.title("Method").println(methodNameToCall);
|
||||
|
||||
found = runBuild(buildOptions, args, builders, methodNameToCall, projectToBuild);
|
||||
|
||||
if (controllers != null && !found) {
|
||||
final IOException ioException = new IOException("Unable to find a builder for: " + args.getParameters());
|
||||
ioException.setStackTrace(new StackTraceElement[0]);
|
||||
throw ioException;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (controllers != null) {
|
||||
// do we have something to control the build process??
|
||||
// now we want to update/search for all project builders if we didn't already run our specific builder
|
||||
for (Class<?> c : controllers) {
|
||||
Class<?>[] params = new Class<?>[] {BuildOptions.class, SimpleArgs.class};
|
||||
Method buildTargeted = null;
|
||||
|
||||
// finish(BuildOptions, Args)
|
||||
try {
|
||||
buildTargeted = c.getMethod("takedown", params);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
if (buildTargeted != null) {
|
||||
Object newInstance = c.newInstance();
|
||||
// see if we can build a targeted build
|
||||
buildTargeted.invoke(newInstance, buildOptions, args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static
|
||||
boolean runBuild(BuildOptions buildOptions, SimpleArgs args, List<Class<?>> builders, String methodNameToCall, String projectToBuild)
|
||||
throws Exception {
|
||||
if (builders == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean found = false;
|
||||
for (Class<?> c : builders) {
|
||||
String simpleName = c.getSimpleName().toLowerCase();
|
||||
|
||||
if (projectToBuild.equals(simpleName)) {
|
||||
Method[] methods = c.getMethods();
|
||||
|
||||
for (Method m : methods) {
|
||||
if (m.getName().equals(methodNameToCall)) {
|
||||
Class<?>[] p = m.getParameterTypes();
|
||||
|
||||
switch (p.length) {
|
||||
case 0: {
|
||||
// build()
|
||||
try {
|
||||
m.invoke(c);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
if (p[0].equals(SimpleArgs.class)) {
|
||||
// build(Args)
|
||||
try {
|
||||
m.invoke(c, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (p[0].equals(BuildOptions.class)) {
|
||||
// build(BuildOptions)
|
||||
try {
|
||||
m.invoke(c, buildOptions);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// build(BuildOptions, Args)
|
||||
try {
|
||||
m.invoke(c, buildOptions, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
if (e.getCause() instanceof Exception) {
|
||||
throw (Exception) e.getCause();
|
||||
}
|
||||
|
||||
throw new Exception(e);
|
||||
}
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
public static
|
||||
String path(String... paths) {
|
||||
StringBuilder buffer = new StringBuilder(128);
|
||||
|
||||
for (String p : paths) {
|
||||
buffer.append(p).append(File.separator);
|
||||
}
|
||||
|
||||
int length = buffer.length();
|
||||
buffer.delete(length - 1, length);
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the java file (from class file) when running from an IDE.
|
||||
*/
|
||||
public static
|
||||
File getJavaFileIDE(File rootFile) throws IOException {
|
||||
String rootPath = rootFile.getAbsolutePath();
|
||||
|
||||
if (rootFile.isDirectory()) {
|
||||
final File eclipseSrc = new File(rootFile.getParentFile(), "src");
|
||||
|
||||
if (eclipseSrc.exists()) {
|
||||
// eclipse (default)
|
||||
return eclipseSrc.getAbsoluteFile();
|
||||
}
|
||||
else {
|
||||
// intellij (default)
|
||||
String moduleName = rootPath.substring(rootPath.lastIndexOf(File.separatorChar) + 1);
|
||||
File parent = rootFile.getParentFile().getParentFile().getParentFile().getParentFile().getParentFile();
|
||||
// our src directory is always under the module dir
|
||||
final File dir = getModuleDir(parent, moduleName);
|
||||
|
||||
return new File(dir, "src").getAbsoluteFile();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a class to it's .java file.
|
||||
*/
|
||||
public static
|
||||
Paths getJavaFile(Class<?> clazz) throws IOException {
|
||||
File rootFile = Build.get(clazz);
|
||||
assert rootFile != null;
|
||||
|
||||
String rootPath = rootFile.getAbsolutePath();
|
||||
String fileName = clazz.getCanonicalName();
|
||||
|
||||
final File javaFile = getJavaFileIDE(rootFile);
|
||||
|
||||
if (javaFile != null) {
|
||||
String convertJava = fileName.replace('.', File.separatorChar) + ".java";
|
||||
return new Paths(javaFile.getAbsolutePath(), convertJava);
|
||||
}
|
||||
else if (rootPath.endsWith(Project.JAR_EXTENSION) && isZipFile(rootFile)) {
|
||||
// check to see if it's a zip file
|
||||
|
||||
// have to go digging for it!
|
||||
// the sources can be IN THE FILE, or they are my sources, and are in the src file.
|
||||
String nameAsFile = fileName.replace('.', File.separatorChar) + ".java";
|
||||
|
||||
boolean found = extractFilesFromZip(rootFile, nameAsFile);
|
||||
|
||||
if (found) {
|
||||
return new Paths(tempDir.getAbsolutePath(), nameAsFile);
|
||||
}
|
||||
|
||||
// try the source file
|
||||
rootPath = rootPath.replace(".jar", "_src.zip");
|
||||
rootFile = new File(rootPath);
|
||||
|
||||
found = extractFilesFromZip(rootFile, nameAsFile);
|
||||
|
||||
if (found) {
|
||||
return new Paths(tempDir.getAbsolutePath(), nameAsFile);
|
||||
}
|
||||
}
|
||||
// not found
|
||||
throw new IOException("Cannot find source file: '" + fileName + "'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all of the .java files accessible which belong to the
|
||||
* package (but NOT subpackages) of the given class
|
||||
*/
|
||||
public static
|
||||
Paths getJavaFilesInPackage(Class<?> clazz) throws IOException {
|
||||
File rootFile = Build.get(clazz);
|
||||
assert rootFile != null;
|
||||
|
||||
String rootPath = rootFile.getAbsolutePath();
|
||||
String fileName = clazz.getCanonicalName();
|
||||
String directoryName = fileName.replace('.', File.separatorChar).substring(0, fileName.lastIndexOf('.'));
|
||||
|
||||
final File javaFile = getJavaFileIDE(rootFile);
|
||||
|
||||
if (javaFile != null) {
|
||||
return new Paths(javaFile.getAbsolutePath(), directoryName + "/*.java");
|
||||
}
|
||||
else if (rootPath.endsWith(Project.JAR_EXTENSION) && isZipFile(rootFile)) {
|
||||
// check to see if it's a zip file
|
||||
|
||||
// have to go digging for it!
|
||||
// the sources can be IN THE FILE, or they are my sources, and are in the src file.
|
||||
|
||||
Paths paths = extractPackageFilesFromZip(rootFile, directoryName);
|
||||
if (paths != null) {
|
||||
return paths;
|
||||
}
|
||||
|
||||
|
||||
// try the source file
|
||||
rootPath = rootPath.replace(".jar", "_src.zip");
|
||||
rootFile = new File(rootPath);
|
||||
|
||||
paths = extractPackageFilesFromZip(rootFile, directoryName);
|
||||
if (paths != null) {
|
||||
return paths;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// not found
|
||||
throw new IOException("Cannot find source file location: '" + fileName + "'");
|
||||
}
|
||||
|
||||
private static
|
||||
boolean extractFilesFromZip(final File rootFile, final String nameAsFile) throws IOException {
|
||||
boolean found = false;
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(rootFile));
|
||||
ZipEntry entry;
|
||||
try {
|
||||
while ((entry = zipInputStream.getNextEntry()) != null) {
|
||||
String name = entry.getName();
|
||||
|
||||
if (name.equals(nameAsFile)) {
|
||||
// read out bytes!
|
||||
final File file = new File(tempDir, nameAsFile);
|
||||
if (!file.getParentFile().exists() && !file.getParentFile().mkdirs()) {
|
||||
throw new IOException("Unable to create temp dir: " + file.getParentFile());
|
||||
}
|
||||
|
||||
final FileOutputStream fileOutputStream = new FileOutputStream(file);
|
||||
try {
|
||||
copyStream(zipInputStream, fileOutputStream);
|
||||
found = true;
|
||||
} finally {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
|
||||
zipInputStream.closeEntry();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all of the directoryName files found in the zip file to temp dir. Only extracts the SAME LEVEL, not subdirs.
|
||||
*/
|
||||
private static
|
||||
Paths extractPackageFilesFromZip(final File rootFile, final String directoryName) throws IOException {
|
||||
final int length = directoryName.length();
|
||||
boolean found = false;
|
||||
Paths paths = new Paths();
|
||||
|
||||
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(rootFile));
|
||||
ZipEntry entry;
|
||||
try {
|
||||
while ((entry = zipInputStream.getNextEntry()) != null) {
|
||||
String name = entry.getName();
|
||||
|
||||
if (name.startsWith(directoryName) && !entry.isDirectory() && name.lastIndexOf('/') <= length && name.endsWith(".java")) {
|
||||
// read out bytes!
|
||||
final File file = new File(tempDir, directoryName);
|
||||
if (!file.exists() && !file.mkdirs()) {
|
||||
throw new IOException("Unable to create temp dir: " + file);
|
||||
}
|
||||
|
||||
final FileOutputStream fileOutputStream = new FileOutputStream(new File(tempDir, name));
|
||||
try {
|
||||
copyStream(zipInputStream, fileOutputStream);
|
||||
paths.add(tempDir.getAbsolutePath(), name);
|
||||
found = true;
|
||||
} finally {
|
||||
fileOutputStream.close();
|
||||
}
|
||||
|
||||
zipInputStream.closeEntry();
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
zipInputStream.close();
|
||||
}
|
||||
|
||||
if (found) {
|
||||
return paths;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static
|
||||
File getModuleDir(final File parent, final String moduleName) {
|
||||
final File file = moduleCache.get(moduleName);
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
|
||||
ArrayList<File> candidates = new ArrayList<File>();
|
||||
|
||||
getDirs(0, candidates, parent, moduleName);
|
||||
|
||||
for (File candidate : candidates) {
|
||||
// our src directory is always under the module dir
|
||||
if (new File(candidate, "src").isDirectory()) {
|
||||
// we also want to CACHE the module dir, as the search can take a while.
|
||||
moduleCache.put(moduleName, candidate);
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static
|
||||
void getDirs(final int i, ArrayList<File> candidates, final File parent, final String moduleName) {
|
||||
if (i > 4) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (File file : parent.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
if (file.getName().equals(moduleName)) {
|
||||
candidates.add(file);
|
||||
}
|
||||
else {
|
||||
getDirs(i + 1, candidates, file, moduleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy the contents of the input stream to the output stream.
|
||||
* <p/>
|
||||
* DOES NOT CLOSE THE STEAMS!
|
||||
*/
|
||||
public static
|
||||
<T extends OutputStream> T copyStream(InputStream inputStream, T outputStream) throws IOException {
|
||||
byte[] buffer = new byte[4096];
|
||||
int read;
|
||||
while ((read = inputStream.read(buffer)) > 0) {
|
||||
outputStream.write(buffer, 0, read);
|
||||
}
|
||||
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the file is a zip/jar file
|
||||
*/
|
||||
public static
|
||||
boolean isZipFile(File file) {
|
||||
byte[] ZIP_HEADER = {'P', 'K', 0x3, 0x4};
|
||||
boolean isZip = true;
|
||||
byte[] buffer = new byte[ZIP_HEADER.length];
|
||||
|
||||
RandomAccessFile raf = null;
|
||||
try {
|
||||
raf = new RandomAccessFile(file, "r");
|
||||
raf.readFully(buffer);
|
||||
for (int i = 0; i < ZIP_HEADER.length; i++) {
|
||||
if (buffer[i] != ZIP_HEADER[i]) {
|
||||
isZip = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
isZip = false;
|
||||
} finally {
|
||||
if (raf != null) {
|
||||
try {
|
||||
raf.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return isZip;
|
||||
}
|
||||
|
||||
|
||||
public static
|
||||
boolean deleteFile(String target) {
|
||||
return deleteFile(new File(FileUtil.normalizeAsFile(target)));
|
||||
}
|
||||
|
||||
public static
|
||||
boolean deleteFile(File target) {
|
||||
target = FileUtil.normalize(target);
|
||||
|
||||
log().title("Deleting file").println(target.getAbsolutePath());
|
||||
|
||||
return target.delete();
|
||||
}
|
||||
|
||||
public static
|
||||
File moveFile(String source, String target) throws IOException {
|
||||
source = FileUtil.normalizeAsFile(source);
|
||||
target = FileUtil.normalizeAsFile(target);
|
||||
|
||||
|
||||
log().title("Moving file").println(" ╭─ " + source, "╰─> " + target);
|
||||
|
||||
return FileUtil.moveFile(source, target);
|
||||
}
|
||||
|
||||
public static
|
||||
File copyFile(File source, File target) throws IOException {
|
||||
source = FileUtil.normalize(source);
|
||||
target = FileUtil.normalize(target);
|
||||
|
||||
|
||||
log().title("Copying file").println(" ╭─ " + source.getAbsolutePath(), "╰─> " + target.getAbsolutePath());
|
||||
|
||||
return FileUtil.copyFile(source, target);
|
||||
}
|
||||
|
||||
public static
|
||||
void copyFile(String source, String target) throws IOException {
|
||||
source = FileUtil.normalizeAsFile(source);
|
||||
target = FileUtil.normalizeAsFile(target);
|
||||
|
||||
log().title("Copying file").println(" ╭─ " + source, "╰─> " + target);
|
||||
|
||||
FileUtil.copyFile(source, target);
|
||||
}
|
||||
|
||||
public static
|
||||
void copyDirectory(String source, String target, String... dirNamesToIgnore) throws IOException {
|
||||
source = FileUtil.normalizeAsFile(source);
|
||||
target = FileUtil.normalizeAsFile(target);
|
||||
|
||||
log().title("Copying dir").println(" ╭─ " + source, "╰─> " + target);
|
||||
FileUtil.copyDirectory(source, target, dirNamesToIgnore);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package dorkbox;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public
|
||||
@interface Config {}
|
|
@ -0,0 +1,11 @@
|
|||
package dorkbox;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ElementType.TYPE})
|
||||
public
|
||||
@interface Instructions {}
|
|
@ -1,115 +0,0 @@
|
|||
package dorkbox;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.CodeSource;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
|
||||
public
|
||||
class Oak {
|
||||
|
||||
// ALSO copied over to OAK build dir (as an example), so make sure to update in both locations
|
||||
// ~/dorkbox/eclipse/jre/bin/java -jar dist/JavaBuilder_v1.3.jar build javabuilder
|
||||
// ~/dorkbox/eclipse/jre/bin/java -Xrunjdwp:transport=dt_socket,server=y,address=1044 -jar dist/JavaBuilder_v1.3.jar build javabuilder
|
||||
|
||||
|
||||
static {
|
||||
File oak = get();
|
||||
if (oak != null) {
|
||||
// we want to look for the libraries, because they are OFTEN going to be in the incorrect path.
|
||||
// this is only necessary if they aren't correctly loaded.
|
||||
try {
|
||||
Class.forName("com.esotericsoftware.wildcard.Paths");
|
||||
} catch (Exception e) {
|
||||
// whoops. can't find it on the path
|
||||
// System.err.println("Execution path: " + oak);
|
||||
|
||||
File libDir = new File(oak.getParentFile(), "libs");
|
||||
if (!libDir.isDirectory()) {
|
||||
libDir = new File(oak.getParentFile().getParentFile(), "libs");
|
||||
}
|
||||
|
||||
if (!libDir.isDirectory()) {
|
||||
throw new RuntimeException("Unable to find the libs directory for execution: " + oak);
|
||||
}
|
||||
|
||||
Class<?>[] parameters = new Class[] {URL.class};
|
||||
Class<URLClassLoader> sysclass = URLClassLoader.class;
|
||||
URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
|
||||
|
||||
try {
|
||||
Method method = sysclass.getDeclaredMethod("addURL", parameters);
|
||||
method.setAccessible(true);
|
||||
|
||||
// add lib dir jars
|
||||
for (File f : libDir.listFiles()) {
|
||||
if (!f.isDirectory() && f.canRead() && f.getName().endsWith(".jar")) {
|
||||
// System.err.println("adding url " + f.getAbsolutePath());
|
||||
method.invoke(sysloader, new Object[] {f.toURI().toURL()});
|
||||
}
|
||||
}
|
||||
|
||||
// now have to add fastMD5 sum jars
|
||||
libDir = new File(libDir, "fast-md5");
|
||||
for (File f : libDir.listFiles()) {
|
||||
if (!f.isDirectory() && f.canRead() && f.getName().endsWith(".jar")) {
|
||||
// System.err.println("adding url " + f.getAbsolutePath());
|
||||
method.invoke(sysloader, new Object[] {f.toURI().toURL()});
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
throw new RuntimeException("Unable to load the libs directory for execution: " + libDir);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static
|
||||
File get() {
|
||||
return get(Oak.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the location that this classfile was loaded from, or possibly null if the class was compiled on the fly
|
||||
*/
|
||||
public static
|
||||
File get(Class<?> clazz) {
|
||||
// Get the location of this class
|
||||
ProtectionDomain pDomain = clazz.getProtectionDomain();
|
||||
CodeSource cSource = pDomain.getCodeSource();
|
||||
|
||||
// file:/X:/workspace/XYZ/classes/ when it's in ide/flat
|
||||
// jar:/X:/workspace/XYZ/jarname.jar when it's jar
|
||||
URL loc = cSource.getLocation();
|
||||
|
||||
// we don't always have a protection domain (for example, when we compile classes on the fly, from memory)
|
||||
if (loc == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Can have %20 as spaces (in winxp at least). need to convert to proper path from URL
|
||||
try {
|
||||
String fileName = URLDecoder.decode(loc.getFile(), "UTF-8");
|
||||
File file = new File(fileName).getAbsoluteFile().getCanonicalFile();
|
||||
return file;
|
||||
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new RuntimeException("Unable to decode file path!", e);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Unable to get canonical file path!", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static
|
||||
void main(String... _args) throws Exception {
|
||||
// now startup like normal
|
||||
Build.start(_args);
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ import java.io.IOException;
|
|||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.build.util.PreJarAction;
|
||||
import dorkbox.build.util.jar.JarOptions;
|
||||
import dorkbox.build.util.jar.JarSigner;
|
||||
|
@ -86,7 +86,7 @@ public class Jarable {
|
|||
/** Builds a jar from the specified source files, class file, and extras */
|
||||
void buildJar() throws IOException {
|
||||
if (this.preJarAction != null) {
|
||||
Build.log().println("Running action before Jar is created...");
|
||||
Builder.log().println("Running action before Jar is created...");
|
||||
this.preJarAction.executeBeforeJarHappens(this.projectJava.stagingDir);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ package dorkbox.build;
|
|||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
import com.twmacinta.util.MD5;
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.BuildOptions;
|
||||
import dorkbox.build.util.BuildLog;
|
||||
import dorkbox.license.License;
|
||||
|
@ -52,7 +52,7 @@ class Project<T extends Project<T>> {
|
|||
public static List<File> builderFiles = new ArrayList<File>();
|
||||
|
||||
static {
|
||||
if (!Build.isJar) {
|
||||
if (!Builder.isJar) {
|
||||
// check to see if our deploy code has changed. if yes, then we have to rebuild everything since
|
||||
// we don't know what might have changed.
|
||||
Paths paths = new Paths();
|
||||
|
@ -64,7 +64,7 @@ class Project<T extends Project<T>> {
|
|||
}
|
||||
|
||||
try {
|
||||
String oldHash = Build.settings.get("BUILD", String.class);
|
||||
String oldHash = Builder.settings.get("BUILD", String.class);
|
||||
String hashedContents = generateChecksums(paths);
|
||||
|
||||
if (oldHash != null) {
|
||||
|
@ -79,9 +79,9 @@ class Project<T extends Project<T>> {
|
|||
if (forceRebuild) {
|
||||
if (!alreadyChecked) {
|
||||
alreadyChecked = true;
|
||||
Build.log().println("Build system changed. Rebuilding.");
|
||||
Builder.log().println("Build system changed. Rebuilding.");
|
||||
}
|
||||
Build.settings.save("BUILD", hashedContents);
|
||||
Builder.settings.save("BUILD", hashedContents);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ class Project<T extends Project<T>> {
|
|||
// exit early if we already built this project
|
||||
if (buildList.contains(this.name)) {
|
||||
if (!this.isBuildingDependencies) {
|
||||
Build.log().title("Building").println(this.name + " already built this run");
|
||||
Builder.log().title("Building").println(this.name + " already built this run");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ class Project<T extends Project<T>> {
|
|||
for (Project<?> s : deps) {
|
||||
array[i++] = s.name;
|
||||
}
|
||||
Build.log().title(this.name).println((Object[]) array);
|
||||
Builder.log().title(this.name).println((Object[]) array);
|
||||
}
|
||||
|
||||
for (Project<?> project : deps) {
|
||||
|
@ -491,7 +491,7 @@ class Project<T extends Project<T>> {
|
|||
// copy dist dir over
|
||||
boolean canCopySingles = false;
|
||||
if (this.distLocation != null) {
|
||||
Build.copyDirectory(this.distLocation, targetLocation.getAbsolutePath());
|
||||
Builder.copyDirectory(this.distLocation, targetLocation.getAbsolutePath());
|
||||
|
||||
if (this.outputFile == null || !this.outputFile.getAbsolutePath().startsWith(this.distLocation)) {
|
||||
canCopySingles = true;
|
||||
|
@ -503,16 +503,16 @@ class Project<T extends Project<T>> {
|
|||
|
||||
if (canCopySingles) {
|
||||
if (this.outputFile != null && this.outputFile.canRead()) {
|
||||
Build.copyFile(this.outputFile, new File(targetLocation, this.outputFile.getName()));
|
||||
Builder.copyFile(this.outputFile, new File(targetLocation, this.outputFile.getName()));
|
||||
}
|
||||
|
||||
// do we have a "source" file as well?
|
||||
if (this.outputFileSource != null && this.outputFileSource.canRead()) {
|
||||
Build.copyFile(this.outputFileSource, new File(targetLocation, this.outputFileSource.getName()));
|
||||
Builder.copyFile(this.outputFileSource, new File(targetLocation, this.outputFileSource.getName()));
|
||||
}
|
||||
|
||||
for (File f : this.sources) {
|
||||
Build.copyFile(f, new File(targetLocation, f.getName()));
|
||||
Builder.copyFile(f, new File(targetLocation, f.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,7 +525,7 @@ class Project<T extends Project<T>> {
|
|||
File source = new File(fullPaths.get(i));
|
||||
|
||||
if (source.isFile()) {
|
||||
Build.copyFile(source, new File(targetLocation, relativePaths.get(i)));
|
||||
Builder.copyFile(source, new File(targetLocation, relativePaths.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -560,7 +560,7 @@ class Project<T extends Project<T>> {
|
|||
|
||||
// check to see if our SOURCES *and check-summed files* have changed.
|
||||
String hashedContents = generateChecksums(this.checksumPaths);
|
||||
String checkContents = Build.settings.get(this.name, String.class);
|
||||
String checkContents = Builder.settings.get(this.name, String.class);
|
||||
|
||||
return hashedContents != null && hashedContents.equals(checkContents);
|
||||
}
|
||||
|
@ -571,7 +571,7 @@ class Project<T extends Project<T>> {
|
|||
void saveChecksums() throws IOException {
|
||||
// hash/save the sources *and check-summed files* files
|
||||
String hashedContents = generateChecksums(this.checksumPaths);
|
||||
Build.settings.save(this.name, hashedContents);
|
||||
Builder.settings.save(this.name, hashedContents);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -27,7 +27,7 @@ import java.util.Map.Entry;
|
|||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.build.util.jar.JarUtil;
|
||||
import dorkbox.util.FileUtil;
|
||||
import dorkbox.util.gwt.GwtSymbolMapParser;
|
||||
|
@ -89,7 +89,7 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
// if the sources are the same, check the output dir
|
||||
if (this.stagingDir.exists()) {
|
||||
String dirChecksum = generateChecksum(this.stagingDir);
|
||||
String checkContents = Build.settings.get(this.stagingDir.getAbsolutePath(), String.class);
|
||||
String checkContents = Builder.settings.get(this.stagingDir.getAbsolutePath(), String.class);
|
||||
|
||||
return dirChecksum != null && dirChecksum.equals(checkContents);
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
// hash/save the output files (if there are any)
|
||||
if (this.stagingDir.exists()) {
|
||||
String fileChecksum = generateChecksum(this.stagingDir);
|
||||
Build.settings.save(this.stagingDir.getAbsolutePath(), fileChecksum);
|
||||
Builder.settings.save(this.stagingDir.getAbsolutePath(), fileChecksum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,18 +144,18 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
|
||||
String clientString = "Client";
|
||||
|
||||
String stagingWar = Build.path(STAGING, "war");
|
||||
String stagingWarWebINF = Build.path(stagingWar, "WEB-INF");
|
||||
String stagingWarWebINFDeploy = Build.path(stagingWarWebINF, "deploy");
|
||||
String stagingWar = Builder.path(STAGING, "war");
|
||||
String stagingWarWebINF = Builder.path(stagingWar, "WEB-INF");
|
||||
String stagingWarWebINFDeploy = Builder.path(stagingWarWebINF, "deploy");
|
||||
|
||||
|
||||
String stagingJunk = Build.path(STAGING, "junk");
|
||||
String stagingUnitCache = Build.path(STAGING, "gwt-unitCache");
|
||||
String stagingSymbols = Build.path(STAGING, "symbolMaps");
|
||||
String clientTempLocation = Build.path(STAGING, clientString + "_javascript");
|
||||
String stagingJunk = Builder.path(STAGING, "junk");
|
||||
String stagingUnitCache = Builder.path(STAGING, "gwt-unitCache");
|
||||
String stagingSymbols = Builder.path(STAGING, "symbolMaps");
|
||||
String clientTempLocation = Builder.path(STAGING, clientString + "_javascript");
|
||||
|
||||
|
||||
String srcWarPath = Build.path("..", this.projectLocation, "war");
|
||||
String srcWarPath = Builder.path("..", this.projectLocation, "war");
|
||||
|
||||
// make the output directory
|
||||
FileUtil.delete(stagingWar);
|
||||
|
@ -244,15 +244,15 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
|
||||
// move the symbol maps to the correct spot
|
||||
FileUtil.mkdir(stagingSymbols);
|
||||
Paths symbolMapPaths = new Paths(Build.path(stagingWarWebINFDeploy, clientString, "symbolMaps"), "*.symbolMap");
|
||||
Paths symbolMapPaths = new Paths(Builder.path(stagingWarWebINFDeploy, clientString, "symbolMaps"), "*.symbolMap");
|
||||
for (File file : symbolMapPaths.getFiles()) {
|
||||
// clean up the symbolmaps first!
|
||||
parseAndCopyGwtSymbols(file, new File(Build.path(stagingSymbols, file.getName())));
|
||||
parseAndCopyGwtSymbols(file, new File(Builder.path(stagingSymbols, file.getName())));
|
||||
}
|
||||
|
||||
|
||||
// move the client generated javascript to the correct spot
|
||||
FileUtil.moveDirectory(Build.path(stagingWar, clientString), clientTempLocation);
|
||||
FileUtil.moveDirectory(Builder.path(stagingWar, clientString), clientTempLocation);
|
||||
|
||||
|
||||
// remove directories that are not needed/wanted in the deployment
|
||||
|
@ -269,18 +269,18 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
// todo: pass in the hive-webclient project name somehow?
|
||||
Paths warFiles = new Paths(srcWarPath, "*.html", "*.ico");
|
||||
for (File file : warFiles.getFiles()) {
|
||||
FileUtil.copyFile(file.getAbsolutePath(), Build.path(stagingWar, file.getName()));
|
||||
FileUtil.copyFile(file.getAbsolutePath(), Builder.path(stagingWar, file.getName()));
|
||||
}
|
||||
|
||||
// copy over images
|
||||
FileUtil.copyDirectory(Build.path(srcWarPath, "images"), Build.path(stagingWar, "images"), ".svn");
|
||||
FileUtil.copyDirectory(Builder.path(srcWarPath, "images"), Builder.path(stagingWar, "images"), ".svn");
|
||||
|
||||
|
||||
// make the web-INF directory
|
||||
FileUtil.mkdir(stagingWarWebINF);
|
||||
|
||||
// move the symbolMaps into the correct spot.
|
||||
FileUtil.moveDirectory(stagingSymbols, Build.path(stagingWarWebINF, "symbolMaps"));
|
||||
FileUtil.moveDirectory(stagingSymbols, Builder.path(stagingWarWebINF, "symbolMaps"));
|
||||
|
||||
// add any extra files to the output war dir.
|
||||
File warDir = new File(stagingWar);
|
||||
|
@ -294,7 +294,7 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
}
|
||||
|
||||
// move the client generated javascript to the correct spot
|
||||
FileUtil.moveDirectory(clientTempLocation, Build.path(stagingWar, clientString));
|
||||
FileUtil.moveDirectory(clientTempLocation, Builder.path(stagingWar, clientString));
|
||||
|
||||
|
||||
// war it up
|
||||
|
@ -318,7 +318,7 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
// calculate the hash of all the files in the source path
|
||||
saveChecksums();
|
||||
} else {
|
||||
Build.log().println("Skipped (nothing changed)");
|
||||
Builder.log().println("Skipped (nothing changed)");
|
||||
}
|
||||
} finally {
|
||||
if (shouldBuild) {
|
||||
|
@ -385,4 +385,4 @@ public class ProjectGwt extends Project<ProjectGwt> {
|
|||
public String getExtension() {
|
||||
return ".war";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ import com.esotericsoftware.yamlbeans.YamlException;
|
|||
import com.esotericsoftware.yamlbeans.YamlWriter;
|
||||
import com.esotericsoftware.yamlbeans.scalar.ScalarSerializer;
|
||||
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.build.util.BuildLog;
|
||||
import dorkbox.build.util.classloader.ByteClassloader;
|
||||
import dorkbox.build.util.classloader.JavaMemFileManager;
|
||||
|
@ -155,12 +155,12 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
return;
|
||||
}
|
||||
|
||||
Build.log().println();
|
||||
Builder.log().println();
|
||||
if (this.bytesClassloader == null && this.jarable == null) {
|
||||
Build.log().title("Building").println(this.name, "Output - " + this.stagingDir);
|
||||
Builder.log().title("Building").println(this.name, "Output - " + this.stagingDir);
|
||||
}
|
||||
else {
|
||||
Build.log().title("Building").println(this.name);
|
||||
Builder.log().title("Building").println(this.name);
|
||||
}
|
||||
|
||||
boolean shouldBuild = !verifyChecksums();
|
||||
|
@ -187,7 +187,7 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
}
|
||||
|
||||
runCompile();
|
||||
Build.log().println("Compile success");
|
||||
Builder.log().println("Compile success");
|
||||
|
||||
if (this.jarable != null) {
|
||||
this.jarable.buildJar();
|
||||
|
@ -199,7 +199,7 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
FileUtil.delete(this.stagingDir);
|
||||
}
|
||||
else {
|
||||
Build.log().println("Skipped (nothing changed)");
|
||||
Builder.log().println("Skipped (nothing changed)");
|
||||
}
|
||||
|
||||
buildList.add(this.name);
|
||||
|
@ -226,7 +226,7 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
// if the sources are the same, check the jar file
|
||||
if (this.jarable != null && this.outputFile.canRead()) {
|
||||
String jarChecksum = generateChecksum(this.outputFile);
|
||||
String checkContents = Build.settings.get(this.outputFile.getAbsolutePath(), String.class);
|
||||
String checkContents = Builder.settings.get(this.outputFile.getAbsolutePath(), String.class);
|
||||
|
||||
boolean outputFileGood = jarChecksum != null && jarChecksum.equals(checkContents);
|
||||
|
||||
|
@ -237,7 +237,7 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
else {
|
||||
// now check the src.zip file (if there was one).
|
||||
jarChecksum = generateChecksum(this.outputFileSource);
|
||||
checkContents = Build.settings.get(this.outputFileSource.getAbsolutePath(), String.class);
|
||||
checkContents = Builder.settings.get(this.outputFileSource.getAbsolutePath(), String.class);
|
||||
|
||||
return jarChecksum != null && jarChecksum.equals(checkContents);
|
||||
}
|
||||
|
@ -257,13 +257,13 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
// hash/save the jar file (if there was one)
|
||||
if (this.outputFile.exists()) {
|
||||
String fileChecksum = generateChecksum(this.outputFile);
|
||||
Build.settings.save(this.outputFile.getAbsolutePath(), fileChecksum);
|
||||
Builder.settings.save(this.outputFile.getAbsolutePath(), fileChecksum);
|
||||
|
||||
if (this.jarable != null && this.jarable.includeSourceAsSeparate) {
|
||||
// now check the src.zip file (if there was one).
|
||||
fileChecksum = generateChecksum(this.outputFileSource);
|
||||
|
||||
Build.settings.save(this.outputFileSource.getAbsolutePath(), fileChecksum);
|
||||
Builder.settings.save(this.outputFileSource.getAbsolutePath(), fileChecksum);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -291,7 +291,7 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
}
|
||||
|
||||
if (this.buildOptions.compiler.debugEnabled) {
|
||||
Build.log().println("Adding debug info");
|
||||
Builder.log().println("Adding debug info");
|
||||
|
||||
args.add("-g"); // Generate all debugging information, including local variables. By default, only line number and source file information is generated.
|
||||
}
|
||||
|
@ -312,7 +312,7 @@ class ProjectJava extends Project<ProjectJava> {
|
|||
args.add("UTF-8");
|
||||
|
||||
if (OS.getJavaVersion() > this.buildOptions.compiler.targetJavaVersion) {
|
||||
Build.log().println("Building cross-platform target for version: " + this.buildOptions.compiler.targetJavaVersion);
|
||||
Builder.log().println("Building cross-platform target for version: " + this.buildOptions.compiler.targetJavaVersion);
|
||||
// if our runtime env. is NOT equal to our target env.
|
||||
args.add("-source");
|
||||
args.add("1." + this.buildOptions.compiler.targetJavaVersion);
|
||||
|
|
|
@ -33,7 +33,7 @@ import com.esotericsoftware.yamlbeans.YamlReader;
|
|||
import com.esotericsoftware.yamlbeans.parser.Parser.ParserException;
|
||||
import com.esotericsoftware.yamlbeans.tokenizer.Tokenizer.TokenizerException;
|
||||
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.build.SimpleArgs;
|
||||
import dorkbox.util.FileUtil;
|
||||
import dorkbox.util.Sys;
|
||||
|
@ -54,11 +54,11 @@ public class BuildParser {
|
|||
|
||||
final File file = new File(normalizeAsFile);
|
||||
if (!file.canRead()) {
|
||||
Build.log().title("Build location").println("Build instructions not found", normalizeAsFile);
|
||||
Builder.log().title("Build location").println("Build instructions not found", normalizeAsFile);
|
||||
return data;
|
||||
}
|
||||
|
||||
Build.log().title("Build location").println("Compiling build instructions", normalizeAsFile);
|
||||
Builder.log().title("Build location").println("Compiling build instructions", normalizeAsFile);
|
||||
|
||||
|
||||
// replace $dir$ with the parent dir, for use in parameters
|
||||
|
|
|
@ -53,7 +53,7 @@ import org.bouncycastle.crypto.util.PrivateKeyFactory;
|
|||
import org.bouncycastle.crypto.util.PublicKeyFactory;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.util.Base64Fast;
|
||||
import dorkbox.util.Sys;
|
||||
import dorkbox.util.crypto.Crypto;
|
||||
|
@ -68,8 +68,8 @@ public class JarSigner {
|
|||
|
||||
public static File sign(String jarName, String name) {
|
||||
|
||||
Build.log().println();
|
||||
Build.log().title("Signing JAR").println(jarName, name.toUpperCase());
|
||||
Builder.log().println();
|
||||
Builder.log().title("Signing JAR").println(jarName, name.toUpperCase());
|
||||
|
||||
if (jarName == null) {
|
||||
throw new IllegalArgumentException("jarName cannot be null.");
|
||||
|
@ -313,4 +313,4 @@ public class JarSigner {
|
|||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,73 +15,37 @@
|
|||
*/
|
||||
package dorkbox.build.util.jar;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.Writer;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
import java.util.zip.ZipInputStream;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
||||
import org.bouncycastle.crypto.digests.SHA512Digest;
|
||||
|
||||
import com.esotericsoftware.wildcard.Paths;
|
||||
import com.ice.tar.TarEntry;
|
||||
import com.ice.tar.TarInputStream;
|
||||
|
||||
import dorkbox.Build;
|
||||
import dorkbox.BuildOptions;
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.build.util.BuildLog;
|
||||
import dorkbox.license.License;
|
||||
import dorkbox.util.Base64Fast;
|
||||
import dorkbox.util.FileUtil;
|
||||
import dorkbox.util.LZMA;
|
||||
import dorkbox.util.OS;
|
||||
import dorkbox.util.Sys;
|
||||
import dorkbox.util.*;
|
||||
import org.bouncycastle.crypto.digests.SHA512Digest;
|
||||
|
||||
public class JarUtil {
|
||||
import java.io.*;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.jar.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
public
|
||||
class JarUtil {
|
||||
public static int JAR_COMPRESSION_LEVEL = 9;
|
||||
|
||||
public static byte[] ZIP_HEADER = { 80, 75, 3, 4 }; // PK34
|
||||
public static byte[] ZIP_HEADER = {80, 75, 3, 4}; // PK34
|
||||
|
||||
public static final String metaInfName = "META-INF/";
|
||||
public static final String configFile = "config.ini";
|
||||
public static final String configFile = "config.ini";
|
||||
|
||||
/**
|
||||
* @return true if the file is a zip/jar file
|
||||
*/
|
||||
public static boolean isZipFile(File file) {
|
||||
public static
|
||||
boolean isZipFile(File file) {
|
||||
boolean isZip = true;
|
||||
byte[] buffer = new byte[ZIP_HEADER.length];
|
||||
|
||||
|
@ -112,12 +76,13 @@ public class JarUtil {
|
|||
/**
|
||||
* @return true if the file is a zip/jar stream
|
||||
*/
|
||||
public static boolean isZipStream(ByteArrayInputStream input) {
|
||||
public static
|
||||
boolean isZipStream(ByteArrayInputStream input) {
|
||||
boolean isZip = true;
|
||||
int length = ZIP_HEADER.length;
|
||||
|
||||
try {
|
||||
input.mark(length+1);
|
||||
input.mark(length + 1);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
byte read = (byte) input.read();
|
||||
|
@ -137,7 +102,8 @@ public class JarUtil {
|
|||
* retrieve the manifest from a jar file -- this will either load a
|
||||
* pre-existing META-INF/MANIFEST.MF, or return null if none
|
||||
*/
|
||||
public static final Manifest getManifestFile(JarFile jarFile) throws IOException {
|
||||
public static final
|
||||
Manifest getManifestFile(JarFile jarFile) throws IOException {
|
||||
JarEntry je = jarFile.getJarEntry(JarFile.MANIFEST_NAME);
|
||||
|
||||
// verify that it really exists.
|
||||
|
@ -147,7 +113,8 @@ public class JarUtil {
|
|||
je = jarEntries.nextElement();
|
||||
if (JarFile.MANIFEST_NAME.equals(je.getName())) {
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
je = null;
|
||||
}
|
||||
}
|
||||
|
@ -159,7 +126,8 @@ public class JarUtil {
|
|||
Sys.close(inputStream);
|
||||
|
||||
return manifest;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -167,10 +135,11 @@ public class JarUtil {
|
|||
/**
|
||||
* a helper function that can take entries from one jar file and write it to
|
||||
* another jar stream
|
||||
*
|
||||
* <p/>
|
||||
* Will close the output stream automatically.
|
||||
*/
|
||||
public static final void writeZipEntry(ZipEntry entry, ZipFile zipInputFile, ZipOutputStream zipOutputStream) throws IOException {
|
||||
public static final
|
||||
void writeZipEntry(ZipEntry entry, ZipFile zipInputFile, ZipOutputStream zipOutputStream) throws IOException {
|
||||
// create a new entry to avoid ZipException: invalid entry compressed size
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
newEntry.setTime(entry.getTime());
|
||||
|
@ -192,10 +161,11 @@ public class JarUtil {
|
|||
/**
|
||||
* a helper function that can take entries from one jar file and write it to
|
||||
* another jar stream
|
||||
*
|
||||
* <p/>
|
||||
* Does NOT close any streams!
|
||||
*/
|
||||
public static void writeZipEntry(ZipEntry entry, ZipInputStream zipInputStream, ZipOutputStream zipOutputStream) throws IOException {
|
||||
public static
|
||||
void writeZipEntry(ZipEntry entry, ZipInputStream zipInputStream, ZipOutputStream zipOutputStream) throws IOException {
|
||||
ZipEntry newEntry = new ZipEntry(entry.getName());
|
||||
newEntry.setTime(entry.getTime());
|
||||
newEntry.setComment(entry.getComment());
|
||||
|
@ -213,7 +183,8 @@ public class JarUtil {
|
|||
}
|
||||
|
||||
|
||||
public static final String updateDigest(InputStream inputStream, MessageDigest digest) throws IOException {
|
||||
public static final
|
||||
String updateDigest(InputStream inputStream, MessageDigest digest) throws IOException {
|
||||
byte[] buffer = new byte[2048];
|
||||
int read = 0;
|
||||
digest.reset();
|
||||
|
@ -234,8 +205,9 @@ public class JarUtil {
|
|||
return Base64Fast.encodeToString(digestBytes, false);
|
||||
}
|
||||
|
||||
public static final ByteArrayOutputStream createNewJar(JarFile jar, String name, byte[] manifestBytes,
|
||||
byte[] signatureFileManifestBytes, byte[] signatureBlockBytes) throws IOException {
|
||||
public static final
|
||||
ByteArrayOutputStream createNewJar(JarFile jar, String name, byte[] manifestBytes, byte[] signatureFileManifestBytes,
|
||||
byte[] signatureBlockBytes) throws IOException {
|
||||
|
||||
name = name.toUpperCase();
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
|
@ -279,8 +251,9 @@ public class JarUtil {
|
|||
JarEntry metaEntry = metaEntries.nextElement();
|
||||
String entryName = metaEntry.getName();
|
||||
|
||||
if (entryName.startsWith(metaInfName)
|
||||
&& !(JarFile.MANIFEST_NAME.equalsIgnoreCase(entryName) || signatureFileName.equalsIgnoreCase(entryName) || signatureBlockName.equalsIgnoreCase(entryName))) {
|
||||
if (entryName.startsWith(metaInfName) && !(JarFile.MANIFEST_NAME.equalsIgnoreCase(entryName) ||
|
||||
signatureFileName.equalsIgnoreCase(entryName) || signatureBlockName.equalsIgnoreCase(
|
||||
entryName))) {
|
||||
|
||||
JarUtil.writeZipEntry(metaEntry, jar, jarOutputStream);
|
||||
}
|
||||
|
@ -307,9 +280,9 @@ public class JarUtil {
|
|||
/**
|
||||
* removes all of the (META-INF, OSGI-INF, etc) information (removes the entire directory), AND ALSO removes all comments from the files
|
||||
*/
|
||||
public static InputStream removeManifestCommentsAndFiles(String fileName, InputStream inputStream,
|
||||
String[] pathToRemove, String[] pathToKeep,
|
||||
Set<String> stripped) throws IOException {
|
||||
public static
|
||||
InputStream removeManifestCommentsAndFiles(String fileName, InputStream inputStream, String[] pathToRemove, String[] pathToKeep,
|
||||
Set<String> stripped) throws IOException {
|
||||
// shortcut out -- nothing to do
|
||||
if (pathToRemove == null || pathToRemove.length == 0) {
|
||||
return inputStream;
|
||||
|
@ -369,16 +342,16 @@ public class JarUtil {
|
|||
/**
|
||||
* Creates a zip file, similar to how jar() works, only minus jar-specific stuff (manifest, etc)
|
||||
*/
|
||||
public static void zip(JarOptions options) throws IOException {
|
||||
public static
|
||||
void zip(JarOptions options) throws IOException {
|
||||
if (options.outputFile == null) {
|
||||
throw new IllegalArgumentException("jarFile cannot be null.");
|
||||
}
|
||||
|
||||
int totalEntries = options.sourcePaths.count();
|
||||
|
||||
Build.log().println();
|
||||
Build.log().title("Creating ZIP").println("(" + totalEntries + " entries)",
|
||||
options.outputFile.getAbsolutePath());
|
||||
Builder.log().println();
|
||||
Builder.log().title("Creating ZIP").println("(" + totalEntries + " entries)", options.outputFile.getAbsolutePath());
|
||||
|
||||
|
||||
List<String> fullPaths = options.sourcePaths.getPaths();
|
||||
|
@ -420,7 +393,7 @@ public class JarUtil {
|
|||
Collections.sort(sortList);
|
||||
for (String dirName : sortList) {
|
||||
ZipEntry zipEntry = new ZipEntry(dirName);
|
||||
zipEntry.setTime(Build.buildDate); // hidden when view as a jar, but it's always there
|
||||
zipEntry.setTime(Builder.buildDate); // hidden when view as a jar, but it's always there
|
||||
output.putNextEntry(zipEntry);
|
||||
output.closeEntry();
|
||||
}
|
||||
|
@ -432,7 +405,7 @@ public class JarUtil {
|
|||
if (options.sourcePaths != null && !options.sourcePaths.isEmpty()) {
|
||||
ArrayList<SortedFiles> sortList2 = new ArrayList<SortedFiles>(options.sourcePaths.count());
|
||||
|
||||
Build.log().println(" Adding sources (" + options.sourcePaths.count() + " entries)...");
|
||||
Builder.log().println(" Adding sources (" + options.sourcePaths.count() + " entries)...");
|
||||
|
||||
for (int i = 0, n = fullPaths.size(); i < n; i++) {
|
||||
String fileName = relativePaths.get(i).replace('\\', '/');
|
||||
|
@ -451,7 +424,8 @@ public class JarUtil {
|
|||
ZipEntry zipEntry = new ZipEntry(cf.fileName);
|
||||
if (options.overrideDate > -1) {
|
||||
zipEntry.setTime(options.overrideDate);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
zipEntry.setTime(cf.file.lastModified());
|
||||
}
|
||||
output.putNextEntry(zipEntry);
|
||||
|
@ -468,7 +442,7 @@ public class JarUtil {
|
|||
// now include the license, if possible
|
||||
///////////////////////////////////////////////
|
||||
if (options.licenses != null) {
|
||||
Build.log().println(" Adding license");
|
||||
Builder.log().println(" Adding license");
|
||||
License.install(output, options.licenses, options.overrideDate);
|
||||
}
|
||||
} finally {
|
||||
|
@ -490,16 +464,17 @@ public class JarUtil {
|
|||
/**
|
||||
* This will ALSO normalize (pack+unpack) the jar AND strip/purge all LICENSE*.* info from sub-dirs/jars (ONLY the
|
||||
* specified licenses will be included)
|
||||
*
|
||||
* <p/>
|
||||
* Note about JarOutputStream:
|
||||
* The JAR_MAGIC "0xCAFE" in the extra field data of the first JAR entry from our JarOutputStream implementation is
|
||||
* not required by JAR specification. It's an "internal implementation detail" to support "executable" jar on Solaris
|
||||
* platform. see#4138619. It would be incorrect to reject a JAR file that does not have this extra field data, from
|
||||
* specification point of view.
|
||||
*
|
||||
* (basically, if you use a JarOutputStream, it adds in extra crap we don't want)
|
||||
* The JAR_MAGIC "0xCAFE" in the extra field data of the first JAR entry from our JarOutputStream implementation is
|
||||
* not required by JAR specification. It's an "internal implementation detail" to support "executable" jar on Solaris
|
||||
* platform. see#4138619. It would be incorrect to reject a JAR file that does not have this extra field data, from
|
||||
* specification point of view.
|
||||
* <p/>
|
||||
* (basically, if you use a JarOutputStream, it adds in extra crap we don't want)
|
||||
*/
|
||||
public static void jar(JarOptions options) throws IOException {
|
||||
public static
|
||||
void jar(JarOptions options) throws IOException {
|
||||
|
||||
if (options.outputFile == null) {
|
||||
throw new IllegalArgumentException("jarFile cannot be null.");
|
||||
|
@ -554,10 +529,9 @@ public class JarUtil {
|
|||
}
|
||||
|
||||
|
||||
BuildLog log = Build.log();
|
||||
BuildLog log = Builder.log();
|
||||
log.println();
|
||||
log.title("Creating JAR").println(totalEntries + " total entries",
|
||||
options.outputFile.getAbsolutePath());
|
||||
log.title("Creating JAR").println(totalEntries + " total entries", options.outputFile.getAbsolutePath());
|
||||
|
||||
|
||||
// CLEANUP DIRECTORIES
|
||||
|
@ -581,10 +555,10 @@ public class JarUtil {
|
|||
///////////////////////////////////////////////
|
||||
if (manifest != null) {
|
||||
Attributes attributes = manifest.getMainAttributes();
|
||||
attributes.putValue("Build-Date", new Date(Build.buildDate).toString() + " (" + Long.toString(Build.buildDate) + ")");
|
||||
attributes.putValue("Build-Date", new Date(Builder.buildDate).toString() + " (" + Long.toString(Builder.buildDate) + ")");
|
||||
|
||||
JarEntry jarEntry = new JarEntry(JarFile.MANIFEST_NAME);
|
||||
jarEntry.setTime(Build.buildDate);
|
||||
jarEntry.setTime(Builder.buildDate);
|
||||
output.putNextEntry(jarEntry);
|
||||
|
||||
manifest.write(output);
|
||||
|
@ -612,7 +586,7 @@ public class JarUtil {
|
|||
Collections.sort(sortedDirectories);
|
||||
for (String dirName : sortedDirectories) {
|
||||
JarEntry jarEntry = new JarEntry(dirName);
|
||||
jarEntry.setTime(Build.buildDate); // hidden when view a jar, but it's always there
|
||||
jarEntry.setTime(Builder.buildDate); // hidden when view a jar, but it's always there
|
||||
output.putNextEntry(jarEntry);
|
||||
output.closeEntry();
|
||||
}
|
||||
|
@ -653,7 +627,8 @@ public class JarUtil {
|
|||
JarEntry jarEntry = new JarEntry(cf.fileName);
|
||||
if (options.overrideDate > -1) {
|
||||
jarEntry.setTime(options.overrideDate);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
jarEntry.setTime(cf.file.lastModified());
|
||||
}
|
||||
output.putNextEntry(jarEntry);
|
||||
|
@ -674,7 +649,8 @@ public class JarUtil {
|
|||
JarEntry jarEntry = new JarEntry(fileName);
|
||||
if (options.overrideDate > -1) {
|
||||
jarEntry.setTime(options.overrideDate);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
jarEntry.setTime(cf.file.lastModified());
|
||||
}
|
||||
output.putNextEntry(jarEntry);
|
||||
|
@ -696,7 +672,8 @@ public class JarUtil {
|
|||
if (targetManifest == null) {
|
||||
outputStream = JarUtil.removeLicenseInfo(jarInputStream);
|
||||
input = new ByteArrayInputStream(outputStream.toByteArray());
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
input.reset();
|
||||
}
|
||||
}
|
||||
|
@ -709,7 +686,6 @@ public class JarUtil {
|
|||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
// NOW we do the EXTRA files.
|
||||
// These files will MATCH the path hierarchy in the jar
|
||||
|
@ -742,7 +718,8 @@ public class JarUtil {
|
|||
JarEntry jarEntry = new JarEntry(cf.fileName);
|
||||
if (options.overrideDate > -1) {
|
||||
jarEntry.setTime(options.overrideDate);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
jarEntry.setTime(cf.file.lastModified());
|
||||
}
|
||||
output.putNextEntry(jarEntry);
|
||||
|
@ -785,7 +762,8 @@ public class JarUtil {
|
|||
JarEntry jarEntry = new JarEntry(cf.fileName);
|
||||
if (options.overrideDate > -1) {
|
||||
jarEntry.setTime(options.overrideDate);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
jarEntry.setTime(cf.file.lastModified());
|
||||
}
|
||||
output.putNextEntry(jarEntry);
|
||||
|
@ -824,10 +802,11 @@ public class JarUtil {
|
|||
|
||||
/**
|
||||
* Removes the license information in a jar input stream. (IE: LICENSE, LICENSE.MIT, license.md, etc)
|
||||
* <p>
|
||||
* <p/>
|
||||
* Be CAREFUL if there is a manifest present, as THIS DOES NOT COPY IT OVER.
|
||||
*/
|
||||
public static ByteArrayOutputStream removeLicenseInfo(JarInputStream jarInputStream) throws IOException {
|
||||
public static
|
||||
ByteArrayOutputStream removeLicenseInfo(JarInputStream jarInputStream) throws IOException {
|
||||
// by default, this will not have access to the manifest! (CHECK BEFORE CALLING THIS, if you want to remove the manifest!)
|
||||
// we will ALSO lose entry comments!
|
||||
|
||||
|
@ -861,7 +840,8 @@ public class JarUtil {
|
|||
/**
|
||||
* Figures out what are going to be directories that should be created in the war.
|
||||
*/
|
||||
private static Set<String> figureOutDirectories(List<String> fullPaths, List<String> relativePaths) {
|
||||
private static
|
||||
Set<String> figureOutDirectories(List<String> fullPaths, List<String> relativePaths) {
|
||||
Set<String> directories = new HashSet<String>();
|
||||
|
||||
for (int i = 0, n = fullPaths.size(); i < n; i++) {
|
||||
|
@ -908,7 +888,8 @@ public class JarUtil {
|
|||
/**
|
||||
* Similar to 'jar', however this is for war files instead.
|
||||
*/
|
||||
public static void war(String warFilePath, List<String> fullPaths, List<String> relativePaths) throws FileNotFoundException, IOException {
|
||||
public static
|
||||
void war(String warFilePath, List<String> fullPaths, List<String> relativePaths) throws FileNotFoundException, IOException {
|
||||
// CLEANUP DIRECTORIES
|
||||
Set<String> directories = figureOutDirectories(fullPaths, relativePaths);
|
||||
|
||||
|
@ -956,7 +937,8 @@ public class JarUtil {
|
|||
}
|
||||
}
|
||||
|
||||
public static void removeArchiveCommentFromJar(String jarName) throws IOException {
|
||||
public static
|
||||
void removeArchiveCommentFromJar(String jarName) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(byteArrayOutputStream));
|
||||
jarOutputStream.setLevel(JAR_COMPRESSION_LEVEL);
|
||||
|
@ -973,7 +955,8 @@ public class JarUtil {
|
|||
String name = metaEntry.getName();
|
||||
if (name.startsWith(metaInfName) && !metaEntry.isDirectory()) {
|
||||
JarUtil.writeZipEntry(metaEntry, jarFile, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// since this is already a valid jar, the META-INF data is
|
||||
// already first.
|
||||
break;
|
||||
|
@ -1014,7 +997,8 @@ public class JarUtil {
|
|||
/**
|
||||
* Also sets the time to the build time for all META-INF files!
|
||||
*/
|
||||
public static long addTimeStampToJar(String jarName) throws IOException {
|
||||
public static
|
||||
long addTimeStampToJar(String jarName) throws IOException {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(byteArrayOutputStream));
|
||||
jarOutputStream.setLevel(JAR_COMPRESSION_LEVEL);
|
||||
|
@ -1026,7 +1010,7 @@ public class JarUtil {
|
|||
// MANIFEST MUST BE FIRST
|
||||
Manifest manifest = jarFile.getManifest();
|
||||
JarEntry jarEntry = new JarEntry(JarFile.MANIFEST_NAME);
|
||||
jarEntry.setTime(Build.buildDate);
|
||||
jarEntry.setTime(Builder.buildDate);
|
||||
jarOutputStream.putNextEntry(jarEntry);
|
||||
manifest.write(jarOutputStream);
|
||||
jarOutputStream.closeEntry();
|
||||
|
@ -1042,9 +1026,10 @@ public class JarUtil {
|
|||
}
|
||||
|
||||
if (name.startsWith(metaInfName) && !metaEntry.isDirectory()) {
|
||||
metaEntry.setTime(Build.buildDate);
|
||||
metaEntry.setTime(Builder.buildDate);
|
||||
JarUtil.writeZipEntry(metaEntry, jarFile, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// since this is already a valid jar, the META-INF data is
|
||||
// already first.
|
||||
break;
|
||||
|
@ -1054,7 +1039,7 @@ public class JarUtil {
|
|||
// now add our TIMESTAMP.
|
||||
// It will ALWAYS calculate the timestamp from the BUILD SYSTEM, not the
|
||||
// LOCAL/REMOTE SYSTEM (which can exist with incorrect/different clocks)
|
||||
long timeStamp = Build.buildDate;
|
||||
long timeStamp = Builder.buildDate;
|
||||
jarEntry = new JarEntry(metaInfName + "___" + Long.toString(timeStamp));
|
||||
jarOutputStream.putNextEntry(jarEntry);
|
||||
jarOutputStream.closeEntry();
|
||||
|
@ -1092,13 +1077,15 @@ public class JarUtil {
|
|||
|
||||
/**
|
||||
* Adds args (launcher or VM args) to the ini file.
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void addArgsToIniInJar(String jarName, String... args) throws IOException {
|
||||
Build.log().println("Modifying config.ini file in jar...");
|
||||
public static
|
||||
void addArgsToIniInJar(String jarName, String... args) throws IOException {
|
||||
Builder.log().println("Modifying config.ini file in jar...");
|
||||
|
||||
for (String arg : args) {
|
||||
Build.log().println("\t" + arg);
|
||||
Builder.log().println("\t" + arg);
|
||||
}
|
||||
|
||||
// we have to use a JarFile, so we preserve the comments that might already be in the file.
|
||||
|
@ -1121,7 +1108,8 @@ public class JarUtil {
|
|||
|
||||
if (!name.equals(configFile)) {
|
||||
JarUtil.writeZipEntry(entry, origJarFile, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
foundConfigFile = true;
|
||||
addArgsToIniContents(entry, origJarFile.getInputStream(entry), jarOutputStream, args);
|
||||
}
|
||||
|
@ -1145,7 +1133,8 @@ public class JarUtil {
|
|||
}
|
||||
|
||||
|
||||
public static void addArgsToIniFile(String iniFile, String... args) throws IOException {
|
||||
public static
|
||||
void addArgsToIniFile(String iniFile, String... args) throws IOException {
|
||||
InputStream inFile = new BufferedInputStream(new FileInputStream(iniFile));
|
||||
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
|
||||
|
||||
|
@ -1159,14 +1148,16 @@ public class JarUtil {
|
|||
/**
|
||||
* Fixes up the ini file inside the jar.
|
||||
*/
|
||||
private static void addArgsToIniContents(InputStream inputStream, OutputStream outputStream, String... args) throws IOException {
|
||||
private static
|
||||
void addArgsToIniContents(InputStream inputStream, OutputStream outputStream, String... args) throws IOException {
|
||||
addArgsToIniContents(null, inputStream, outputStream, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fixes up the ini file inside the jar.
|
||||
*/
|
||||
private static void addArgsToIniContents(JarEntry entry, InputStream inputStream, OutputStream outputStream,
|
||||
String... args) throws IOException {
|
||||
private static
|
||||
void addArgsToIniContents(JarEntry entry, InputStream inputStream, OutputStream outputStream, String... args) throws IOException {
|
||||
|
||||
ByteArrayOutputStream outputStreamCopy = new ByteArrayOutputStream();
|
||||
if (inputStream != null) {
|
||||
|
@ -1187,12 +1178,11 @@ public class JarUtil {
|
|||
* returns null only for the END of the stream.
|
||||
* returns an empty String if two newlines appear in a row.
|
||||
*/
|
||||
while (( line = input.readLine()) != null) {
|
||||
while ((line = input.readLine()) != null) {
|
||||
iniFileArgs.add(line);
|
||||
}
|
||||
}
|
||||
catch (IOException e) { }
|
||||
finally {
|
||||
} catch (IOException e) {
|
||||
} finally {
|
||||
Sys.close(input);
|
||||
}
|
||||
|
||||
|
@ -1232,7 +1222,8 @@ public class JarUtil {
|
|||
Sys.copyStream(inputStreamCopy, outputStream);
|
||||
jarOutputStream.closeEntry();
|
||||
Sys.close(inputStreamCopy);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Sys.copyStream(inputStreamCopy, outputStream);
|
||||
outputStream.flush();
|
||||
Sys.close(outputStream);
|
||||
|
@ -1243,11 +1234,11 @@ public class JarUtil {
|
|||
/**
|
||||
* Adds the specified files AS REGULAR FILES to the jar.
|
||||
*
|
||||
* @param filesToAdd
|
||||
* a PAIR of strings. First in pair is SOURCE, second in pair is
|
||||
* DEST
|
||||
* @param filesToAdd a PAIR of strings. First in pair is SOURCE, second in pair is
|
||||
* DEST
|
||||
*/
|
||||
public static void addFilesToJar(String jarName, BuildOptions options, ExtraDataInterface extraDataWriter, Pack... filesToAdd) throws IOException {
|
||||
public static
|
||||
void addFilesToJar(String jarName, BuildOptions options, ExtraDataInterface extraDataWriter, Pack... filesToAdd) throws IOException {
|
||||
addFilesToJar(jarName, options, null, extraDataWriter, filesToAdd);
|
||||
}
|
||||
|
||||
|
@ -1255,22 +1246,23 @@ public class JarUtil {
|
|||
/**
|
||||
* Adds the specified files AS REGULAR FILES to the jar. Will ALSO let us REPLACE files in the jar
|
||||
*
|
||||
* @param filesToAdd
|
||||
* a PAIR of strings. First in pair is SOURCE, second in pair is DEST
|
||||
* @param filesToAdd a PAIR of strings. First in pair is SOURCE, second in pair is DEST
|
||||
*/
|
||||
public static void addFilesToJar(String jarName, BuildOptions properties, EncryptInterface encryption, ExtraDataInterface extraDataWriter,
|
||||
Pack... filesToAdd) throws IOException {
|
||||
public static
|
||||
void addFilesToJar(String jarName, BuildOptions properties, EncryptInterface encryption, ExtraDataInterface extraDataWriter,
|
||||
Pack... filesToAdd) throws IOException {
|
||||
PackAction[] actionsToRemove;
|
||||
if (properties.compiler.enableDebugSpeedImprovement) {
|
||||
actionsToRemove = new PackAction[] {PackAction.Pack, PackAction.Lzma, PackAction.Encrypt};
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
actionsToRemove = new PackAction[] {PackAction.Encrypt};
|
||||
}
|
||||
|
||||
boolean addDebug = properties.compiler.debugEnabled;
|
||||
boolean release = properties.compiler.release;
|
||||
|
||||
Build.log().println("Adding files to jar: '" + jarName + "'");
|
||||
Builder.log().println("Adding files to jar: '" + jarName + "'");
|
||||
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
JarOutputStream jarOutputStream = new JarOutputStream(new BufferedOutputStream(byteArrayOutputStream));
|
||||
|
@ -1291,7 +1283,7 @@ public class JarUtil {
|
|||
for (Pack pack : filesToAdd) {
|
||||
String destPath = pack.getDestPath();
|
||||
if (name.equals(destPath)) {
|
||||
Build.log().println(" Replacing '" + destPath + "'");
|
||||
Builder.log().println(" Replacing '" + destPath + "'");
|
||||
canAdd = false;
|
||||
break;
|
||||
}
|
||||
|
@ -1310,7 +1302,7 @@ public class JarUtil {
|
|||
String sourcePath = FileUtil.normalizeAsFile(pack.getSourcePath());
|
||||
String destPath = pack.getDestPath();
|
||||
|
||||
Build.log().println(" '" + sourcePath + "' -> '" + destPath + "'");
|
||||
Builder.log().println(" '" + sourcePath + "' -> '" + destPath + "'");
|
||||
|
||||
InputStream inputStream;
|
||||
int length = 0;
|
||||
|
@ -1322,7 +1314,8 @@ public class JarUtil {
|
|||
entry.setTime(time);
|
||||
inputStream = new FileInputStream(fileToAdd);
|
||||
length = (int) fileToAdd.length(); // yea, yea, yea, the length truncates...
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
inputStream = new ByteArrayInputStream(new byte[0]);
|
||||
}
|
||||
|
||||
|
@ -1344,7 +1337,8 @@ public class JarUtil {
|
|||
}
|
||||
|
||||
unpackEntry(task, extraDataWriter, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
packEntry(task);
|
||||
|
||||
if (extraDataWriter != null) {
|
||||
|
@ -1370,28 +1364,29 @@ public class JarUtil {
|
|||
|
||||
/**
|
||||
* Repackages the JAR, compressing/etc based on specific rules.
|
||||
*
|
||||
* <p/>
|
||||
* Also makes sure to have our custom header (in 'extra data') written for each entry
|
||||
*
|
||||
* <p/>
|
||||
* This is how we get the JAR file size down.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static void packageJar(String jarName, BuildOptions properties,
|
||||
EncryptInterface encryption, ExtraDataInterface extraDataWriter,
|
||||
List<String> fileExtensionToHandle,
|
||||
Repack... specialActions) throws IOException {
|
||||
public static
|
||||
void packageJar(String jarName, BuildOptions properties, EncryptInterface encryption, ExtraDataInterface extraDataWriter,
|
||||
List<String> fileExtensionToHandle, Repack... specialActions) throws IOException {
|
||||
|
||||
PackAction[] actionsToRemove;
|
||||
if (properties.compiler.enableDebugSpeedImprovement) {
|
||||
actionsToRemove = new PackAction[] {PackAction.Pack, PackAction.Lzma, PackAction.Encrypt};
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
actionsToRemove = new PackAction[] {PackAction.Encrypt};
|
||||
}
|
||||
|
||||
BuildLog log = Build.log();
|
||||
BuildLog log = Builder.log();
|
||||
boolean release = properties.compiler.release;
|
||||
|
||||
String tempJarName = jarName+".tmp";
|
||||
String tempJarName = jarName + ".tmp";
|
||||
JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(tempJarName, false));
|
||||
jarOutputStream.setLevel(JAR_COMPRESSION_LEVEL);
|
||||
|
||||
|
@ -1409,7 +1404,8 @@ public class JarUtil {
|
|||
extraDataWriter.write(entry, null);
|
||||
}
|
||||
JarUtil.writeZipEntry(entry, jarFile, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// only handle if we match one of our extensions!
|
||||
boolean handle = false;
|
||||
for (String fileExtension : fileExtensionToHandle) {
|
||||
|
@ -1425,7 +1421,8 @@ public class JarUtil {
|
|||
extraDataWriter.write(entry, null);
|
||||
}
|
||||
JarUtil.writeZipEntry(entry, jarFile, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Repack repack = null;
|
||||
|
||||
for (Repack specialRepack : specialActions) {
|
||||
|
@ -1465,7 +1462,8 @@ public class JarUtil {
|
|||
if (repack.canDo(PackAction.Extract)) {
|
||||
// this also writes out (and overrides) our custom extra data header
|
||||
unpackEntry(task, extraDataWriter, jarOutputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
packEntry(task);
|
||||
|
||||
// now write (single entry) to the outputStream
|
||||
|
@ -1493,10 +1491,11 @@ public class JarUtil {
|
|||
|
||||
log.println(".");
|
||||
|
||||
Build.moveFile(tempJarName, jarName);
|
||||
Builder.moveFile(tempJarName, jarName);
|
||||
}
|
||||
|
||||
private static void unpackEntry(PackTask task, ExtraDataInterface extraDataWriter, JarOutputStream jarOutputStream) {
|
||||
private static
|
||||
void unpackEntry(PackTask task, ExtraDataInterface extraDataWriter, JarOutputStream jarOutputStream) {
|
||||
InputStream inputStream = task.inputStream;
|
||||
Repack repack = task.pack;
|
||||
|
||||
|
@ -1534,7 +1533,8 @@ public class JarUtil {
|
|||
} catch (Exception e) {
|
||||
System.err.println("Unable to extract contents of tar file!");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
if (extension.equals("gz") || extension.equals("gzip")) {
|
||||
TarInputStream newInputStream = null;
|
||||
GZIPInputStream gzipInputStream = null;
|
||||
|
@ -1565,7 +1565,8 @@ public class JarUtil {
|
|||
jarOutputStream.flush();
|
||||
jarOutputStream.closeEntry();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// ONLY ungzip (gzip only works on ONE file)
|
||||
|
||||
// this is a regular file (such as a txt file, etc)
|
||||
|
@ -1592,14 +1593,16 @@ public class JarUtil {
|
|||
}
|
||||
Sys.close(newInputStream);
|
||||
Sys.close(gzipInputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// input stream can be fileInputStream (if it was a file)
|
||||
// or a bytearrayinput stream if it was a stream from another file
|
||||
boolean isZip = false;
|
||||
if (inputStream instanceof FileInputStream) {
|
||||
File file = new File(name);
|
||||
isZip = isZipFile(file);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
ByteArrayInputStream s = (ByteArrayInputStream) inputStream;
|
||||
isZip = isZipStream(s);
|
||||
}
|
||||
|
@ -1623,14 +1626,16 @@ public class JarUtil {
|
|||
System.err.println("Unable to extract contents of compressed file!");
|
||||
}
|
||||
Sys.close(zipInputStream);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
System.err.println("Unable to extract contents of compressed file!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void packEntry(PackTask task) throws IOException {
|
||||
private static
|
||||
void packEntry(PackTask task) throws IOException {
|
||||
InputStream inputStream = task.inputStream;
|
||||
int length = task.length;
|
||||
Repack repack = task.pack;
|
||||
|
@ -1687,7 +1692,8 @@ public class JarUtil {
|
|||
// convert the output stream to an input stream
|
||||
inputStream = new ByteArrayInputStream(encryptedOutputStream.toByteArray());
|
||||
length = inputStream.available();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
throw new RuntimeException("** Unable to encrypt data when AES information is null!!");
|
||||
}
|
||||
}
|
||||
|
@ -1699,14 +1705,15 @@ public class JarUtil {
|
|||
* Merge the specified files into the primaryFile
|
||||
*
|
||||
* @param primaryFile This is the file that will contain all of the other files.
|
||||
* @param files Array of files (zips/jars) to be added into the primary file
|
||||
* @param files Array of files (zips/jars) to be added into the primary file
|
||||
* @throws IOException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public static void merge(File primaryFile, File... files) throws FileNotFoundException, IOException {
|
||||
public static
|
||||
void merge(File primaryFile, File... files) throws FileNotFoundException, IOException {
|
||||
String[] fileNames = new String[files.length];
|
||||
|
||||
for (int i=0; i<files.length; i++) {
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
fileNames[i] = files[i].getAbsolutePath();
|
||||
}
|
||||
|
||||
|
@ -1717,12 +1724,13 @@ public class JarUtil {
|
|||
* Merge the specified files into the primaryFile
|
||||
*
|
||||
* @param primaryFile This is the file that will contain all of the other files.
|
||||
* @param files Array of files (zips/jars) to be added into the primary file
|
||||
* @param files Array of files (zips/jars) to be added into the primary file
|
||||
* @throws IOException
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public static void merge(File primaryFile, String... files) throws FileNotFoundException, IOException {
|
||||
Build.log().println("Merging files into single jar/zip: '" + primaryFile + "'");
|
||||
public static
|
||||
void merge(File primaryFile, String... files) throws FileNotFoundException, IOException {
|
||||
Builder.log().println("Merging files into single jar/zip: '" + primaryFile + "'");
|
||||
|
||||
// write everything to staging dir, then jar it up.
|
||||
String tempDirectory = FileUtil.tempDirectory("mergeTemp");
|
||||
|
@ -1735,7 +1743,8 @@ public class JarUtil {
|
|||
// is this a zip?
|
||||
if (FileUtil.isZipFile(file)) {
|
||||
FileUtil.unzipJar(file, mergeLocation, false);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// just copy it over
|
||||
String relativeToDir = FileUtil.getChildRelativeToDir(file, "src");
|
||||
FileUtil.copyFile(file, new File(mergeLocation, relativeToDir));
|
||||
|
|
|
@ -17,10 +17,10 @@
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL TINKERPOP BE LIABLE FOR ANY
|
||||
DISCLAIMED. IN NO EVENT SHALL <ORGANIZATION> BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
|
|
@ -0,0 +1,502 @@
|
|||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 2.1, February 1999
|
||||
|
||||
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
[This is the first released version of the Lesser GPL. It also counts
|
||||
as the successor of the GNU Library Public License, version 2, hence
|
||||
the version number 2.1.]
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
Licenses are intended to guarantee your freedom to share and change
|
||||
free software--to make sure the software is free for all its users.
|
||||
|
||||
This license, the Lesser General Public License, applies to some
|
||||
specially designated software packages--typically libraries--of the
|
||||
Free Software Foundation and other authors who decide to use it. You
|
||||
can use it too, but we suggest you first think carefully about whether
|
||||
this license or the ordinary General Public License is the better
|
||||
strategy to use in any particular case, based on the explanations below.
|
||||
|
||||
When we speak of free software, we are referring to freedom of use,
|
||||
not price. Our General Public Licenses are designed to make sure that
|
||||
you have the freedom to distribute copies of free software (and charge
|
||||
for this service if you wish); that you receive source code or can get
|
||||
it if you want it; that you can change the software and use pieces of
|
||||
it in new free programs; and that you are informed that you can do
|
||||
these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
distributors to deny you these rights or to ask you to surrender these
|
||||
rights. These restrictions translate to certain responsibilities for
|
||||
you if you distribute copies of the library or if you modify it.
|
||||
|
||||
For example, if you distribute copies of the library, whether gratis
|
||||
or for a fee, you must give the recipients all the rights that we gave
|
||||
you. You must make sure that they, too, receive or can get the source
|
||||
code. If you link other code with the library, you must provide
|
||||
complete object files to the recipients, so that they can relink them
|
||||
with the library after making changes to the library and recompiling
|
||||
it. And you must show them these terms so they know their rights.
|
||||
|
||||
We protect your rights with a two-step method: (1) we copyright the
|
||||
library, and (2) we offer you this license, which gives you legal
|
||||
permission to copy, distribute and/or modify the library.
|
||||
|
||||
To protect each distributor, we want to make it very clear that
|
||||
there is no warranty for the free library. Also, if the library is
|
||||
modified by someone else and passed on, the recipients should know
|
||||
that what they have is not the original version, so that the original
|
||||
author's reputation will not be affected by problems that might be
|
||||
introduced by others.
|
||||
|
||||
Finally, software patents pose a constant threat to the existence of
|
||||
any free program. We wish to make sure that a company cannot
|
||||
effectively restrict the users of a free program by obtaining a
|
||||
restrictive license from a patent holder. Therefore, we insist that
|
||||
any patent license obtained for a version of the library must be
|
||||
consistent with the full freedom of use specified in this license.
|
||||
|
||||
Most GNU software, including some libraries, is covered by the
|
||||
ordinary GNU General Public License. This license, the GNU Lesser
|
||||
General Public License, applies to certain designated libraries, and
|
||||
is quite different from the ordinary General Public License. We use
|
||||
this license for certain libraries in order to permit linking those
|
||||
libraries into non-free programs.
|
||||
|
||||
When a program is linked with a library, whether statically or using
|
||||
a shared library, the combination of the two is legally speaking a
|
||||
combined work, a derivative of the original library. The ordinary
|
||||
General Public License therefore permits such linking only if the
|
||||
entire combination fits its criteria of freedom. The Lesser General
|
||||
Public License permits more lax criteria for linking other code with
|
||||
the library.
|
||||
|
||||
We call this license the "Lesser" General Public License because it
|
||||
does Less to protect the user's freedom than the ordinary General
|
||||
Public License. It also provides other free software developers Less
|
||||
of an advantage over competing non-free programs. These disadvantages
|
||||
are the reason we use the ordinary General Public License for many
|
||||
libraries. However, the Lesser license provides advantages in certain
|
||||
special circumstances.
|
||||
|
||||
For example, on rare occasions, there may be a special need to
|
||||
encourage the widest possible use of a certain library, so that it becomes
|
||||
a de-facto standard. To achieve this, non-free programs must be
|
||||
allowed to use the library. A more frequent case is that a free
|
||||
library does the same job as widely used non-free libraries. In this
|
||||
case, there is little to gain by limiting the free library to free
|
||||
software only, so we use the Lesser General Public License.
|
||||
|
||||
In other cases, permission to use a particular library in non-free
|
||||
programs enables a greater number of people to use a large body of
|
||||
free software. For example, permission to use the GNU C Library in
|
||||
non-free programs enables many more people to use the whole GNU
|
||||
operating system, as well as its variant, the GNU/Linux operating
|
||||
system.
|
||||
|
||||
Although the Lesser General Public License is Less protective of the
|
||||
users' freedom, it does ensure that the user of a program that is
|
||||
linked with the Library has the freedom and the wherewithal to run
|
||||
that program using a modified version of the Library.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow. Pay close attention to the difference between a
|
||||
"work based on the library" and a "work that uses the library". The
|
||||
former contains code derived from the library, whereas the latter must
|
||||
be combined with the library in order to run.
|
||||
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
other authorized party saying it may be distributed under the terms of
|
||||
this Lesser General Public License (also called "this License").
|
||||
Each licensee is addressed as "you".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
such a program is covered only if its contents constitute a work based
|
||||
on the Library (independent of the use of the Library in a tool for
|
||||
writing it). Whether that is true depends on what the Library does
|
||||
and what the program that uses the Library does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Library's
|
||||
complete source code as you receive it, in any medium, provided that
|
||||
you conspicuously and appropriately publish on each copy an
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
distribute the object code for the work under the terms of Section 6.
|
||||
Any executables containing that work also fall under Section 6,
|
||||
whether or not they are linked directly with the Library itself.
|
||||
|
||||
6. As an exception to the Sections above, you may also combine or
|
||||
link a "work that uses the Library" with the Library to produce a
|
||||
work containing portions of the Library, and distribute that work
|
||||
under terms of your choice, provided that the terms permit
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
Library will not necessarily be able to recompile the application
|
||||
to use the modified definitions.)
|
||||
|
||||
b) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (1) uses at run time a
|
||||
copy of the library already present on the user's computer system,
|
||||
rather than copying library functions into the executable, and (2)
|
||||
will operate properly with a modified version of the library, if
|
||||
the user installs one, as long as the modified version is
|
||||
interface-compatible with the version that the work was made with.
|
||||
|
||||
c) Accompany the work with a written offer, valid for at
|
||||
least three years, to give the same user the materials
|
||||
specified in Subsection 6a, above, for a charge no more
|
||||
than the cost of performing this distribution.
|
||||
|
||||
d) If distribution of the work is made by offering access to copy
|
||||
from a designated place, offer equivalent access to copy the above
|
||||
specified materials from the same place.
|
||||
|
||||
e) Verify that the user has already received a copy of these
|
||||
materials or that you have already sent this user a copy.
|
||||
|
||||
For an executable, the required form of the "work that uses the
|
||||
Library" must include any data and utility programs needed for
|
||||
reproducing the executable from it. However, as a special exception,
|
||||
the materials to be distributed need not include anything that is
|
||||
normally distributed (in either source or binary form) with the major
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
Library), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute, link with or modify the Library
|
||||
subject to these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties with
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
excluded. In such case, this License incorporates the limitation as if
|
||||
written in the body of this License.
|
||||
|
||||
13. The Free Software Foundation may publish revised and/or new
|
||||
versions of the Lesser General Public License from time to time.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
decision will be guided by the two goals of preserving the free status
|
||||
of all derivatives of our free software and of promoting the sharing
|
||||
and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
|
||||
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Libraries
|
||||
|
||||
If you develop a new library, and you want it to be of the greatest
|
||||
possible use to the public, we recommend making it free software that
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.1 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -0,0 +1,373 @@
|
|||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 6. Disclaimer of Warranty *
|
||||
* ------------------------- *
|
||||
* *
|
||||
* Covered Software is provided under this License on an "as is" *
|
||||
* basis, without warranty of any kind, either expressed, implied, or *
|
||||
* statutory, including, without limitation, warranties that the *
|
||||
* Covered Software is free of defects, merchantable, fit for a *
|
||||
* particular purpose or non-infringing. The entire risk as to the *
|
||||
* quality and performance of the Covered Software is with You. *
|
||||
* Should any Covered Software prove defective in any respect, You *
|
||||
* (not any Contributor) assume the cost of any necessary servicing, *
|
||||
* repair, or correction. This disclaimer of warranty constitutes an *
|
||||
* essential part of this License. No use of any Covered Software is *
|
||||
* authorized under this License except under this disclaimer. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
************************************************************************
|
||||
* *
|
||||
* 7. Limitation of Liability *
|
||||
* -------------------------- *
|
||||
* *
|
||||
* Under no circumstances and under no legal theory, whether tort *
|
||||
* (including negligence), contract, or otherwise, shall any *
|
||||
* Contributor, or anyone who distributes Covered Software as *
|
||||
* permitted above, be liable to You for any direct, indirect, *
|
||||
* special, incidental, or consequential damages of any character *
|
||||
* including, without limitation, damages for lost profits, loss of *
|
||||
* goodwill, work stoppage, computer failure or malfunction, or any *
|
||||
* and all other commercial damages or losses, even if such party *
|
||||
* shall have been informed of the possibility of such damages. This *
|
||||
* limitation of liability shall not apply to liability for death or *
|
||||
* personal injury resulting from such party's negligence to the *
|
||||
* extent applicable law prohibits such limitation. Some *
|
||||
* jurisdictions do not allow the exclusion or limitation of *
|
||||
* incidental or consequential damages, so this exclusion and *
|
||||
* limitation may not apply to You. *
|
||||
* *
|
||||
************************************************************************
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
|
@ -1,121 +1 @@
|
|||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
There is no license, as the author has released it into the public domain.
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
*/
|
||||
package dorkbox.license;
|
||||
|
||||
import dorkbox.Builder;
|
||||
import dorkbox.Build;
|
||||
import dorkbox.Oak;
|
||||
import dorkbox.build.Project;
|
||||
|
||||
import java.io.*;
|
||||
|
@ -161,7 +161,7 @@ class License implements Comparable<License> {
|
|||
|
||||
File targetLicenseFile = new File(targetLocation, "LICENSE." + entry.license.getExtension());
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(targetLicenseFile);
|
||||
Build.copyStream(new ByteArrayInputStream(bytes), fileOutputStream);
|
||||
Builder.copyStream(new ByteArrayInputStream(bytes), fileOutputStream);
|
||||
fileOutputStream.close();
|
||||
}
|
||||
}
|
||||
|
@ -211,7 +211,7 @@ class License implements Comparable<License> {
|
|||
InputStream input = new ByteArrayInputStream(licenseFile.getBytes(UTF_8));
|
||||
OutputStream output = new FileOutputStream(new File(targetLocation, "LICENSE"));
|
||||
|
||||
Build.copyStream(input, output);
|
||||
Builder.copyStream(input, output);
|
||||
output.close();
|
||||
|
||||
// copy over full text licenses
|
||||
|
@ -221,7 +221,7 @@ class License implements Comparable<License> {
|
|||
|
||||
File targetLicenseFile = new File(targetLocation, "LICENSE." + entry.license.getExtension());
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(targetLicenseFile);
|
||||
Build.copyStream(new ByteArrayInputStream(bytes), fileOutputStream);
|
||||
Builder.copyStream(new ByteArrayInputStream(bytes), fileOutputStream);
|
||||
fileOutputStream.close();
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ class License implements Comparable<License> {
|
|||
zipOutputStream.putNextEntry(zipEntry);
|
||||
|
||||
ByteArrayInputStream input = new ByteArrayInputStream(licenseFile.getBytes(UTF_8));
|
||||
Build.copyStream(input, zipOutputStream);
|
||||
Builder.copyStream(input, zipOutputStream);
|
||||
zipOutputStream.closeEntry();
|
||||
|
||||
// iterator is different every time...
|
||||
|
@ -291,7 +291,7 @@ class License implements Comparable<License> {
|
|||
|
||||
// look on disk, or look in a jar for the licenses.
|
||||
// Either way, we want the BYTES of those files!
|
||||
String rootPath = Oak.get(License.class).getPath();
|
||||
String rootPath = Build.get(License.class).getPath();
|
||||
File rootFile = new File(rootPath);
|
||||
String fileName = License.class.getCanonicalName();
|
||||
|
||||
|
@ -333,13 +333,13 @@ class License implements Comparable<License> {
|
|||
|
||||
FileInputStream input = new FileInputStream(f);
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream((int) f.length());
|
||||
Build.copyStream(input, output);
|
||||
Builder.copyStream(input, output);
|
||||
input.close();
|
||||
|
||||
licenseList.add(new LicenseWrapper(lt, output.toByteArray()));
|
||||
}
|
||||
}
|
||||
else if (rootPath.endsWith(Project.JAR_EXTENSION) && Build.isZipFile(rootFile)) {
|
||||
else if (rootPath.endsWith(Project.JAR_EXTENSION) && Builder.isZipFile(rootFile)) {
|
||||
// have to go digging for it!
|
||||
String nameAsFile = fileName.replace('.', '/').substring(0, fileName.lastIndexOf('.') + 1);
|
||||
|
||||
|
@ -357,7 +357,7 @@ class License implements Comparable<License> {
|
|||
if (licenseType != null) {
|
||||
// read out bytes!
|
||||
ByteArrayOutputStream output = new ByteArrayOutputStream(4096);
|
||||
Build.copyStream(zipInputStream, output);
|
||||
Builder.copyStream(zipInputStream, output);
|
||||
|
||||
licenseList.add(new LicenseWrapper(licenseType, output.toByteArray()));
|
||||
zipInputStream.closeEntry();
|
||||
|
|
|
@ -21,9 +21,11 @@ public enum LicenseType {
|
|||
CC0("CC0", "CC0 License"),
|
||||
EPL("EPLv1", "Eclipse Public License"),
|
||||
GPLv2_CP("GPLv2_CP", "GPL v2 License, with Classpath exception"),
|
||||
LGPLv2("LGPLv2.1", "LGPL v2.1 License"),
|
||||
LGPLv3("LGPLv3", "LGPL v3 License"),
|
||||
MIT("MIT", "MIT License"), // same as MIT X11
|
||||
MPL("MPLv1.1", "Mozilla Public License"),
|
||||
MPL("MPLv1.1", "Mozilla Public License 1.1"),
|
||||
MPL2("MPLv2.0", "Mozilla Public License 2.0"),
|
||||
OFL("OFLv1.1", "SIL Open Font License"),
|
||||
PUBLIC("Public", "Public Domain"), // not quite the same as CC0 (CC0 is better)
|
||||
;
|
||||
|
|
Loading…
Reference in New Issue