oms3.util.Components Maven / Gradle / Ivy
/*
* $Id:$
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
*/
package oms3.util;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import oms3.Access;
import oms3.ComponentAccess;
import oms3.annotations.Bound;
import oms3.annotations.Description;
import oms3.annotations.Documentation;
import oms3.annotations.Execute;
import oms3.annotations.In;
import oms3.annotations.Out;
import oms3.annotations.Role;
/**
* Basic component utility methods.
*
* @author Olaf David
*/
public class Components {
private Components() {
}
public static List parameter(Class> comp) {
List f = new ArrayList();
for (Field field : comp.getFields()) {
Role r = field.getAnnotation(Role.class);
if (r != null && Annotations.plays(r, Role.PARAMETER)) {
f.add(field);
}
}
return f;
}
public static List inVars(Class> comp) {
List f = new ArrayList();
for (Field field : comp.getFields()) {
In in = field.getAnnotation(In.class);
if (in != null) {
Role r = field.getAnnotation(Role.class);
if (r != null && Annotations.plays(r, Role.PARAMETER)) {
continue;
}
f.add(field);
}
}
return f;
}
public static List outVars(Class> comp) {
List f = new ArrayList();
for (Field field : comp.getFields()) {
Out out = field.getAnnotation(Out.class);
if (out != null) {
f.add(field);
}
}
return f;
}
static boolean isComponentClass(Class> c) {
Method[] m = c.getMethods();
for (Method method : m) {
if (method.getAnnotation(Execute.class) != null) {
return true;
}
}
return false;
}
public static Collection> internalComponents(Class> model) {
Collection> comps = new ArrayList>();
comps.add(model);
internalComponents0(comps, model);
return comps;
}
public static void internalComponents0(Collection> comps, Class> model) {
for (Field f : model.getDeclaredFields()) {
f.setAccessible(true);
Class> fc = f.getType();
if (!fc.isPrimitive() && !fc.getName().startsWith("java.") && isComponentClass(fc)) {
if (!comps.contains(fc)) {
comps.add(fc);
internalComponents0(comps, fc);
}
}
}
}
public static void explore(Object comp) {
explore(comp, System.out);
}
public static void explore(Object comp, PrintStream w) {
Field[] fi = comp.getClass().getDeclaredFields();
for (Field f : fi) {
Role r = f.getAnnotation(Role.class);
if (Annotations.plays(r, Role.PARAMETER)) {
w.println(" field2in(model, \"" + f.getName() + "\", comp, \"" + f.getName() + "\");");
} else if (Annotations.isInOut(f)) {
w.println(" field2inout(hru, \"" + f.getName() + "\", comp, \"" + f.getName() + "\");");
} else if (Annotations.isIn(f)) {
w.println(" field2in(hru, \"" + f.getName() + "\", comp, \"" + f.getName() + "\");");
} else if (Annotations.isOut(f)) {
w.println(" out2field(comp, \"" + f.getName() + "\", hru, \"" + f.getName() + "\");");
}
}
}
/**
* Figure out connectivity and generate Java statements.
* @param comps
*/
public static void figureOutConnect(PrintStream w, Object... comps) {
// add all the components via Proxy.
List l = new ArrayList();
for (Object c : comps) {
l.add(new ComponentAccess(c));
}
// find all out slots
for (ComponentAccess cp_out : l) {
w.println("// connect " + objName(cp_out));
// over all input slots.
for (Access fout : cp_out.outputs()) {
String s = " out2in(" + objName(cp_out) + ", \"" + fout.getField().getName() + "\"";
for (ComponentAccess cp_in : l) {
// skip if it is the same component.
if (cp_in == cp_out) {
continue;
}
// out points to in
for (Access fin : cp_in.inputs()) {
// name equivalence enought for now.
if (fout.getField().getName().equals(fin.getField().getName())) {
s = s + ", " + objName(cp_in);
}
}
}
w.println(s + ");");
}
w.println();
}
}
public static void figureOutParamDeclarations(PrintStream w, Object... comps) {
Map m = new HashMap();
for (Object c : comps) {
ComponentAccess cp = new ComponentAccess(c);
// System.out.println("// Parameter from " + objName(cp));
// over all input slots.
for (Access fin : cp.inputs()) {
Role role = fin.getField().getAnnotation(Role.class);
if (role != null && Annotations.plays(role, Role.PARAMETER)) {
// make sure parameter is only there once.
m.put(fin.getField().getName(), fin);
}
}
}
List sl = new ArrayList(m.keySet());
Collections.sort(sl, new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
for (String key : sl) {
Access fin = m.get(key);
Description d = fin.getField().getAnnotation(Description.class);
if (d != null) {
w.println(" @Description(\"" + d.value() + "\")");
}
Bound b = fin.getField().getAnnotation(Bound.class);
if (b != null) {
w.println(" @Bound(\"" + b.value() + "\")");
}
w.println(" @Role(\"" + fin.getField().getAnnotation(Role.class).value() + "\")");
w.println(" @In public " + fin.getField().getType().getSimpleName() + " " + fin.getField().getName() + ";");
w.println();
}
}
public static void declare(PrintStream w, Object... comps) {
w.println("// Declarartions");
for (Object c : comps) {
ComponentAccess cp = new ComponentAccess(c);
w.println(" " + c.getClass().getName() + " " + objName(cp) + " = new " + c.getClass().getName() + "();");
}
w.println();
}
public static void figureOutMapIn(PrintStream w, Object... comps) {
for (Object c : comps) {
ComponentAccess cp = new ComponentAccess(c);
w.println("// Input mapping to " + objName(cp));
for (Access fin : cp.inputs()) {
Role role = fin.getField().getAnnotation(Role.class);
if (role != null && Annotations.plays(role, Role.PARAMETER)) {
w.println(" in2in(\"" + fin.getField().getName() + "\", " + objName(cp) + ");");
}
}
w.println();
}
}
public static void figureOutMapIn0(PrintStream w, Object... comps) {
Map> maps = new HashMap>();
for (Object c : comps) {
ComponentAccess cp = new ComponentAccess(c);
for (Access fin : cp.inputs()) {
Role role = fin.getField().getAnnotation(Role.class);
if (role != null && Annotations.plays(role, Role.PARAMETER)) {
List l = maps.get(fin.getField().getName());
if (l == null) {
maps.put(fin.getField().getName(), l = new ArrayList());
}
l.add(objName(cp));
}
}
}
List sl = new ArrayList(maps.keySet());
Collections.sort(sl, new Comparator() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
for (String string : sl) {
w.print(" in2in(\"" + string + "\"");
List l = maps.get(string);
for (String string1 : l) {
w.print(", " + string1);
}
w.println(");");
}
}
static private String objName(ComponentAccess cp) {
return cp.getComponent().getClass().getSimpleName().toLowerCase();
}
public static List> getComponentClasses(File jar) throws IOException {
return getComponentClasses(jar.toURI().toURL());
}
/** Get all components from a jar file
*
* @param jar
* @return the list of components from the jar. (Implement 'Execute' annotation)
* @throws IOException
* @throws ClassNotFoundException
*/
public static List> getComponentClasses(URL jar) throws IOException {
JarInputStream jarFile = new JarInputStream(jar.openStream());
URLClassLoader cl = new URLClassLoader(new URL[]{jar}, Thread.currentThread().getContextClassLoader());
List> idx = new ArrayList>();
JarEntry jarEntry = jarFile.getNextJarEntry();
while (jarEntry != null) {
String classname = jarEntry.getName();
// System.out.println(classname);
if (classname.endsWith(".class")) {
classname = classname.substring(0, classname.indexOf(".class")).replace('/', '.');
try {
Class> c = Class.forName(classname, false, cl);
for (Method method : c.getMethods()) {
if ((method.getAnnotation(Execute.class)) != null) {
idx.add(c);
break;
}
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
jarEntry = jarFile.getNextJarEntry();
}
jarFile.close();
return idx;
}
/**
* Get all components from a set of jar files.
*
* @param parent a parent {@link ClassLoader} to use. If null
, the context
* classloader will be used.
* @param jars the {@link URL}s of the jar to browse for components.
* @return the list of component classes in the jars.
* @throws IOException
*/
public static List> getComponentClasses( ClassLoader parent, URL... jars ) throws IOException {
if (parent == null) {
parent = Thread.currentThread().getContextClassLoader();
}
URLClassLoader cl = new URLClassLoader(jars, parent);
List> idx = new ArrayList>();
for( URL jar : jars ) {
JarInputStream jarFile = new JarInputStream(jar.openStream());
JarEntry jarEntry = jarFile.getNextJarEntry();
while( jarEntry != null ) {
String classname = jarEntry.getName();
// System.out.println(classname);
if (classname.endsWith(".class")) {
classname = classname.substring(0, classname.indexOf(".class")).replace('/', '.');
try {
Class< ? > c = Class.forName(classname, false, cl);
for( Method method : c.getMethods() ) {
if ((method.getAnnotation(Execute.class)) != null) {
idx.add(c);
break;
}
}
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
}
jarEntry = jarFile.getNextJarEntry();
}
jarFile.close();
}
return idx;
}
/** Get the documentation with the default locale
*
* @param comp The component to get the documentation from.
* @return the documentation URL or null if not available
*/
public static URL getDocumentation(Class> comp) {
return getDocumentation(comp, Locale.getDefault());
}
/** Get the documentation as URL reference;
*
* @param comp The class to get the 'Documentation' tag from
* @param loc The locale
* @return the URL of the documentation file, null if no documentation is available.
*/
public static URL getDocumentation(Class> comp, Locale loc) {
Documentation doc = (Documentation) comp.getAnnotation(Documentation.class);
if (doc != null) {
String v = doc.value();
try {
// try full URL first (external reference)
URL url = new URL(v);
return url;
} catch (MalformedURLException E) {
// local resource bundled with the class
String name = v.substring(0, v.lastIndexOf('.'));
String ext = v.substring(v.lastIndexOf('.'));
String lang = loc.getLanguage();
URL f = comp.getResource(name + "_" + lang + ext);
if (f != null) {
return f;
}
f = comp.getResource(v);
if (f != null) {
return f;
}
}
}
return null;
}
public static String getDescription(Class> comp) {
return getDescription(comp, Locale.getDefault());
}
/** Get the Component Description
*
* @param comp the component class
* @param loc the locale
* @return the localized description
*/
public static String getDescription(Class> comp, Locale loc) {
Description descr = (Description) comp.getAnnotation(Description.class);
if (descr != null) {
String lang = loc.getLanguage();
Method[] m = descr.getClass().getMethods();
for (Method method : m) {
// System.out.println(method);
if (method.getName().equals(lang)) {
try {
String d = (String) method.invoke(descr, (Object[]) null);
if (d != null && !d.isEmpty()) {
return d;
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
return descr.value();
}
return null;
}
// public static void main(String[] args) throws Exception {
// double start = System.currentTimeMillis();
// System.out.println(getComponentClasses(new File("/od/projects/oms3.prj.prms2008/dist/oms3.prj.prms2008.jar")));
// double end = System.currentTimeMillis();
// System.out.println("time " + (end - start));
//
// List> comps = getComponentClasses(new File("/od/projects/oms3.prj.prms2008/dist/oms3.prj.prms2008.jar"));
//
// Class> basin = null;
// for (Class> c : comps) {
// if (c.getName().equals("prms2008.Basin")) {
// basin = c;
// break;
// }
// }
//
// System.out.println(getDocumentation(basin, Locale.getDefault()));
//
// System.out.println(getDescription(basin, Locale.getDefault()));
//
// }
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy