Merge remote-tracking branch 'plaa/master' into latest-jogl
Conflicts: core/.classpath
This commit is contained in:
commit
00a17eb0e2
@ -33,5 +33,7 @@
|
||||
<classpathentry kind="lib" path="lib/aopalliance.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jogl/gluegen-rt.jar"/>
|
||||
<classpathentry kind="lib" path="lib/jogl/jogl-all.jar"/>
|
||||
<classpathentry kind="lib" path="lib-test/test-plugin.jar"/>
|
||||
<classpathentry kind="lib" path="lib/annotation-detector-3.0.2-SNAPSHOT.jar"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
@ -101,6 +101,7 @@
|
||||
<zipfileset src="${lib.dir}/miglayout15-swing.jar"/>
|
||||
<zipfileset src="${lib.dir}/opencsv-2.3.jar"/>
|
||||
<zipfileset src="${lib.dir}/OrangeExtensions-1.2.jar"/>
|
||||
<zipfileset src="${lib.dir}/annotation-detector-3.0.2-SNAPSHOT.jar"/>
|
||||
|
||||
|
||||
<!-- JOGL libraries need to be jar-in-jar -->
|
||||
|
BIN
core/lib-test/test-plugin.jar
Normal file
BIN
core/lib-test/test-plugin.jar
Normal file
Binary file not shown.
BIN
core/lib/annotation-detector-3.0.2-SNAPSHOT.jar
Normal file
BIN
core/lib/annotation-detector-3.0.2-SNAPSHOT.jar
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
16
core/src/net/sf/openrocket/plugin/AnnotationFinder.java
Normal file
16
core/src/net/sf/openrocket/plugin/AnnotationFinder.java
Normal file
@ -0,0 +1,16 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Interface for finding annotated classes from the class path.
|
||||
*/
|
||||
public interface AnnotationFinder {
|
||||
|
||||
/**
|
||||
* Return a list of all types (classes and interfaces) that are annotated
|
||||
* with the provided annotation.
|
||||
*/
|
||||
public List<Class<?>> findAnnotatedTypes(Class<?> annotation);
|
||||
|
||||
}
|
92
core/src/net/sf/openrocket/plugin/AnnotationFinderImpl.java
Normal file
92
core/src/net/sf/openrocket/plugin/AnnotationFinderImpl.java
Normal file
@ -0,0 +1,92 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.openrocket.util.BugException;
|
||||
import net.sf.openrocket.util.JarUtil;
|
||||
import eu.infomas.annotation.AnnotationDetector;
|
||||
import eu.infomas.annotation.AnnotationDetector.TypeReporter;
|
||||
|
||||
/**
|
||||
* An AnnotationFinder that uses annotation-detector library to scan
|
||||
* the class path. Compatible with the JIJ loader.
|
||||
*/
|
||||
public class AnnotationFinderImpl implements AnnotationFinder {
|
||||
|
||||
@SuppressWarnings("resource")
|
||||
@Override
|
||||
public List<Class<?>> findAnnotatedTypes(Class<?> annotation) {
|
||||
final List<Class<?>> classes = new ArrayList<Class<?>>();
|
||||
|
||||
TypeReporter reporter = new ListReporter(classes);
|
||||
final AnnotationDetector cf = new AnnotationDetector(reporter);
|
||||
try {
|
||||
ClassLoader loader = this.getClass().getClassLoader();
|
||||
if (loader instanceof URLClassLoader) {
|
||||
|
||||
/*
|
||||
* In case of URLClassLoader (which may be our own instantiation)
|
||||
* use the URLs from there, as java.class.path may not be up-to-date.
|
||||
*/
|
||||
|
||||
URLClassLoader urlClassLoader = (URLClassLoader) loader;
|
||||
URL[] urls = urlClassLoader.getURLs();
|
||||
|
||||
List<File> files = new ArrayList<File>();
|
||||
for (URL url : urls) {
|
||||
if (url.getProtocol() == "file") {
|
||||
files.add(JarUtil.urlToFile(url));
|
||||
}
|
||||
}
|
||||
|
||||
cf.detect(files.toArray(new File[0]));
|
||||
} else {
|
||||
|
||||
/*
|
||||
* If not using a URLClassLoader, just do the default.
|
||||
*/
|
||||
cf.detect();
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
throw new BugException("Unable to search class path", e);
|
||||
}
|
||||
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
private static class ListReporter implements TypeReporter {
|
||||
private final List<Class<?>> classes;
|
||||
private final Set<String> names = new HashSet<String>();
|
||||
|
||||
public ListReporter(List<Class<?>> classes) {
|
||||
this.classes = classes;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public Class<? extends Annotation>[] annotations() {
|
||||
return new Class[] { Plugin.class };
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reportTypeAnnotation(Class<? extends Annotation> annotation, String className) {
|
||||
if (names.add(className)) {
|
||||
try {
|
||||
classes.add(this.getClass().getClassLoader().loadClass(className));
|
||||
} catch (ClassNotFoundException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class JIJ {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
String cp = System.getProperty("java.class.path");
|
||||
String[] cps = cp.split(File.pathSeparator);
|
||||
|
||||
URL[] urls = new URL[cps.length + 1];
|
||||
for (int i = 0; i < cps.length; i++) {
|
||||
urls[i] = new File(cps[i]).toURI().toURL();
|
||||
}
|
||||
urls[cps.length] = new File("/home/sampo/Projects/OpenRocket/core/example.jar").toURI().toURL();
|
||||
|
||||
System.out.println("Classpath: " + Arrays.toString(urls));
|
||||
|
||||
URLClassLoader loader = new URLClassLoader(urls, null);
|
||||
Class<?> c = loader.loadClass("net.sf.openrocket.plugin.Test");
|
||||
Method m = c.getMethod("main", args.getClass());
|
||||
m.invoke(null, (Object) args);
|
||||
}
|
||||
|
||||
}
|
@ -6,8 +6,10 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* Annotation that defines an interface to be a plugin interface.
|
||||
* Plugin interfaces are automatically discovered from plugin JARs and
|
||||
* Annotation that defines an interface to be a plugin interface and
|
||||
* classes as plugin implementations.
|
||||
* <p>
|
||||
* Plugin interfaces are automatically discovered from the classpath and
|
||||
* registered as plugins in Guice.
|
||||
*
|
||||
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
|
||||
|
@ -1,14 +1,9 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
import com.google.inject.AbstractModule;
|
||||
import com.google.inject.multibindings.Multibinder;
|
||||
@ -21,63 +16,46 @@ import com.google.inject.multibindings.Multibinder;
|
||||
*/
|
||||
public class PluginModule extends AbstractModule {
|
||||
|
||||
private final List<File> jars;
|
||||
private final ClassLoader classLoader;
|
||||
|
||||
private Map<Class<?>, Multibinder<?>> binders = new HashMap<Class<?>, Multibinder<?>>();
|
||||
|
||||
|
||||
/**
|
||||
* Sole constructor.
|
||||
*
|
||||
* @param jars the JAR files to search for plugins
|
||||
* @param classLoader the class loader used to load classes from the JAR files
|
||||
*/
|
||||
public PluginModule(List<File> jars, ClassLoader classLoader) {
|
||||
this.jars = jars;
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void configure() {
|
||||
for (File jar : jars) {
|
||||
List<String> classNames = readClassNames(jar);
|
||||
for (String className : classNames) {
|
||||
checkForPlugin(className);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationFinder finder = new AnnotationFinderImpl();
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void checkForPlugin(String className) {
|
||||
try {
|
||||
@Override
|
||||
protected void configure() {
|
||||
|
||||
List<Class<?>> classes = finder.findAnnotatedTypes(Plugin.class);
|
||||
List<Class<?>> interfaces = new ArrayList<Class<?>>();
|
||||
List<Class<?>> unusedInterfaces;
|
||||
|
||||
|
||||
// Find plugin interfaces
|
||||
for (Class<?> c : classes) {
|
||||
if (c.isInterface()) {
|
||||
interfaces.add(c);
|
||||
}
|
||||
}
|
||||
unusedInterfaces = new ArrayList<Class<?>>(interfaces);
|
||||
|
||||
// Find plugin implementations
|
||||
for (Class<?> c : classes) {
|
||||
if (c.isInterface())
|
||||
continue;
|
||||
|
||||
Class<?> c = classLoader.loadClass(className);
|
||||
for (Class<?> intf : c.getInterfaces()) {
|
||||
System.out.println("Testing class " + c + " interface " + intf);
|
||||
|
||||
if (isPluginInterface(intf)) {
|
||||
System.out.println("BINDING");
|
||||
if (interfaces.contains(intf)) {
|
||||
// Ugly hack to enable dynamic binding... Can this be done type-safely?
|
||||
Multibinder<Object> binder = (Multibinder<Object>) findBinder(intf);
|
||||
binder.addBinding().to(c);
|
||||
unusedInterfaces.remove(intf);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("Could not load class " + className + ": " + e);
|
||||
}
|
||||
|
||||
// TODO: Unused plugin interfaces should be bound to an empty set - how?
|
||||
}
|
||||
|
||||
|
||||
private boolean isPluginInterface(Class<?> intf) {
|
||||
return intf.isAnnotationPresent(Plugin.class);
|
||||
}
|
||||
|
||||
|
||||
private Multibinder<?> findBinder(Class<?> intf) {
|
||||
Multibinder<?> binder = binders.get(intf);
|
||||
if (binder == null) {
|
||||
@ -87,36 +65,4 @@ public class PluginModule extends AbstractModule {
|
||||
return binder;
|
||||
}
|
||||
|
||||
|
||||
private List<String> readClassNames(File jar) {
|
||||
List<String> classNames = new ArrayList<String>();
|
||||
|
||||
JarFile file = null;
|
||||
try {
|
||||
file = new JarFile(jar);
|
||||
Enumeration<JarEntry> entries = file.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarEntry entry = entries.nextElement();
|
||||
String name = entry.getName();
|
||||
if (name.toLowerCase().endsWith(".class") && !name.contains("$")) {
|
||||
name = name.substring(0, name.length() - 6);
|
||||
name = name.replace('/', '.');
|
||||
classNames.add(name);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading JAR file " + jar);
|
||||
} finally {
|
||||
if (file != null) {
|
||||
try {
|
||||
file.close();
|
||||
} catch (IOException e) {
|
||||
// Curse all checked exceptions...
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return classNames;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
public class Test {
|
||||
|
||||
@Inject
|
||||
private Set<ExamplePlugin> impls;
|
||||
|
||||
|
||||
public void run() {
|
||||
System.out.println("Plugin count: " + impls.size());
|
||||
for (ExamplePlugin i : impls) {
|
||||
i.doit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws MalformedURLException {
|
||||
// Properties p = System.getProperties();
|
||||
// Enumeration<Object> e = p.keys();
|
||||
// while (e.hasMoreElements()) {
|
||||
// Object key = e.nextElement();
|
||||
// Object value = p.get(key);
|
||||
// System.out.println(key + " = " + value);
|
||||
// }
|
||||
|
||||
List<File> jars = Arrays.asList(new File("/home/sampo/Projects/OpenRocket/core/example.jar"));
|
||||
URL[] urls = { new File("/home/sampo/Projects/OpenRocket/core/example.jar").toURI().toURL() };
|
||||
ClassLoader classLoader = new URLClassLoader(urls);
|
||||
|
||||
classLoader = Test.class.getClassLoader();
|
||||
|
||||
Injector injector = Guice.createInjector(new PluginModule(jars, classLoader));
|
||||
injector.getInstance(Test.class).run();
|
||||
}
|
||||
}
|
@ -16,7 +16,6 @@ import net.sf.openrocket.logging.LogHelper;
|
||||
import net.sf.openrocket.logging.LogLevel;
|
||||
import net.sf.openrocket.logging.LogLevelBufferLogger;
|
||||
import net.sf.openrocket.logging.PrintStreamLogger;
|
||||
import net.sf.openrocket.plugin.PluginHelper;
|
||||
import net.sf.openrocket.plugin.PluginModule;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
@ -135,26 +134,27 @@ public class GuiceStartup {
|
||||
" " + LOG_STDERR_PROPERTY + "=" + System.getProperty(LOG_STDERR_PROPERTY) + ")";
|
||||
log.info(str);
|
||||
|
||||
|
||||
|
||||
|
||||
//Replace System.err with a PrintStream that logs lines to DEBUG, or VBOSE if they are indented.
|
||||
//If debug info is not being output to the console then the data is both logged and written to
|
||||
//stderr.
|
||||
final boolean writeToStderr = !( printer.getOutput(LogLevel.DEBUG) == System.out || printer.getOutput(LogLevel.DEBUG) == System.err);
|
||||
final PrintStream stdErr = System.err;
|
||||
final boolean writeToStderr = !(printer.getOutput(LogLevel.DEBUG) == System.out || printer.getOutput(LogLevel.DEBUG) == System.err);
|
||||
final PrintStream stdErr = System.err;
|
||||
System.setErr(new PrintStream(new OutputStream() {
|
||||
StringBuilder currentLine = new StringBuilder();
|
||||
|
||||
@Override
|
||||
public synchronized void write(int b) throws IOException {
|
||||
if ( writeToStderr ){
|
||||
if (writeToStderr) {
|
||||
//Write to real stderr
|
||||
stdErr.write(b);
|
||||
}
|
||||
if (b == '\r' || b == '\n') {
|
||||
//Line is complete, log it
|
||||
if (currentLine.toString().trim().length() > 0){
|
||||
if (currentLine.toString().trim().length() > 0) {
|
||||
String s = currentLine.toString();
|
||||
if ( Character.isWhitespace(s.charAt(0))){
|
||||
if (Character.isWhitespace(s.charAt(0))) {
|
||||
log.verbose(currentLine.toString());
|
||||
} else {
|
||||
log.debug(currentLine.toString());
|
||||
@ -247,7 +247,7 @@ public class GuiceStartup {
|
||||
|
||||
private static Injector initializeGuice() {
|
||||
Module applicationModule = new ApplicationModule();
|
||||
Module pluginModule = new PluginModule(PluginHelper.getPluginJars(), GuiceStartup.class.getClassLoader());
|
||||
Module pluginModule = new PluginModule();
|
||||
|
||||
return Guice.createInjector(applicationModule, pluginModule);
|
||||
}
|
||||
|
@ -1,6 +1,12 @@
|
||||
package net.sf.openrocket.unit;
|
||||
|
||||
import static net.sf.openrocket.util.Chars.*;
|
||||
import static net.sf.openrocket.util.Chars.CUBED;
|
||||
import static net.sf.openrocket.util.Chars.DEGREE;
|
||||
import static net.sf.openrocket.util.Chars.DOT;
|
||||
import static net.sf.openrocket.util.Chars.MICRO;
|
||||
import static net.sf.openrocket.util.Chars.PERMILLE;
|
||||
import static net.sf.openrocket.util.Chars.SQUARED;
|
||||
import static net.sf.openrocket.util.Chars.ZWSP;
|
||||
import static net.sf.openrocket.util.MathUtil.pow2;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -86,6 +92,7 @@ public class UnitGroup {
|
||||
static {
|
||||
UNITS_NONE = new UnitGroup();
|
||||
UNITS_NONE.addUnit(Unit.NOUNIT);
|
||||
UNITS_NONE.setDefaultUnit(0);
|
||||
|
||||
UNITS_ENERGY = new UnitGroup();
|
||||
UNITS_ENERGY.addUnit(new GeneralUnit(1, "J"));
|
||||
@ -127,9 +134,9 @@ public class UnitGroup {
|
||||
UNITS_LENGTH.setDefaultUnit(1);
|
||||
|
||||
UNITS_MOTOR_DIMENSIONS = new UnitGroup();
|
||||
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(1, "m")); // just added
|
||||
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.001, "mm"));
|
||||
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.01, "cm"));
|
||||
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(1, "m"));
|
||||
UNITS_MOTOR_DIMENSIONS.addUnit(new GeneralUnit(0.0254, "in"));
|
||||
UNITS_MOTOR_DIMENSIONS.setDefaultUnit(0);
|
||||
|
||||
@ -140,6 +147,7 @@ public class UnitGroup {
|
||||
UNITS_DISTANCE.addUnit(new GeneralUnit(0.9144, "yd"));
|
||||
UNITS_DISTANCE.addUnit(new GeneralUnit(1609.344, "mi"));
|
||||
UNITS_DISTANCE.addUnit(new GeneralUnit(1852, "nmi"));
|
||||
UNITS_DISTANCE.setDefaultUnit(0);
|
||||
|
||||
UNITS_ALL_LENGTHS = new UnitGroup();
|
||||
UNITS_ALL_LENGTHS.addUnit(new GeneralUnit(0.001, "mm"));
|
||||
@ -164,15 +172,16 @@ public class UnitGroup {
|
||||
|
||||
|
||||
UNITS_STABILITY = new UnitGroup();
|
||||
UNITS_STABILITY.addUnit(new GeneralUnit(1, "m"));
|
||||
UNITS_STABILITY.addUnit(new GeneralUnit(0.001, "mm"));
|
||||
UNITS_STABILITY.addUnit(new GeneralUnit(0.01, "cm"));
|
||||
UNITS_STABILITY.addUnit(new GeneralUnit(1, "m"));
|
||||
UNITS_STABILITY.addUnit(new GeneralUnit(0.0254, "in"));
|
||||
UNITS_STABILITY.addUnit(new CaliberUnit((Rocket) null));
|
||||
UNITS_STABILITY.setDefaultUnit(3);
|
||||
UNITS_STABILITY.setDefaultUnit(4);
|
||||
|
||||
UNITS_STABILITY_CALIBERS = new UnitGroup();
|
||||
UNITS_STABILITY_CALIBERS.addUnit(new GeneralUnit(1, "cal"));
|
||||
UNITS_STABILITY_CALIBERS.setDefaultUnit(0);
|
||||
|
||||
|
||||
UNITS_VELOCITY = new UnitGroup();
|
||||
@ -180,23 +189,27 @@ public class UnitGroup {
|
||||
UNITS_VELOCITY.addUnit(new GeneralUnit(1 / 3.6, "km/h"));
|
||||
UNITS_VELOCITY.addUnit(new GeneralUnit(0.3048, "ft/s"));
|
||||
UNITS_VELOCITY.addUnit(new GeneralUnit(0.44704, "mph"));
|
||||
UNITS_VELOCITY.setDefaultUnit(0);
|
||||
|
||||
UNITS_WINDSPEED = new UnitGroup();
|
||||
UNITS_WINDSPEED.addUnit(new GeneralUnit(1, "m/s"));
|
||||
UNITS_WINDSPEED.addUnit(new GeneralUnit(1 / 3.6, "km/h"));
|
||||
UNITS_WINDSPEED.addUnit(new GeneralUnit(0.3048, "ft/s"));
|
||||
UNITS_WINDSPEED.addUnit(new GeneralUnit(0.44704, "mph"));
|
||||
UNITS_WINDSPEED.setDefaultUnit(0);
|
||||
|
||||
UNITS_ACCELERATION = new UnitGroup();
|
||||
UNITS_ACCELERATION.addUnit(new GeneralUnit(1, "m/s" + SQUARED));
|
||||
UNITS_ACCELERATION.addUnit(new GeneralUnit(0.3048, "ft/s" + SQUARED));
|
||||
UNITS_ACCELERATION.addUnit(new GeneralUnit(9.80665, "G"));
|
||||
UNITS_ACCELERATION.setDefaultUnit(0);
|
||||
|
||||
UNITS_MASS = new UnitGroup();
|
||||
UNITS_MASS.addUnit(new GeneralUnit(0.001, "g"));
|
||||
UNITS_MASS.addUnit(new GeneralUnit(1, "kg"));
|
||||
UNITS_MASS.addUnit(new GeneralUnit(0.0283495231, "oz"));
|
||||
UNITS_MASS.addUnit(new GeneralUnit(0.45359237, "lb"));
|
||||
UNITS_MASS.setDefaultUnit(0);
|
||||
|
||||
UNITS_INERTIA = new UnitGroup();
|
||||
UNITS_INERTIA.addUnit(new GeneralUnit(0.0001, "kg" + DOT + "cm" + SQUARED));
|
||||
@ -211,6 +224,7 @@ public class UnitGroup {
|
||||
UNITS_ANGLE.addUnit(new DegreeUnit());
|
||||
UNITS_ANGLE.addUnit(new FixedPrecisionUnit("rad", 0.01));
|
||||
UNITS_ANGLE.addUnit(new GeneralUnit(1.0 / 3437.74677078, "arcmin"));
|
||||
UNITS_ANGLE.setDefaultUnit(0);
|
||||
|
||||
UNITS_DENSITY_BULK = new UnitGroup();
|
||||
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1000, "g/cm" + CUBED));
|
||||
@ -218,6 +232,7 @@ public class UnitGroup {
|
||||
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1, "kg/m" + CUBED));
|
||||
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(1729.99404, "oz/in" + CUBED));
|
||||
UNITS_DENSITY_BULK.addUnit(new GeneralUnit(16.0184634, "lb/ft" + CUBED));
|
||||
UNITS_DENSITY_BULK.setDefaultUnit(0);
|
||||
|
||||
UNITS_DENSITY_SURFACE = new UnitGroup();
|
||||
UNITS_DENSITY_SURFACE.addUnit(new GeneralUnit(10, "g/cm" + SQUARED));
|
||||
@ -232,15 +247,18 @@ public class UnitGroup {
|
||||
UNITS_DENSITY_LINE.addUnit(new GeneralUnit(0.001, "g/m"));
|
||||
UNITS_DENSITY_LINE.addUnit(new GeneralUnit(1, "kg/m"));
|
||||
UNITS_DENSITY_LINE.addUnit(new GeneralUnit(0.0930102465, "oz/ft"));
|
||||
UNITS_DENSITY_LINE.setDefaultUnit(0);
|
||||
|
||||
UNITS_FORCE = new UnitGroup();
|
||||
UNITS_FORCE.addUnit(new GeneralUnit(1, "N"));
|
||||
UNITS_FORCE.addUnit(new GeneralUnit(4.44822162, "lbf"));
|
||||
UNITS_FORCE.addUnit(new GeneralUnit(9.80665, "kgf"));
|
||||
UNITS_FORCE.setDefaultUnit(0);
|
||||
|
||||
UNITS_IMPULSE = new UnitGroup();
|
||||
UNITS_IMPULSE.addUnit(new GeneralUnit(1, "Ns"));
|
||||
UNITS_IMPULSE.addUnit(new GeneralUnit(4.44822162, "lbf" + DOT + "s"));
|
||||
UNITS_IMPULSE.setDefaultUnit(0);
|
||||
|
||||
UNITS_TIME_STEP = new UnitGroup();
|
||||
UNITS_TIME_STEP.addUnit(new FixedPrecisionUnit("ms", 1, 0.001));
|
||||
@ -249,10 +267,12 @@ public class UnitGroup {
|
||||
|
||||
UNITS_SHORT_TIME = new UnitGroup();
|
||||
UNITS_SHORT_TIME.addUnit(new GeneralUnit(1, "s"));
|
||||
UNITS_SHORT_TIME.setDefaultUnit(0);
|
||||
|
||||
UNITS_FLIGHT_TIME = new UnitGroup();
|
||||
UNITS_FLIGHT_TIME.addUnit(new GeneralUnit(1, "s"));
|
||||
UNITS_FLIGHT_TIME.addUnit(new GeneralUnit(60, "min"));
|
||||
UNITS_FLIGHT_TIME.setDefaultUnit(0);
|
||||
|
||||
UNITS_ROLL = new UnitGroup();
|
||||
UNITS_ROLL.addUnit(new GeneralUnit(1, "rad/s"));
|
||||
@ -274,32 +294,29 @@ public class UnitGroup {
|
||||
UNITS_PRESSURE.addUnit(new GeneralUnit(3386.389, "inHg"));
|
||||
UNITS_PRESSURE.addUnit(new GeneralUnit(6894.75729, "psi"));
|
||||
UNITS_PRESSURE.addUnit(new GeneralUnit(1, "Pa"));
|
||||
UNITS_PRESSURE.setDefaultUnit(0);
|
||||
|
||||
UNITS_RELATIVE = new UnitGroup();
|
||||
UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01, 1.0));
|
||||
UNITS_RELATIVE.addUnit(new GeneralUnit(0.01, "%"));
|
||||
UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + PERMILLE, 1, 0.001));
|
||||
// UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01, 1.0));
|
||||
// UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("%", 1, 0.01));
|
||||
// UNITS_RELATIVE.addUnit(new FixedPrecisionUnit("" + PERMILLE, 1, 0.001));
|
||||
UNITS_RELATIVE.setDefaultUnit(1);
|
||||
|
||||
|
||||
UNITS_ROUGHNESS = new UnitGroup();
|
||||
UNITS_ROUGHNESS.addUnit(new GeneralUnit(1, "m")); // just added
|
||||
UNITS_ROUGHNESS.addUnit(new GeneralUnit(0.000001, MICRO + "m"));
|
||||
UNITS_ROUGHNESS.addUnit(new GeneralUnit(0.0000254, "mil"));
|
||||
UNITS_ROUGHNESS.addUnit(new GeneralUnit(1, "m"));
|
||||
UNITS_ROUGHNESS.setDefaultUnit(0);
|
||||
|
||||
|
||||
UNITS_COEFFICIENT = new UnitGroup();
|
||||
UNITS_COEFFICIENT.addUnit(new FixedPrecisionUnit("" + ZWSP, 0.01)); // zero-width space
|
||||
UNITS_COEFFICIENT.setDefaultUnit(0);
|
||||
|
||||
|
||||
// This is not used by OpenRocket, and not extensively tested:
|
||||
UNITS_FREQUENCY = new UnitGroup();
|
||||
// UNITS_FREQUENCY.addUnit(new GeneralUnit(1, "s"));
|
||||
// UNITS_FREQUENCY.addUnit(new GeneralUnit(0.001, "ms"));
|
||||
// UNITS_FREQUENCY.addUnit(new GeneralUnit(0.000001, MICRO + "s"));
|
||||
UNITS_FREQUENCY.addUnit(new FrequencyUnit(.001, "mHz"));
|
||||
UNITS_FREQUENCY.addUnit(new FrequencyUnit(1, "Hz"));
|
||||
UNITS_FREQUENCY.addUnit(new FrequencyUnit(1000, "kHz"));
|
||||
|
@ -1,6 +1,10 @@
|
||||
package net.sf.openrocket.database;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@ -14,31 +18,31 @@ import net.sf.openrocket.util.Coordinate;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ThrustCurveMotorSetTest {
|
||||
|
||||
|
||||
|
||||
|
||||
private static final ThrustCurveMotor motor1 = new ThrustCurveMotor(
|
||||
Manufacturer.getManufacturer("A"),
|
||||
"F12X", "Desc", Motor.Type.UNKNOWN, new double[] { },
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
|
||||
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestA");
|
||||
"F12X", "Desc", Motor.Type.UNKNOWN, new double[] {},
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 },
|
||||
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestA");
|
||||
|
||||
private static final ThrustCurveMotor motor2 = new ThrustCurveMotor(
|
||||
Manufacturer.getManufacturer("A"),
|
||||
"F12H", "Desc", Motor.Type.SINGLE, new double[] { 5 },
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 1, 0},
|
||||
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestB");
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 1, 0 },
|
||||
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestB");
|
||||
|
||||
private static final ThrustCurveMotor motor3 = new ThrustCurveMotor(
|
||||
Manufacturer.getManufacturer("A"),
|
||||
"F12", "Desc", Motor.Type.UNKNOWN, new double[] { 0, Motor.PLUGGED },
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 2, 0},
|
||||
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestC");
|
||||
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 },
|
||||
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestC");
|
||||
|
||||
private static final ThrustCurveMotor motor4 = new ThrustCurveMotor(
|
||||
Manufacturer.getManufacturer("A"),
|
||||
"F12", "Desc", Motor.Type.HYBRID, new double[] { 0 },
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] {0, 2, 0},
|
||||
new Coordinate[] {Coordinate.NUL, Coordinate.NUL, Coordinate.NUL}, "digestD");
|
||||
0.024, 0.07, new double[] { 0, 1, 2 }, new double[] { 0, 2, 0 },
|
||||
new Coordinate[] { Coordinate.NUL, Coordinate.NUL, Coordinate.NUL }, "digestD");
|
||||
|
||||
|
||||
@Test
|
||||
@ -50,7 +54,7 @@ public class ThrustCurveMotorSetTest {
|
||||
assertEquals("J115", ThrustCurveMotorSet.simplifyDesignation("384-J115"));
|
||||
assertEquals("A2", ThrustCurveMotorSet.simplifyDesignation("A2T"));
|
||||
assertEquals("1/2A2T", ThrustCurveMotorSet.simplifyDesignation("1/2A2T"));
|
||||
assertEquals("Micro Maxx II", ThrustCurveMotorSet.simplifyDesignation("Micro Maxx II"));
|
||||
assertEquals("MicroMaxxII", ThrustCurveMotorSet.simplifyDesignation("Micro Maxx II"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
9
core/test/net/sf/openrocket/plugin/Example2Plugin.java
Normal file
9
core/test/net/sf/openrocket/plugin/Example2Plugin.java
Normal file
@ -0,0 +1,9 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
/**
|
||||
* Example plugin interface for testing purposes.
|
||||
*/
|
||||
@Plugin
|
||||
public interface Example2Plugin {
|
||||
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
/**
|
||||
* Example plugin for testing purposes.
|
||||
*/
|
||||
@Plugin
|
||||
public interface ExamplePlugin {
|
||||
|
||||
public void doit();
|
||||
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
/**
|
||||
* ExamplePlugin implementation for testing purposes.
|
||||
*/
|
||||
@Plugin
|
||||
public class ExamplePluginImpl implements ExamplePlugin {
|
||||
|
||||
@Override
|
||||
public void doit() {
|
||||
System.out.println("ExamplePluginImpl.doit() called");
|
||||
}
|
||||
|
||||
}
|
10
core/test/net/sf/openrocket/plugin/MultiPluginImpl.java
Normal file
10
core/test/net/sf/openrocket/plugin/MultiPluginImpl.java
Normal file
@ -0,0 +1,10 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
/**
|
||||
* Plugin that implements both ExamplePlugin and Example2Plugin
|
||||
* for testing purposes.
|
||||
*/
|
||||
@Plugin
|
||||
public class MultiPluginImpl implements ExamplePlugin, Example2Plugin {
|
||||
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
/**
|
||||
* An implementation of ExamplePlugin that is not annotated with @Plugin
|
||||
* for testing purposes. This should not be injected into the test class.
|
||||
*/
|
||||
public class NotAnExamplePluginImpl implements ExamplePlugin {
|
||||
|
||||
}
|
26
core/test/net/sf/openrocket/plugin/PluginTest.java
Normal file
26
core/test/net/sf/openrocket/plugin/PluginTest.java
Normal file
@ -0,0 +1,26 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.inject.Guice;
|
||||
import com.google.inject.Injector;
|
||||
|
||||
/**
|
||||
* Test the plugin loading system using Guice.
|
||||
*
|
||||
* This is more of an integration than a unit test. It uses the
|
||||
* PluginModule to load a Guice injector, and then verifies that it
|
||||
* has found the appropriate plugins.
|
||||
*/
|
||||
public class PluginTest {
|
||||
|
||||
@Test
|
||||
public void testPluginModule() {
|
||||
|
||||
Injector injector = Guice.createInjector(new PluginModule());
|
||||
PluginTester tester = injector.getInstance(PluginTester.class);
|
||||
tester.testPlugins();
|
||||
|
||||
}
|
||||
|
||||
}
|
38
core/test/net/sf/openrocket/plugin/PluginTester.java
Normal file
38
core/test/net/sf/openrocket/plugin/PluginTester.java
Normal file
@ -0,0 +1,38 @@
|
||||
package net.sf.openrocket.plugin;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.openrocket.util.ArrayList;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class PluginTester {
|
||||
|
||||
@Inject
|
||||
private Set<ExamplePlugin> examplePlugins;
|
||||
@Inject
|
||||
private Set<Example2Plugin> example2Plugins;
|
||||
|
||||
|
||||
public void testPlugins() {
|
||||
assertContains(examplePlugins, ExamplePluginImpl.class, MultiPluginImpl.class, JarPluginImpl.class);
|
||||
assertContains(example2Plugins, MultiPluginImpl.class);
|
||||
}
|
||||
|
||||
|
||||
private void assertContains(Set<?> set, Class<?>... classes) {
|
||||
assertEquals(classes.length, set.size());
|
||||
|
||||
List<Class<?>> list = new ArrayList<Class<?>>(Arrays.asList(classes));
|
||||
for (Object o : set) {
|
||||
Class<?> c = o.getClass();
|
||||
assertTrue(list.contains(c));
|
||||
list.remove(c);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,10 @@
|
||||
package net.sf.openrocket.util;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@ -53,7 +57,7 @@ public class TestMutex {
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private volatile int testState = 0;
|
||||
private volatile String failure = null;
|
||||
|
||||
@ -106,6 +110,7 @@ public class TestMutex {
|
||||
testState = 6;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
failure = "Exception occurred in thread: " + e;
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user