/*******************************************************************************
* Copyright (c) 2009, 2010 Innovation Gate GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Innovation Gate GmbH - initial API and implementation
******************************************************************************/
package de.innovationgate.eclipse.editors.tmlscript.parsing;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarInputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.Javadoc;
import org.eclipse.jdt.core.dom.MarkerAnnotation;
import org.eclipse.jdt.core.dom.MemberValuePair;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.Name;
import org.eclipse.jdt.core.dom.NormalAnnotation;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.TagElement;
import org.eclipse.jdt.core.dom.Type;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.TypeLiteral;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.launching.IVMInstall;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jdt.launching.LibraryLocation;
import org.osgi.framework.Bundle;
import de.innovationgate.eclipse.editors.Plugin;
import de.innovationgate.eclipse.editors.tmlscript.parsing.js.methods.JavaObject;
import de.innovationgate.utils.WGUtils;
import de.innovationgate.wga.common.CodeCompletion;
import de.innovationgate.wga.common.beans.csconfig.v1.Version;
import de.innovationgate.wga.model.VersionCompliance;
import de.innovationgate.wga.model.WGADesignConfigurationModel;
public class ReflectionManager {
private static Map<String, ReflectionManager> _instances = new HashMap<String, ReflectionManager>();
private VersionCompliance _versionCompliance = null;
private Map<String, Set<TMLScriptMethod>> _publicMethodsCache = new HashMap<String, Set<TMLScriptMethod>>();
private Map<String, Set<TMLScriptProperty>> _publicPropertiesCache = new HashMap<String, Set<TMLScriptProperty>>();
private Map<String, Set<TMLScriptMethod>> _publicConstructorsCache = new HashMap<String, Set<TMLScriptMethod>>();
private Map<String, String> _javaLangPackage = new HashMap<String, String>();
private Map<String, TMLScriptPackage> _packages = new HashMap<String, TMLScriptPackage>();
// constant indicating the global TMLScript scope . all global methods, properties, vars and the tmlcontext method should be visible then
public static final String GLOBAL_SCOPE_CLASSNAME = "$GLOBAL_SCOPE$";
public static final String CLASSNAME_SCRIPT_FUNCTION = "Function";
public static final String CLASSNAME_OBJECT_DEFINTION = "ObjectDefinition";
public static final String CLASSNAME_SCRIPT_OBJECT = "ScriptObject";
public static final String JS_ARRAY = "$JS.Object[]";
public static final String JS_STRING = "$JS.String";
public static final String JS_STRING_ARRAY = "$JS.String[]";
public static final String JS_NUMBER = "$JS.Number";
public static final String JS_INTEGER = "$JS.Integer";
public static final String JS_LONG = "$JS.Long";
public static final String JS_DOUBLE = "$JS.Double";
public static final String JS_FLOAT = "$JS.Float";
public static final String JS_BOOLEAN = "$JS.Boolean";
public static final String JS_REGEXP = "$JS.RegExp";
public static final String JS_FUNCTION = "$JS.Function";
public static int ENV_DEFAULT = 1;
public static int ENV_BLOCK = 2;
public static int ENV_MODULE = 4;
public static int ENV_ACTION = 8;
public static int ENV_EVENTSCRIPT = 16;
public static Set<TMLScriptMethod> JS_STRING_METHODS = new HashSet<TMLScriptMethod>();
static {
TMLScriptMethod method = new TMLScriptMethod("charAt", "char", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("index", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("charCodeAt", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("index", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("concat", "java.lang.String", JS_STRING);
TMLScriptMethodParameter varArgString = new TMLScriptMethodParameter("string", JS_STRING);
varArgString.setVararg(true);
method.getParameters().add(varArgString);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("indexOf", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("searchValue", JS_STRING));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("indexOf", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("searchValue", JS_STRING));
method.getParameters().add(new TMLScriptMethodParameter("fromIndex", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("lastIndexOf", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("searchValue", JS_STRING));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("lastIndexOf", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("searchValue", JS_STRING));
method.getParameters().add(new TMLScriptMethodParameter("fromIndex", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("localeCompare", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("compareString", JS_STRING));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("match", "java.lang.String[]", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("regexp", JS_REGEXP));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("replace", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("regexp", JS_REGEXP));
method.getParameters().add(new TMLScriptMethodParameter("newSubStr", "java.lang.String"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("replace", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("substr", "java.lang.String"));
method.getParameters().add(new TMLScriptMethodParameter("newSubStr", "java.lang.String"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("replace", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("regexp", JS_REGEXP));
method.getParameters().add(new TMLScriptMethodParameter("funct", JS_FUNCTION));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("replace", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("substr", "java.lang.String"));
method.getParameters().add(new TMLScriptMethodParameter("funct", JS_FUNCTION));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("search", "int", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("regexp", JS_REGEXP));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("slice", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("start", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("slice", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("start", "int"));
method.getParameters().add(new TMLScriptMethodParameter("end", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("split", "java.lang.String[]", JS_STRING);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("split", "java.lang.String[]", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("separator", "java.lang.String"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("split", "java.lang.String[]", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("separator", JS_REGEXP));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("split", "java.lang.String[]", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("separator", "java.lang.String"));
method.getParameters().add(new TMLScriptMethodParameter("limit", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("split", "java.lang.String[]", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("separator", JS_REGEXP));
method.getParameters().add(new TMLScriptMethodParameter("limit", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("substr", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("start", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("substr", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("start", "int"));
method.getParameters().add(new TMLScriptMethodParameter("length", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("substring", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("indexA", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("substring", "java.lang.String", JS_STRING);
method.getParameters().add(new TMLScriptMethodParameter("indexA", "int"));
method.getParameters().add(new TMLScriptMethodParameter("indexB", "int"));
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("toString", "java.lang.String", JS_STRING);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("toLocaleLowerCase", "java.lang.String", JS_STRING);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("toLocaleUpperCase", "java.lang.String", JS_STRING);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("toLowerCase", "java.lang.String", JS_STRING);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("toUpperCase", "java.lang.String", JS_STRING);
JS_STRING_METHODS.add(method);
method = new TMLScriptMethod("valueOf", "java.lang.String", JS_STRING);
JS_STRING_METHODS.add(method);
}
public static Set<TMLScriptProperty> JS_STRING_PROPERTIES = new HashSet<TMLScriptProperty>();
static {
JS_STRING_PROPERTIES.add(new TMLScriptProperty("length", "int", JS_STRING));
}
public static Set<TMLScriptMethod> JS_NUMBER_METHODS = new HashSet<TMLScriptMethod>();
static {
TMLScriptMethod method = new TMLScriptMethod("toExponetial", "java.lang.String", JS_NUMBER);
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toExponetial", "java.lang.String", JS_NUMBER);
method.getParameters().add(new TMLScriptMethodParameter("fragtionDigits", "int"));
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toFixed", "java.lang.String", JS_NUMBER);
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toFixed", "java.lang.String", JS_NUMBER);
method.getParameters().add(new TMLScriptMethodParameter("digits", "int"));
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toLocaleString", "java.lang.String", JS_NUMBER);
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toPrecision", "java.lang.String", JS_NUMBER);
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toPrecision", "java.lang.String", JS_NUMBER);
method.getParameters().add(new TMLScriptMethodParameter("precision", "int"));
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toString", "java.lang.String", JS_NUMBER);
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("toString", "java.lang.String", JS_NUMBER);
method.getParameters().add(new TMLScriptMethodParameter("radix", "int"));
JS_NUMBER_METHODS.add(method);
method = new TMLScriptMethod("valueOf", "java.lang.String", JS_NUMBER);
JS_NUMBER_METHODS.add(method);
}
public static ReflectionManager getInstance(VersionCompliance versionCompliance) {
ReflectionManager manager = _instances.get(versionCompliance.getKey());
if (manager == null) {
manager = new ReflectionManager(versionCompliance);
_instances.put(versionCompliance.getKey(), manager);
}
return manager;
}
private ReflectionManager(VersionCompliance versionCompliance) {
_versionCompliance = versionCompliance;
List<String> javaLangClasses = getClassNamesInPackage("java.lang", false);
for (String name : javaLangClasses) {
_javaLangPackage.put(name.substring(name.lastIndexOf(".") + 1), name);
}
retrievePackages();
}
// public Set<TMLScriptProperty> getPublicProperties(String classname) {
// return getPublicProperties(classname, ENV_DEFAULT);
// }
public Set<TMLScriptProperty> getPublicProperties(String classname, int env) {
if (classname == null || classname.equals("java.lang.Object")) {
return Collections.emptySet();
}
if (!classname.startsWith("$N$")) {
if (classname.contains("[")) {
return retrieveJSArrayProperties(classname.substring(0, classname.indexOf("[")));
} else {
classname = jsWrap(classname);
}
} else {
classname = classname.substring("$N$".length());
}
if (classname.equals(JS_STRING)) {
return JS_STRING_PROPERTIES;
}
Set<TMLScriptProperty> properties = _publicPropertiesCache.get(classname);
if (properties != null) {
if (classname.equals(GLOBAL_SCOPE_CLASSNAME)) {
Set<TMLScriptProperty> propertiesInclGlobals = new HashSet<TMLScriptProperty>();
propertiesInclGlobals.addAll(properties);
handleGlobalScopeProperties(propertiesInclGlobals, env);
return propertiesInclGlobals;
} else {
return properties;
}
}
properties = new HashSet<TMLScriptProperty>();
String effectiveClassname = classname;
if (effectiveClassname.equals(GLOBAL_SCOPE_CLASSNAME)) {
effectiveClassname = "de.innovationgate.wgpublisher.webtml.utils.TMLContext";
}
// first attempt - try to retrieve meta data from source
InputStream source = retrieveJavaSource(effectiveClassname);
if (source != null) {
//performPropertyParsingViaANTLR(classname, properties, source);
performPropertyParsingViaJDTAST(effectiveClassname, properties);
} else {
try {
ClassLoader loader = retrieveClassLoader();
Class<?> clazz = loader.loadClass(effectiveClassname);
for (Field field : clazz.getDeclaredFields()) {
if (Modifier.isPublic(field.getModifiers())) {
String type = buildFullQualifiedClassname(field.getType());
TMLScriptProperty tmlScriptProperty = new TMLScriptProperty(field.getName(), type, effectiveClassname);
tmlScriptProperty.setStatic(Modifier.isStatic(field.getModifiers()));
properties.add(tmlScriptProperty);
}
}
if (clazz.getSuperclass() != null) {
String superClass = clazz.getSuperclass().getName();
properties.addAll(getPublicProperties(superClass, env));
}
}
catch (ClassNotFoundException e) {
// ignore unknown classes
}
}
_publicPropertiesCache.put(classname, properties);
if (classname.equals(GLOBAL_SCOPE_CLASSNAME)) {
Set<TMLScriptProperty> propertiesInclGlobals = new HashSet<TMLScriptProperty>();
propertiesInclGlobals.addAll(properties);
handleGlobalScopeProperties(propertiesInclGlobals, env);
return propertiesInclGlobals;
} else {
return properties;
}
}
private void handleGlobalScopeProperties(Set<TMLScriptProperty> properties, int env) {
properties.add(TMLScriptProperty.PROPERTY_PACKAGES);
if (hasEnvironmentFlag(env, ENV_MODULE)) {
// this script might get executed as job
TMLScriptProperty jobContext = new TMLScriptProperty("jobContext", "de.innovationgate.wgpublisher.scheduler.JobContext", GLOBAL_SCOPE_CLASSNAME);
properties.add(jobContext);
}
if (hasEnvironmentFlag(env, ENV_ACTION)) {
for (int i=0; i < 5; i++) {
TMLScriptProperty param = new TMLScriptProperty("tmlparam" + (i+1), "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
properties.add(param);
}
}
if (hasEnvironmentFlag(env, ENV_EVENTSCRIPT)) {
TMLScriptProperty portletEvent = new TMLScriptProperty("portletEvent", "de.innovationgate.wgpublisher.webtml.utils.PortletEvent", GLOBAL_SCOPE_CLASSNAME);
properties.add(portletEvent);
TMLScriptProperty portletEvents = new TMLScriptProperty("portletEvents", "java.util.List", GLOBAL_SCOPE_CLASSNAME);
properties.add(portletEvents);
}
if (_versionCompliance.toWGAVersion().isAtLeast(5, 3)) {
properties.addAll(getPublicProperties("de.innovationgate.wgpublisher.expressions.tmlscript.RhinoScope", env));
}
}
private void handleGlobalScopeMethods(Set<TMLScriptMethod> methods, int env) {
if (_versionCompliance.toWGAVersion().isAtLeast(5, 3)) {
methods.addAll(getPublicMethods("de.innovationgate.wgpublisher.expressions.tmlscript.RhinoScope", env));
} else {
TMLScriptMethod callAction = new TMLScriptMethod("callAction", "void", GLOBAL_SCOPE_CLASSNAME);
callAction.getParameters().add(new TMLScriptMethodParameter("actionID", "java.lang.String"));
methods.add(callAction);
callAction = new TMLScriptMethod("callAction", "void", GLOBAL_SCOPE_CLASSNAME);
callAction.getParameters().add(new TMLScriptMethodParameter("actionID", "java.lang.String"));
TMLScriptMethodParameter callActionParams = new TMLScriptMethodParameter("param", "java.lang.Object");
callActionParams.setVararg(true);
callAction.getParameters().add(callActionParams);
methods.add(callAction);
callAction = new TMLScriptMethod("callAction", "void", GLOBAL_SCOPE_CLASSNAME);
callAction.getParameters().add(new TMLScriptMethodParameter("context", "de.innovationgate.wgpublisher.webtml.utils.TMLContext"));
callAction.getParameters().add(new TMLScriptMethodParameter("actionID", "java.lang.String"));
methods.add(callAction);
callAction = new TMLScriptMethod("callAction", "void", GLOBAL_SCOPE_CLASSNAME);
callAction.getParameters().add(new TMLScriptMethodParameter("context", "de.innovationgate.wgpublisher.webtml.utils.TMLContext"));
callAction.getParameters().add(new TMLScriptMethodParameter("actionID", "java.lang.String"));
callActionParams = new TMLScriptMethodParameter("param", "java.lang.Object");
callActionParams.setVararg(true);
callAction.getParameters().add(callActionParams);
methods.add(callAction);
TMLScriptMethod createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("modulename", "java.lang.String"));
methods.add(createObject);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
createObject.getParameters().add(new TMLScriptMethodParameter("modulename", "java.lang.String"));
methods.add(createObject);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("objectDef", CLASSNAME_OBJECT_DEFINTION));
methods.add(createObject);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
createObject.getParameters().add(new TMLScriptMethodParameter("objectDef", CLASSNAME_OBJECT_DEFINTION));
methods.add(createObject);
TMLScriptMethodParameter createObjectParams = new TMLScriptMethodParameter("param", "java.lang.Object");
createObjectParams.setVararg(true);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("modulename", "java.lang.String"));
createObject.getParameters().add(createObjectParams);
methods.add(createObject);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
createObject.getParameters().add(new TMLScriptMethodParameter("modulename", "java.lang.String"));
createObject.getParameters().add(createObjectParams);
methods.add(createObject);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("objectDef", CLASSNAME_OBJECT_DEFINTION));
createObject.getParameters().add(createObjectParams);
methods.add(createObject);
createObject = new TMLScriptMethod("createObject", CLASSNAME_SCRIPT_OBJECT, GLOBAL_SCOPE_CLASSNAME);
createObject.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
createObject.getParameters().add(new TMLScriptMethodParameter("objectDef", CLASSNAME_OBJECT_DEFINTION));
createObject.getParameters().add(createObjectParams);
methods.add(createObject);
TMLScriptMethod delDoublets = new TMLScriptMethod("deleteDoublets", "java.util.List", GLOBAL_SCOPE_CLASSNAME);
delDoublets.getParameters().add(new TMLScriptMethodParameter("list", "java.util.List"));
methods.add(delDoublets);
TMLScriptMethod deserialize = new TMLScriptMethod("deserializeObject", "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
deserialize.getParameters().add(new TMLScriptMethodParameter("string", "java.lang.String"));
methods.add(deserialize);
TMLScriptMethod format = new TMLScriptMethod("format", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
format.getParameters().add(new TMLScriptMethodParameter("object", "java.util.Date"));
format.getParameters().add(new TMLScriptMethodParameter("pattern", "java.lang.String"));
methods.add(format);
format = new TMLScriptMethod("format", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
format.getParameters().add(new TMLScriptMethodParameter("object", "java.lang.Number"));
format.getParameters().add(new TMLScriptMethodParameter("pattern", "java.lang.String"));
methods.add(format);
TMLScriptMethod lookupKeys = new TMLScriptMethod("getLookupKeys", "java.util.List", GLOBAL_SCOPE_CLASSNAME);
lookupKeys.getParameters().add(new TMLScriptMethodParameter("lookupTable", "java.util.Map"));
methods.add(lookupKeys);
methods.add(new JavaObject());
TMLScriptMethod loadHTML = new TMLScriptMethod("loadHTML", "org.dom4j.Document", GLOBAL_SCOPE_CLASSNAME);
loadHTML.getParameters().add(new TMLScriptMethodParameter("client", "org.apache.http.client.HttpClient"));
loadHTML.getParameters().add(new TMLScriptMethodParameter("url", "java.lang.String"));
methods.add(loadHTML);
loadHTML = new TMLScriptMethod("loadHTML", "org.dom4j.Document", GLOBAL_SCOPE_CLASSNAME);
loadHTML.getParameters().add(new TMLScriptMethodParameter("url", "java.lang.String"));
methods.add(loadHTML);
TMLScriptMethod loadObjectDefinition = new TMLScriptMethod("loadObjectDefinition", CLASSNAME_OBJECT_DEFINTION, GLOBAL_SCOPE_CLASSNAME);
loadObjectDefinition.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
loadObjectDefinition.getParameters().add(new TMLScriptMethodParameter("moduleName", "java.lang.String"));
methods.add(loadObjectDefinition);
loadObjectDefinition = new TMLScriptMethod("loadObjectDefinition", CLASSNAME_OBJECT_DEFINTION, GLOBAL_SCOPE_CLASSNAME);
loadObjectDefinition.getParameters().add(new TMLScriptMethodParameter("moduleName", "java.lang.String"));
methods.add(loadObjectDefinition);
if (hasEnvironmentFlag(env, ENV_MODULE)) {
TMLScriptMethod localDB = new TMLScriptMethod("localDB", "de.innovationgate.webgate.api.WGDatabase", GLOBAL_SCOPE_CLASSNAME);
localDB.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
methods.add(localDB);
localDB = new TMLScriptMethod("localDB", "de.innovationgate.webgate.api.WGDatabase", GLOBAL_SCOPE_CLASSNAME);
methods.add(localDB);
TMLScriptMethod localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
localLabel.getParameters().add(new TMLScriptMethodParameter("container", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("file", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
localLabel.getParameters().add(new TMLScriptMethodParameter("file", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("file", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
localLabel.getParameters().add(new TMLScriptMethodParameter("container", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("file", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("params", "java.util.List"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("currentObject", CLASSNAME_SCRIPT_OBJECT));
localLabel.getParameters().add(new TMLScriptMethodParameter("file", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("params", "java.util.List"));
methods.add(localLabel);
localLabel = new TMLScriptMethod("localLabel", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
localLabel.getParameters().add(new TMLScriptMethodParameter("file", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("key", "java.lang.String"));
localLabel.getParameters().add(new TMLScriptMethodParameter("params", "java.util.List"));
methods.add(localLabel);
}
TMLScriptMethod parseXML = new TMLScriptMethod("parseXML", "org.dom4j.Document", GLOBAL_SCOPE_CLASSNAME);
parseXML.getParameters().add(new TMLScriptMethodParameter("xmlText", "java.lang.String"));
methods.add(parseXML);
TMLScriptMethod registerGlobal = new TMLScriptMethod("registerGlobal", "void", GLOBAL_SCOPE_CLASSNAME);
registerGlobal.getParameters().add(new TMLScriptMethodParameter("name", "java.lang.String"));
registerGlobal.getParameters().add(new TMLScriptMethodParameter("ref", "java.lang.Object"));
methods.add(registerGlobal);
registerGlobal = new TMLScriptMethod("registerGlobal", "void", GLOBAL_SCOPE_CLASSNAME);
registerGlobal.getParameters().add(new TMLScriptMethodParameter("name", "java.lang.String"));
registerGlobal.getParameters().add(new TMLScriptMethodParameter("ref", "java.lang.Object"));
registerGlobal.getParameters().add(new TMLScriptMethodParameter("db", "de.innovationgate.webgate.api.WGDatabase"));
methods.add(registerGlobal);
TMLScriptMethod runMasterFunction = new TMLScriptMethod("runMasterFunction", "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
runMasterFunction.getParameters().add(new TMLScriptMethodParameter("func", CLASSNAME_SCRIPT_FUNCTION));
TMLScriptMethodParameter runMasterFunctionParams = new TMLScriptMethodParameter("param", "java.lang.Object");
runMasterFunctionParams.setVararg(true);
runMasterFunction.getParameters().add(runMasterFunctionParams);
methods.add(runMasterFunction);
runMasterFunction = new TMLScriptMethod("runMasterFunction", "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
runMasterFunction.getParameters().add(new TMLScriptMethodParameter("context", "de.innovationgate.wgpublisher.webtml.utils.TMLContext"));
runMasterFunction.getParameters().add(new TMLScriptMethodParameter("func", CLASSNAME_SCRIPT_FUNCTION));
runMasterFunctionParams = new TMLScriptMethodParameter("param", "java.lang.Object");
runMasterFunctionParams.setVararg(true);
runMasterFunction.getParameters().add(runMasterFunctionParams);
methods.add(runMasterFunction);
TMLScriptMethod runMasterMethod = new TMLScriptMethod("runMasterMethod", "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
runMasterMethod.getParameters().add(new TMLScriptMethodParameter("func", CLASSNAME_SCRIPT_FUNCTION));
TMLScriptMethodParameter runMasterMethodParams = new TMLScriptMethodParameter("param", "java.lang.Object");
runMasterMethodParams.setVararg(true);
runMasterMethod.getParameters().add(runMasterMethodParams);
methods.add(runMasterMethod);
TMLScriptMethod serializeObject = new TMLScriptMethod("serializeObject", "java.lang.String", GLOBAL_SCOPE_CLASSNAME);
serializeObject.getParameters().add(new TMLScriptMethodParameter("obj", "java.lang.Object"));
methods.add(serializeObject);
TMLScriptMethod sortList = new TMLScriptMethod("sortList", "void", GLOBAL_SCOPE_CLASSNAME);
sortList.getParameters().add(new TMLScriptMethodParameter("list", "java.util.List"));
methods.add(sortList);
sortList = new TMLScriptMethod("sortList", "void", GLOBAL_SCOPE_CLASSNAME);
sortList.getParameters().add(new TMLScriptMethodParameter("list", "java.util.List"));
sortList.getParameters().add(new TMLScriptMethodParameter("sortMeta", "java.lang.String"));
methods.add(sortList);
sortList = new TMLScriptMethod("sortList", "void", GLOBAL_SCOPE_CLASSNAME);
sortList.getParameters().add(new TMLScriptMethodParameter("list", "java.util.List"));
sortList.getParameters().add(new TMLScriptMethodParameter("compareFunction", CLASSNAME_SCRIPT_FUNCTION));
methods.add(sortList);
TMLScriptMethod synchronizedFunction = new TMLScriptMethod("synchronizedFunction", CLASSNAME_SCRIPT_FUNCTION, GLOBAL_SCOPE_CLASSNAME);
synchronizedFunction.getParameters().add(new TMLScriptMethodParameter("func", CLASSNAME_SCRIPT_FUNCTION));
methods.add(synchronizedFunction);
synchronizedFunction = new TMLScriptMethod("synchronizedFunction", CLASSNAME_SCRIPT_FUNCTION, GLOBAL_SCOPE_CLASSNAME);
synchronizedFunction.getParameters().add(new TMLScriptMethodParameter("func", CLASSNAME_SCRIPT_FUNCTION));
synchronizedFunction.getParameters().add(new TMLScriptMethodParameter("syncObj", "java.lang.Object"));
methods.add(synchronizedFunction);
TMLScriptMethod xpath = new TMLScriptMethod("xpath", "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
xpath.getParameters().add(new TMLScriptMethodParameter("xml", "java.lang.String"));
xpath.getParameters().add(new TMLScriptMethodParameter("xpath", "java.lang.String"));
methods.add(xpath);
xpath = new TMLScriptMethod("xpath", "java.lang.Object", GLOBAL_SCOPE_CLASSNAME);
xpath.getParameters().add(new TMLScriptMethodParameter("javaBean", "java.lang.Object"));
xpath.getParameters().add(new TMLScriptMethodParameter("xpath", "java.lang.String"));
methods.add(xpath);
TMLScriptMethod xpathList = new TMLScriptMethod("xpathList", "java.util.List", GLOBAL_SCOPE_CLASSNAME);
xpathList.getParameters().add(new TMLScriptMethodParameter("xml", "java.lang.String"));
xpathList.getParameters().add(new TMLScriptMethodParameter("xpath", "java.lang.String"));
methods.add(xpathList);
xpathList = new TMLScriptMethod("xpathList", "java.util.List", GLOBAL_SCOPE_CLASSNAME);
xpathList.getParameters().add(new TMLScriptMethodParameter("javaBean", "java.lang.Object"));
xpathList.getParameters().add(new TMLScriptMethodParameter("xpath", "java.lang.String"));
methods.add(xpathList);
}
}
private void performPropertyParsingViaJDTAST(final String classname, final Set<TMLScriptProperty> properties) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
StringWriter writer = new StringWriter();
InputStreamReader reader = new InputStreamReader(retrieveJavaSource(classname));
try {
WGUtils.inToOut(reader, writer, 1024);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
parser.setSource(writer.toString().toCharArray());
ASTNode ast = parser.createAST(new NullProgressMonitor());
ast.accept(new ASTVisitor() {
private Map<String, String> _imports = new HashMap<String, String>();
@Override
public void endVisit(TypeDeclaration node) {
final ReflectionModeVisitor modeVisitor = new ReflectionModeVisitor(_imports, classname);
node.accept(modeVisitor);
if (modeVisitor.getDelegate() != null) {
performPropertyParsingViaJDTAST(modeVisitor.getDelegate(), properties);
return;
}
if (modeVisitor.getPropertyMode() != ReflectionModeVisitor.MODE_UNKNOWN) {
node.accept(new ASTVisitor() {
@Override
public boolean visit(FieldDeclaration node) {
if (org.eclipse.jdt.core.dom.Modifier.isPublic(node.getModifiers())) {
CodeCompletionAnnotationVisitor codeCompletion = new CodeCompletionAnnotationVisitor(_imports, classname);
node.accept(codeCompletion);
if (modeVisitor.getPropertyMode() == ReflectionModeVisitor.MODE_INCLUDE && !codeCompletion.annotationExists()) {
return super.visit(node);
}
if (modeVisitor.getPropertyMode() == ReflectionModeVisitor.MODE_EXCLUDE && codeCompletion.annotationExists()) {
return super.visit(node);
}
String sType = buildFullQualifiedClassname(node.getType(), _imports, classname);
for (Object obj : node.fragments()) {
VariableDeclarationFragment fragment = (VariableDeclarationFragment) obj;
TMLScriptProperty tmlScriptProperty = new TMLScriptProperty(fragment.getName().toString(), sType, classname);
if (org.eclipse.jdt.core.dom.Modifier.isStatic(node.getModifiers())) {
tmlScriptProperty.setStatic(true);
}
properties.add(tmlScriptProperty);
}
}
return super.visit(node);
}
});
}
}
@Override
public void endVisit(ImportDeclaration node) {
String packageName = node.getName().toString();
if (!packageName.contains("*")) {
String simpleName = packageName;
if (packageName.contains(".")) {
simpleName = packageName.substring(packageName.lastIndexOf(".") + 1);
}
_imports.put(simpleName, packageName);
}
super.endVisit(node);
}
});
}
// public Set<TMLScriptMethod> getPublicMethods(String classname) {
// return getPublicMethods(classname, ENV_DEFAULT);
// }
public Set<TMLScriptMethod> getPublicMethods(String classname, int env) {
if (classname == null || classname.equals("java.lang.Object")) {
return Collections.emptySet();
}
if (!classname.startsWith("$N$")) {
if (classname.contains("[")) {
return retrieveJSArrayMethods(classname.substring(0, classname.indexOf("[")));
} else {
classname = jsWrap(classname);
}
} else {
classname = classname.substring("$N$".length());
}
if (classname.equals(JS_STRING)) {
return JS_STRING_METHODS;
} else if (classname.equals(JS_DOUBLE) || classname.equals(JS_FLOAT) || classname.equals(JS_INTEGER) || classname.equals(JS_LONG)) {
return JS_NUMBER_METHODS;
}
Set<TMLScriptMethod> methods = _publicMethodsCache.get(classname);
if (methods != null) {
if (classname.equals(GLOBAL_SCOPE_CLASSNAME)) {
Set<TMLScriptMethod> methodsInclGlobals = new HashSet<TMLScriptMethod>();
methodsInclGlobals.addAll(methods);
handleGlobalScopeMethods(methodsInclGlobals, env);
return methodsInclGlobals;
} else {
return methods;
}
}
methods = new HashSet<TMLScriptMethod>();
String effectiveClassname = classname;
if (classname.equals(GLOBAL_SCOPE_CLASSNAME)) {
effectiveClassname = "de.innovationgate.wgpublisher.webtml.utils.TMLContext";
}
// first attempt - try to retrieve method declarations from source
InputStream source = retrieveJavaSource(effectiveClassname);
if (source != null) {
//performMethodParsingViaANTLR(classname, methods, source);
performMethodParsingViaJDTAST(effectiveClassname, methods, env);
} else {
// second attempt - use java reflection for method declarations
try {
ClassLoader loader = retrieveClassLoader();
Class<?> clazz = loader.loadClass(effectiveClassname);
for (Method method : clazz.getDeclaredMethods()) {
if (Modifier.isPublic(method.getModifiers())) {
String type = "void";
if (method.getReturnType() != null) {
type = buildFullQualifiedClassname(method.getReturnType());
}
TMLScriptMethod tmlScriptMethod = new TMLScriptMethod(method.getName(), type, effectiveClassname);
if (Modifier.isStatic(method.getModifiers())) {
tmlScriptMethod.setStatic(true);
}
int i=0;
for (Class<?> paramType : method.getParameterTypes()) {
String paramTypeName = buildFullQualifiedClassname(paramType);
TMLScriptMethodParameter tmlscriptParam = new TMLScriptMethodParameter("arg" + i, paramTypeName);
tmlScriptMethod.getParameters().add(tmlscriptParam);
i++;
}
methods.add(tmlScriptMethod);
}
}
if (clazz.getSuperclass() != null) {
String superClass = clazz.getSuperclass().getName();
methods.addAll(getPublicMethods(superClass, env));
}
if (clazz.getInterfaces() != null) {
for (Class<?> intClass : clazz.getInterfaces()) {
methods.addAll(getPublicMethods(intClass.getName(), env));
}
}
}
catch (ClassNotFoundException e) {
// ignore unknown classes
}
}
_publicMethodsCache.put(classname, methods);
if (classname.equals(GLOBAL_SCOPE_CLASSNAME)) {
Set<TMLScriptMethod> methodsInclGlobals = new HashSet<TMLScriptMethod>();
methodsInclGlobals.addAll(methods);
handleGlobalScopeMethods(methodsInclGlobals, env);
return methodsInclGlobals;
} else {
return methods;
}
}
private void performMethodParsingViaJDTAST(final String classname, final Set<TMLScriptMethod> methods, final int envFlags) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
StringWriter writer = new StringWriter();
InputStreamReader reader = new InputStreamReader(retrieveJavaSource(classname));
try {
WGUtils.inToOut(reader, writer, 1024);
}
catch (IOException e) {
}
parser.setSource(writer.toString().toCharArray());
ASTNode ast = parser.createAST(new NullProgressMonitor());
ast.accept(new ASTVisitor() {
private Map<String, String> _imports = new HashMap<String, String>();
@Override
public void endVisit(ImportDeclaration node) {
String packageName = node.getName().toString();
if (!packageName.contains("*")) {
String simpleName = packageName;
if (packageName.contains(".")) {
simpleName = packageName.substring(packageName.lastIndexOf(".") + 1);
}
_imports .put(simpleName, packageName);
}
super.endVisit(node);
}
@Override
public void endVisit(TypeDeclaration node) {
ReflectionModeVisitor modeVisitor = new ReflectionModeVisitor(_imports, classname);
node.accept(modeVisitor);
if (modeVisitor.getDelegate() != null) {
performMethodParsingViaJDTAST(modeVisitor.getDelegate(), methods, envFlags);
return;
}
if (modeVisitor.getMethodMode() != ReflectionModeVisitor.MODE_UNKNOWN && org.eclipse.jdt.core.dom.Modifier.isPublic(node.getModifiers()) && node.isPackageMemberTypeDeclaration()) {
for (MethodDeclaration method : node.getMethods()) {
CodeCompletionAnnotationVisitor codeCompletion = new CodeCompletionAnnotationVisitor(_imports, classname);
method.accept(codeCompletion);
if (modeVisitor.getMethodMode() == ReflectionModeVisitor.MODE_INCLUDE && !codeCompletion.annotationExists()) {
continue;
}
if (modeVisitor.getMethodMode() == ReflectionModeVisitor.MODE_EXCLUDE && codeCompletion.annotationExists()) {
continue;
}
if (org.eclipse.jdt.core.dom.Modifier.isPublic(method.getModifiers()) && !method.isConstructor()) {
String sType = "void";
Type type = method.getReturnType2();
if (type != null) {
sType = buildFullQualifiedClassname(type, _imports, classname);
}
TMLScriptMethod tmlScriptMethod = new TMLScriptMethod(method.getName().toString(), sType, classname);
tmlScriptMethod.setBeanMode(modeVisitor.getBeanMode());
tmlScriptMethod.setDeprecated(isDeprecated(method));
if (org.eclipse.jdt.core.dom.Modifier.isStatic(method.getModifiers())) {
tmlScriptMethod.setStatic(true);
}
for (Object param : method.parameters()) {
SingleVariableDeclaration varDec = (SingleVariableDeclaration) param;
String varType = varDec.getType().toString();
if (_imports.containsKey(varType)) {
varType = _imports.get(varType);
}
de.innovationgate.eclipse.editors.tmlscript.parsing.TMLScriptMethodParameter tmlscriptParam = new de.innovationgate.eclipse.editors.tmlscript.parsing.TMLScriptMethodParameter(varDec.getName().toString(), varType);
tmlscriptParam.setVararg(varDec.isVarargs());
tmlScriptMethod.getParameters().add(tmlscriptParam);
}
methods.add(tmlScriptMethod);
}
}
Type superClass = node.getSuperclassType();
if (superClass != null) {
methods.addAll(getPublicMethods(buildFullQualifiedClassname(superClass, _imports, classname), envFlags));
}
}
super.endVisit(node);
}
});
}
@SuppressWarnings("unchecked")
protected boolean isDeprecated(MethodDeclaration method) {
Javadoc doc = method.getJavadoc();
if (doc != null) {
Iterator<TagElement> elements = doc.tags().iterator();
while (elements.hasNext()) {
TagElement element = elements.next();
if (element.getTagName() != null && element.getTagName().equals(TagElement.TAG_DEPRECATED)) {
return true;
}
}
}
return false;
}
private InputStream retrieveJavaSource(String classname) {
ZipInputStream zipIn = null;
try {
Version wgaVersion = (Version) WGADesignConfigurationModel.VERSIONCOMPLIANCE_TO_WGA_VERSION.get(_versionCompliance.getKey());
if (wgaVersion != null) {
InputStream sourceIn;
try {
sourceIn = Plugin.getDefault().getResourceAsStream("resources/wga/source_" + wgaVersion.getMajorVersion() + "_" + wgaVersion.getMinorVersion() + ".jar");
}
catch (Exception e) {
Plugin.getDefault().logError("Unable to find source for wga version compliance '" + wgaVersion.getMajorVersion() + "." + wgaVersion.getMinorVersion() + "'.");
return null;
}
zipIn = new ZipInputStream(sourceIn);
ZipEntry entry = zipIn.getNextEntry();
while (entry != null) {
String sourceName = entry.getName();
sourceName = sourceName.replaceAll("/", ".");
if (sourceName.endsWith(".java")) {
sourceName = sourceName.substring(0, sourceName.length() - ".java".length());
}
if (sourceName.equals(classname)) {
return zipIn;
}
entry = zipIn.getNextEntry();
}
}
}
catch (IOException e) {
}
// source not found
try {
zipIn.close();
}
catch (IOException e) {
}
return null;
}
private String buildFullQualifiedClassname(Type type, Map<String, String> imports, String classname) {
String sType = type.toString();
if (sType.contains("<")) {
sType = sType.substring(0, sType.indexOf("<"));
}
if (!sType.contains(".") && !type.isPrimitiveType()) {
if (imports.containsKey(sType)) {
sType = imports.get(sType);
} else if (_javaLangPackage.containsKey(sType)) {
sType = _javaLangPackage.get(sType);
} else {
String packageName = classname.substring(0, classname.lastIndexOf("."));
sType = packageName + "." + sType;
}
}
return sType;
}
private String buildFullQualifiedClassname(Name name, Map<String, String> imports, String classname) {
String sType = name.getFullyQualifiedName();
if (!sType.contains(".")) {
if (imports.containsKey(sType)) {
sType = imports.get(sType);
} else if (_javaLangPackage.containsKey(sType)) {
sType = _javaLangPackage.get(sType);
} else {
String packageName = classname.substring(0, classname.lastIndexOf("."));
sType = packageName + "." + sType;
}
}
return sType;
}
private String buildFullQualifiedClassname(Class<?> clazz) {
if (clazz != null) {
if (clazz.getName().startsWith("[")) {
return clazz.getComponentType().getName() + "[]";
} else {
return clazz.getName();
}
} else {
return null;
}
}
public static String buildSimpleClassname(String paramType) {
if (paramType != null && paramType.contains(".")) {
return paramType.substring(paramType.lastIndexOf(".") + 1);
} else {
return paramType;
}
}
private IVMInstall retrieveVMInstall() {
// currently only default VM
IVMInstall vm = JavaRuntime.getDefaultVMInstall();
return vm;
}
private ClassLoader retrieveClassLoader() {
List<URL> jarURLs = new ArrayList<URL>();
List<File> jars = retrieveJarFilesInClasspath(false);
for (File jarFile : jars) {
try {
jarURLs.add(jarFile.toURL());
}
catch (MalformedURLException e) {
Plugin.getDefault().logError("Unable to locate java library location for code completion.", e);
}
}
//
// LibraryLocation[] libLocations = JavaRuntime.getLibraryLocations(retrieveVMInstall());
// for (LibraryLocation libLocation : libLocations) {
// try {
// jarURLs.add(libLocation.getSystemLibraryPath().toFile().toURL());
// }
// catch (MalformedURLException e) {
// Plugin.getDefault().logError("Unable to locate java library location for code completion.", e);
// }
// }
//
// // try to find Core plugin and add J2EE libs to classpath
// Bundle bundle = Platform.getBundle("de.innovationgate.eclipse.plugins.Core");
// if (bundle != null) {
// Version wgaVersion = WGADesignConfigurationModel.VERSIONCOMPLIANCE_TO_WGA_VERSION.get(_versionCompliance.getKey());
// IPath path = new Path("resources").append("librarySets");
// if (wgaVersion.isAtLeast(5, 0)) {
// path = path.append("j2ee14");
// } else {
// path = path.append("j2ee13");
// }
// URL librarySetURL = FileLocator.find(bundle, path, null);
// try {
// File librarySetsDir = new File(FileLocator.toFileURL(librarySetURL).getPath());
// File[] jars = librarySetsDir.listFiles(new FilenameFilter() {
//
// public boolean accept(File dir, String name) {
// return name.endsWith(".jar");
// }
// });
// for (File jar : jars) {
// jarURLs.add(jar.toURL());
// }
// }
// catch (IOException e) {
// Plugin.getDefault().logError("Unable to locate java library location for code completion.", e);
// }
// }
return new URLClassLoader(jarURLs.toArray(new URL[0]));
}
private List<File> retrieveJarFilesInClasspath(boolean includeSource) {
List<File> jarFiles = new ArrayList<File>();
// retrieve from lib locations of VM
LibraryLocation[] libLocations = JavaRuntime.getLibraryLocations(retrieveVMInstall());
for (LibraryLocation libLocation : libLocations) {
File jarFile = libLocation.getSystemLibraryPath().toFile();
jarFiles.add(jarFile);
}
Version wgaVersion = (Version) WGADesignConfigurationModel.VERSIONCOMPLIANCE_TO_WGA_VERSION.get(_versionCompliance.getKey());
if (includeSource) {
if (wgaVersion != null) {
try {
File sourceJar = Plugin.getDefault().getResourceAsFile("resources/wga/source_" + wgaVersion.getMajorVersion() + "_" + wgaVersion.getMinorVersion() + ".jar");
if (sourceJar != null) {
jarFiles.add(sourceJar);
}
}
catch (IOException e) {
Plugin.getDefault().logWarning("Unable to retrieve wga source.jar as file.", e);
}
}
}
// retrieve J2EE libs
Bundle bundle = Platform.getBundle("de.innovationgate.eclipse.plugins.Core");
if (bundle != null && wgaVersion != null) {
IPath path = new Path("resources").append("librarySets");
if (wgaVersion.isAtLeast(5, 0)) {
path = path.append("j2ee14");
} else {
path = path.append("j2ee13");
}
URL librarySetURL = FileLocator.find(bundle, path, null);
try {
File librarySetsDir = new File(FileLocator.toFileURL(librarySetURL).getPath());
File[] jars = librarySetsDir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
});
jarFiles.addAll(Arrays.asList(jars));
} catch (Exception e) {
}
}
return jarFiles;
}
private List<String> getClassNamesInPackage(File jar, String packageName, boolean includeSubPackages) {
List<String> classes = new ArrayList<String>();
packageName = packageName.replaceAll("\\.", "/");
JarInputStream jarIn = null;
try {
jarIn = new JarInputStream(new FileInputStream(jar));
JarEntry jarEntry = jarIn.getNextJarEntry();
while (jarEntry != null) {
if (jarEntry.getName().endsWith(".class")) {
String name = jarEntry.getName().replaceAll("/", "\\.");
if (!name.contains("$")) {
name = name.substring(0, name.length() - ".class".length());
}
if (includeSubPackages) {
if (jarEntry.getName().startsWith(packageName)) {
classes.add(name);
}
} else {
if (jarEntry.getName().substring(0, jarEntry.getName().lastIndexOf('/')).equals(packageName)) {
classes.add(name);
}
}
}
jarEntry = jarIn.getNextJarEntry();
}
}
catch (Exception e) {
Plugin.getDefault().logError("Error during lookup of classnames for package '" + packageName + "'.", e);
} finally {
if (jarIn != null) {
try {
jarIn.close();
}
catch (IOException e) {
}
}
}
return classes;
}
private List<String> getClassNamesInPackage(String packageName, boolean includeSubPackages) {
List<String> classNames = new ArrayList<String>();
LibraryLocation[] libLocations = JavaRuntime.getLibraryLocations(retrieveVMInstall());
for (LibraryLocation libLocation : libLocations) {
classNames.addAll(getClassNamesInPackage(libLocation.getSystemLibraryPath().toFile(), packageName, includeSubPackages));
}
return classNames;
}
// private List<String> retrievePackageNames() {
// List<String> packageNames = new ArrayList<String>();
//
// List<File> jarFiles = retrieveJarFilesInClasspath(true);
// for (File jarFile : jarFiles) {
// JarInputStream jarIn = null;
// try {
// jarIn = new JarInputStream(new FileInputStream(jarFile));
// JarEntry jarEntry = jarIn.getNextJarEntry();
// while (jarEntry != null) {
// if (jarEntry.isDirectory()) {
// String name = jarEntry.getName().replaceAll("/", "\\.");
// if (name.endsWith(".")) {
// name = name.substring(0, name.length()-1);
// }
// packageNames.add(name);
// }
// jarEntry = jarIn.getNextJarEntry();
// }
// } catch (Exception e) {
// Plugin.getDefault().logError("Error during package name retrival.", e);
// } finally {
// if (jarIn != null) {
// try {
// jarIn.close();
// }
// catch (IOException e) {
// }
// }
// }
// }
//
//
// return packageNames;
// }
private void retrievePackages() {
List<File> jarFiles = retrieveJarFilesInClasspath(true);
for (File jarFile : jarFiles) {
JarInputStream jarIn = null;
try {
jarIn = new JarInputStream(new FileInputStream(jarFile));
JarEntry jarEntry = jarIn.getNextJarEntry();
while (jarEntry != null) {
if (!jarEntry.isDirectory() && !jarEntry.getName().contains("$") && (jarEntry.getName().endsWith(".class") || jarEntry.getName().endsWith(".java"))) {
String packageName = jarEntry.getName().substring(0, jarEntry.getName().lastIndexOf("/"));
packageName = packageName.replaceAll("/", "\\.");
String className = jarEntry.getName().replaceAll("/", "\\.");
if (className.endsWith(".class")) {
className = className.substring(0, className.indexOf(".class"));
} else if (className.endsWith(".java")) {
className = className.substring(0, className.indexOf(".java"));
}
TMLScriptPackage tmlscriptPackage = _packages.get(packageName);
if (tmlscriptPackage == null) {
tmlscriptPackage = new TMLScriptPackage(packageName);
_packages.put(packageName, tmlscriptPackage);
}
tmlscriptPackage.getClassnames().add(className);
//Set<TMLScriptMethod> constructors = getPublicConstructors(className);
//tmlscriptPackage.getConstructors().addAll(constructors);
}
jarEntry = jarIn.getNextJarEntry();
}
} catch (Exception e) {
Plugin.getDefault().logError("Error during package retrival.", e);
} finally {
if (jarIn != null) {
try {
jarIn.close();
}
catch (IOException e) {
}
}
}
}
}
public Set<TMLScriptMethod> getPublicConstructors(String classname) {
if (classname == null || classname.equals("java.lang.Object")) {
return Collections.emptySet();
}
Set<TMLScriptMethod> constructors = _publicConstructorsCache.get(classname);
if (constructors != null) {
return constructors;
}
constructors = new HashSet<TMLScriptMethod>();
String effectiveClassname = classname;
if (classname.equals(GLOBAL_SCOPE_CLASSNAME)) {
effectiveClassname = "de.innovationgate.wgpublisher.webtml.utils.TMLContext";
}
// first attempt - try to retrieve constructors declarations from source
InputStream source = retrieveJavaSource(effectiveClassname);
if (source != null) {
performConstructorParsingViaJDTAST(effectiveClassname, constructors);
} else {
// second attempt - use java reflection for constructor declarations
try {
ClassLoader loader = retrieveClassLoader();
Class<?> clazz = loader.loadClass(effectiveClassname);
for (Constructor<?> constructor : clazz.getDeclaredConstructors()) {
if (Modifier.isPublic(constructor.getModifiers())) {
String type = effectiveClassname;
TMLScriptMethod tmlScriptMethod = new TMLScriptMethod(constructor.getName().substring(constructor.getName().lastIndexOf(".") + 1), type, effectiveClassname);
int i=0;
for (Class<?> paramType : constructor.getParameterTypes()) {
TMLScriptMethodParameter tmlscriptParam = new TMLScriptMethodParameter("arg" + i, paramType.getName());
tmlScriptMethod.getParameters().add(tmlscriptParam);
i++;
}
constructors.add(tmlScriptMethod);
}
}
}
catch (ClassNotFoundException e) {
// ignore unknown classes
}
}
_publicConstructorsCache.put(classname, constructors);
return constructors;
}
private void performConstructorParsingViaJDTAST(final String classname, final Set<TMLScriptMethod> constructors) {
ASTParser parser = ASTParser.newParser(AST.JLS3);
StringWriter writer = new StringWriter();
InputStreamReader reader = new InputStreamReader(retrieveJavaSource(classname));
try {
WGUtils.inToOut(reader, writer, 1024);
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
parser.setSource(writer.toString().toCharArray());
ASTNode ast = parser.createAST(new NullProgressMonitor());
ast.accept(new ASTVisitor() {
private Map<String, String> _imports = new HashMap<String, String>();
@Override
public void endVisit(ImportDeclaration node) {
String packageName = node.getName().toString();
if (!packageName.contains("*")) {
String simpleName = packageName;
if (packageName.contains(".")) {
simpleName = packageName.substring(packageName.lastIndexOf(".") + 1);
}
_imports .put(simpleName, packageName);
}
super.endVisit(node);
}
@Override
public void endVisit(TypeDeclaration node) {
ReflectionModeVisitor modeVisitor = new ReflectionModeVisitor(_imports, classname);
node.accept(modeVisitor);
if (modeVisitor.getDelegate() != null) {
performConstructorParsingViaJDTAST(modeVisitor.getDelegate(), constructors);
return;
}
if (modeVisitor.getMethodMode() != ReflectionModeVisitor.MODE_UNKNOWN && org.eclipse.jdt.core.dom.Modifier.isPublic(node.getModifiers()) && node.isPackageMemberTypeDeclaration()) {
for (MethodDeclaration method : node.getMethods()) {
CodeCompletionAnnotationVisitor codeCompletion = new CodeCompletionAnnotationVisitor(_imports, classname);
method.accept(codeCompletion);
if (modeVisitor.getMethodMode() == ReflectionModeVisitor.MODE_INCLUDE && !codeCompletion.annotationExists()) {
continue;
}
if (modeVisitor.getMethodMode() == ReflectionModeVisitor.MODE_EXCLUDE && codeCompletion.annotationExists()) {
continue;
}
if (org.eclipse.jdt.core.dom.Modifier.isPublic(method.getModifiers()) && method.isConstructor()) {
String sType = classname;
TMLScriptMethod tmlScriptMethod = new TMLScriptMethod(method.getName().toString(), sType, classname);
tmlScriptMethod.setDeprecated(isDeprecated(method));
for (Object param : method.parameters()) {
SingleVariableDeclaration varDec = (SingleVariableDeclaration) param;
String varType = varDec.getType().toString();
if (_imports.containsKey(varType)) {
varType = _imports.get(varType);
}
de.innovationgate.eclipse.editors.tmlscript.parsing.TMLScriptMethodParameter tmlscriptParam = new de.innovationgate.eclipse.editors.tmlscript.parsing.TMLScriptMethodParameter(varDec.getName().toString(), varType);
tmlScriptMethod.getParameters().add(tmlscriptParam);
}
constructors.add(tmlScriptMethod);
}
}
}
super.endVisit(node);
}
});
}
public Set<TMLScriptPackage> getPackages() {
Set<TMLScriptPackage> packages = new HashSet<TMLScriptPackage>();
packages.addAll(_packages.values());
return packages;
}
public Set<TMLScriptProperty> getPublicStaticProperties(String classname) {
return getPublicStaticProperties(classname, ENV_DEFAULT);
}
public Set<TMLScriptProperty> getPublicStaticProperties(String classname, int env) {
Set<TMLScriptProperty> filtered = new HashSet<TMLScriptProperty>();
Iterator<TMLScriptProperty> properties = getPublicProperties(classname, env).iterator();
while (properties.hasNext()) {
TMLScriptProperty prop = properties.next();
if (prop.isStatic()) {
filtered.add(prop);
}
}
return filtered;
}
public Set<TMLScriptMethod> getPublicStaticMethods(String classname) {
return getPublicStaticMethods(classname, ENV_DEFAULT);
}
public Set<TMLScriptMethod> getPublicStaticMethods(String classname, int env) {
Set<TMLScriptMethod> filtered = new HashSet<TMLScriptMethod>();
Iterator<TMLScriptMethod> methods = getPublicMethods(classname, env).iterator();
while (methods.hasNext()) {
TMLScriptMethod method = methods.next();
if (method.isStatic()) {
filtered.add(method);
}
}
return filtered;
}
class ReflectionModeVisitor extends ASTVisitor {
public static final int MODE_UNKNOWN = -1;
public static final int MODE_INCLUDE = 1;
public static final int MODE_EXCLUDE = 2;
public static final int BEAN_MODE_LOWERCASED = 1;
public static final int BEAN_MODE_ALL = 2;
public static final int BEAN_MODE_NONE = 3;
private int _methodMode = MODE_UNKNOWN;
private int _propertyMode = MODE_UNKNOWN;
private int _beanMode = MODE_UNKNOWN;
private String _delegate = null;
private Map<String, String> _imports;
private String _classname;
public ReflectionModeVisitor(Map<String, String> imports, String classname) {
_imports = imports;
_classname = classname;
if (_classname.startsWith("de.innovationgate.webgate.api") || _classname.startsWith("de.innovationgate.utils")) {
// change defaults for WGAPI and utils
_methodMode = MODE_EXCLUDE;
_propertyMode = MODE_EXCLUDE;
_beanMode = BEAN_MODE_NONE;
}
}
@Override
public void endVisit(NormalAnnotation node) {
String fqName = buildFullQualifiedClassname(node.getTypeName(), _imports, _classname);
if (fqName != null && fqName.equals("de.innovationgate.wga.common.CodeCompletion")) {
// annotation present set defaults
_methodMode = MODE_EXCLUDE;
_propertyMode = MODE_INCLUDE;
_beanMode = BEAN_MODE_LOWERCASED;
_delegate = null;
node.accept(new ASTVisitor() {
@Override
public void endVisit(MemberValuePair node) {
if (node.getName().toString().equals("methodMode")) {
if (node.getValue().toString().contains("MODE_EXCLUDE")) {
_methodMode = MODE_EXCLUDE;
} else if (node.getValue().toString().contains("MODE_INCLUDE")) {
_methodMode = MODE_INCLUDE;
}
}
if (node.getName().toString().equals("propertyMode")) {
if (node.getValue().toString().contains("MODE_EXCLUDE")) {
_propertyMode = MODE_EXCLUDE;
} else if (node.getValue().toString().contains("MODE_INCLUDE")) {
_propertyMode = MODE_INCLUDE;
}
}
if (node.getName().toString().equals("beanMode")) {
if (node.getValue().toString().contains("BEAN_MODE_ALL")) {
_beanMode = BEAN_MODE_ALL;
} else if (node.getValue().toString().contains("BEAN_MODE_LOWERCASED")) {
_beanMode = BEAN_MODE_LOWERCASED;
} else if (node.getValue().toString().contains("BEAN_MODE_NONE")) {
_beanMode = BEAN_MODE_NONE;
}
}
if (node.getName().toString().equals("delegate")) {
if (node.getValue() instanceof TypeLiteral) {
TypeLiteral literal = (TypeLiteral)node.getValue();
String fqname = buildFullQualifiedClassname(literal.getType(), _imports, _classname);
if (!fqname.equals(CodeCompletion.class.getName())) {
_delegate = fqname;
}
}
}
super.endVisit(node);
}
});
}
super.endVisit(node);
}
public int getMethodMode() {
return _methodMode;
}
public int getBeanMode() {
return _beanMode;
}
public int getPropertyMode() {
return _propertyMode;
}
public String getDelegate() {
return _delegate;
}
}
private class CodeCompletionAnnotationVisitor extends ASTVisitor {
private boolean _annotationExists = false;
private Map<String, String> _imports;
private String _classname;
public CodeCompletionAnnotationVisitor(Map<String, String> imports, String classname) {
_imports = imports;
_classname = classname;
}
@Override
public void endVisit(MarkerAnnotation node) {
String fqName = buildFullQualifiedClassname(node.getTypeName(), _imports, _classname);
if (fqName != null && fqName.equals("de.innovationgate.wga.common.CodeCompletion")) {
_annotationExists = true;
}
super.endVisit(node);
}
public boolean annotationExists() {
return _annotationExists;
}
}
private static boolean hasEnvironmentFlag(int flags, int flag) {
int tmp= flags & flag;
if(tmp==flag) {
return true;
}
return false;
}
public static String jsWrap(String sType) {
if (sType != null) {
if (sType.equals("java.lang.String")) {
return JS_STRING;
} else if (sType.equals("boolean") || sType.equals("java.lang.Boolean")) {
return JS_BOOLEAN;
} else if (sType.equals("int") || sType.equals("java.lang.Integer")) {
return JS_INTEGER;
} else if (sType.equals("float") || sType.equals("java.lang.Float")) {
return JS_FLOAT;
} else if (sType.equals("double") || sType.equals("java.lang.Double")) {
return JS_DOUBLE;
} else if (sType.equals("long") || sType.equals("java.lang.Long")) {
return JS_LONG;
} else if (sType.equals("java.lang.Number")) {
return JS_NUMBER;
}
}
return sType;
}
public static String jsUnwrap(String input) {
if (input != null) {
// if (type.equals(JS_STRING)) {
// return "java.lang.String";
// } else if (type.equals(JS_BOOLEAN)) {
// return "java.lang.Boolean";
// } else if (type.equals(JS_INTEGER)) {
// return "java.lang.Integer";
// } else if (type.equals(JS_FLOAT)) {
// return "java.lang.Float";
// } else if (type.equals(JS_LONG)) {
// return "java.lang.Long";
// } else if (type.equals(JS_DOUBLE)) {
// return "java.lang.Double";
// } else if (type.equals(JS_NUMBER)) {
// return "java.lang.Double";
// }
//
String className = null;
boolean isArray = false;
String type = input;
if (input.contains("[")) {
isArray = true;
type = type.substring(0, type.indexOf("["));
}
if (type.contains(".")) {
className = type;
} else {
if (type.equals("boolean")) {
className = "java.lang.Boolean";
} else if (type.equals("long")) {
className = "java.lang.Long";
} else if (type.equals("int")) {
className = "java.lang.Integer";
} else if (type.equals("float")) {
className = "java.lang.Float";
} else if (type.equals("double")) {
className = "java.lang.Double";
}
}
if (className != null) {
if (isArray) {
return "$N$" + className + "[]";
} else {
return "$N$" + className;
}
}
}
return input;
}
public static Set<TMLScriptMethod> retrieveJSArrayMethods(String type) {
Set<TMLScriptMethod> methods = new HashSet<TMLScriptMethod>();
TMLScriptMethod method = new TMLScriptMethod("pop", type, JS_ARRAY);
methods.add(method);
method = new TMLScriptMethod("push", "int", JS_ARRAY);
TMLScriptMethodParameter param = new TMLScriptMethodParameter("element", type);
param.setVararg(true);
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("reverse", type + "[]", JS_ARRAY);
methods.add(method);
method = new TMLScriptMethod("shift", type, JS_ARRAY);
methods.add(method);
method = new TMLScriptMethod("sort", "void", JS_ARRAY);
param = new TMLScriptMethodParameter("compareFunct", JS_FUNCTION);
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("splice", type, JS_ARRAY);
param = new TMLScriptMethodParameter("index", "int");
method.getParameters().add(param);
param = new TMLScriptMethodParameter("howMany", "int");
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("splice", type, JS_ARRAY);
param = new TMLScriptMethodParameter("index", "int");
method.getParameters().add(param);
param = new TMLScriptMethodParameter("howMany", "int");
method.getParameters().add(param);
param = new TMLScriptMethodParameter("element", type);
param.setVararg(true);
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("unshift", "int", JS_ARRAY);
param = new TMLScriptMethodParameter("element", type);
param.setVararg(true);
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("concat", type + "[]", JS_ARRAY);
param = new TMLScriptMethodParameter("value", type + "[]");
param.setVararg(true);
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("concat", type + "[]", JS_ARRAY);
param = new TMLScriptMethodParameter("value", type);
param.setVararg(true);
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("join", "java.lang.String", JS_ARRAY);
param = new TMLScriptMethodParameter("separator", "java.lang.String");
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("slice", type + "[]", JS_ARRAY);
param = new TMLScriptMethodParameter("begin", "int");
method.getParameters().add(param);
methods.add(method);
method = new TMLScriptMethod("slice", type + "[]", JS_ARRAY);
param = new TMLScriptMethodParameter("begin", "int");
param = new TMLScriptMethodParameter("end", "int");
method.getParameters().add(param);
methods.add(method);
return methods;
}
public static Set<TMLScriptProperty> retrieveJSArrayProperties(String type) {
Set<TMLScriptProperty> props = new HashSet<TMLScriptProperty>();
props.add(new TMLScriptProperty("length", "int", JS_ARRAY));
return props;
}
}