/*******************************************************************************
* Copyright 2009, 2010 Innovation Gate GmbH. All Rights Reserved.
*
* This file is part of the OpenWGA server platform.
*
* OpenWGA is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* In addition, a special exception is granted by the copyright holders
* of OpenWGA called "OpenWGA plugin exception". You should have received
* a copy of this exception along with OpenWGA in file COPYING.
* If not, see <http://www.openwga.com/gpl-plugin-exception>.
*
* OpenWGA is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with OpenWGA in file COPYING.
* If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package de.innovationgate.wgpublisher.expressions.tmlscript.wgaglobal;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.servlet.http.Cookie;
import org.apache.log4j.Logger;
import org.cyberneko.html.parsers.DOMParser;
import org.dom4j.io.DOMReader;
import org.xml.sax.InputSource;
import de.innovationgate.ext.org.mozilla.javascript.Context;
import de.innovationgate.ext.org.mozilla.javascript.EvaluatorException;
import de.innovationgate.ext.org.mozilla.javascript.Function;
import de.innovationgate.ext.org.mozilla.javascript.JavaScriptException;
import de.innovationgate.ext.org.mozilla.javascript.NativeArray;
import de.innovationgate.ext.org.mozilla.javascript.NativeJavaObject;
import de.innovationgate.ext.org.mozilla.javascript.NativeObject;
import de.innovationgate.ext.org.mozilla.javascript.RhinoException;
import de.innovationgate.ext.org.mozilla.javascript.Scriptable;
import de.innovationgate.ext.org.mozilla.javascript.ScriptableObject;
import de.innovationgate.ext.org.mozilla.javascript.WrappedException;
import de.innovationgate.ext.org.mozilla.javascript.Wrapper;
import de.innovationgate.utils.FormattingException;
import de.innovationgate.utils.ImageScaler;
import de.innovationgate.utils.XStreamUtils;
import de.innovationgate.utils.Zipper;
import de.innovationgate.webgate.api.WGAPIException;
import de.innovationgate.webgate.api.WGContent;
import de.innovationgate.webgate.api.WGDatabase;
import de.innovationgate.webgate.api.WGDocument;
import de.innovationgate.webgate.api.WGException;
import de.innovationgate.webgate.api.WGHierarchicalDatabase;
import de.innovationgate.webgate.api.WGStructEntryList;
import de.innovationgate.wga.common.CodeCompletion;
import de.innovationgate.wga.modules.ModuleInstantiationException;
import de.innovationgate.wgpublisher.expressions.ExpressionEngine;
import de.innovationgate.wgpublisher.expressions.ExpressionResult;
import de.innovationgate.wgpublisher.expressions.tmlscript.ContextRedirector;
import de.innovationgate.wgpublisher.expressions.tmlscript.JavascriptFunctionComparator;
import de.innovationgate.wgpublisher.expressions.tmlscript.RhinoContext;
import de.innovationgate.wgpublisher.expressions.tmlscript.RhinoExpressionEngine;
import de.innovationgate.wgpublisher.expressions.tmlscript.RhinoExpressionEngineImpl;
import de.innovationgate.wgpublisher.expressions.tmlscript.SynchronizedFunction;
import de.innovationgate.wgpublisher.expressions.tmlscript.TMLScriptDate;
import de.innovationgate.wgpublisher.expressions.tmlscript.TMLScriptGlobal;
import de.innovationgate.wgpublisher.expressions.tmlscript.TMLScriptRootScope;
import de.innovationgate.wgpublisher.expressions.tmlscript.ThreadLocalPreserver;
import de.innovationgate.wgpublisher.expressions.tmlscript.VarArgParser;
import de.innovationgate.wgpublisher.expressions.tmlscript.VarArgParser.Arguments;
import de.innovationgate.wgpublisher.plugins.WGAPlugin;
import de.innovationgate.wgpublisher.scheduler.JobContext;
import de.innovationgate.wgpublisher.webtml.utils.FormInfo;
import de.innovationgate.wgpublisher.webtml.utils.Mail;
import de.innovationgate.wgpublisher.webtml.utils.TMLAction;
import de.innovationgate.wgpublisher.webtml.utils.TMLActionException;
import de.innovationgate.wgpublisher.webtml.utils.TMLContext;
import de.innovationgate.wgpublisher.webtml.utils.TMLException;
import de.innovationgate.wgpublisher.webtml.utils.TMLForm;
import de.innovationgate.wgpublisher.webtml.utils.URLBuilder;
@CodeCompletion(delegate=WGAGlobalCC.class)
public class WGAGlobal extends ScriptableObject {
private static Auth _auth = new Auth();
private static Xml _xml = new Xml();
private static Master _master = new Master();
private static Html _html = new Html();
private static class ListComparatorByMeta implements Comparator {
private String metaName = new String();
private int sortSign = 1;
public ListComparatorByMeta(String metaName, int sortDir) {
if (metaName != null) {
this.metaName = metaName;
}
else {
this.metaName = "name";
}
this.sortSign = sortDir;
}
public int compare(Object o1, Object o2) {
int ret = 0;
if (o1 instanceof WGDocument && o2 instanceof WGDocument) {
Object value1 = null;
Object value2 = null;
try {
value1 = (Object) ((WGDocument) o1).getMetaData(this.metaName);
value2 = (Object) ((WGDocument) o2).getMetaData(this.metaName);
}
catch (WGAPIException e) {
RhinoContext.throwAsScriptRuntimeEx(e);
}
if (value1 instanceof Date && value2 instanceof Date) {
Long millis1 = new Long(((Date) value1).getTime());
Long millis2 = new Long(((Date) value2).getTime());
ret = millis1.compareTo(millis2);
}
else if (value1 instanceof Double && value2 instanceof Double) {
ret = ((Double) value1).compareTo(((Double) value2));
}
else if (value1 instanceof Integer && value2 instanceof Integer) {
ret = ((Integer) value1).compareTo(((Integer) value2));
}
else {
ret = ((String) value1).toLowerCase().compareTo(((String) value2).toLowerCase());
}
}
else if (o1 instanceof Comparable && o2 instanceof Comparable) {
return ((Comparable) o1).compareTo(o2);
}
else {
String value1 = o1.toString();
String value2 = o2.toString();
if (value1 != null && value2 != null) {
ret = value1.toLowerCase().compareTo(value2.toLowerCase());
}
else {
ret = 1;
}
}
return ret * this.sortSign;
}
public boolean equals(Object o1) {
return this.equals(o1);
}
}
private static class ListComparatorByMetaList implements Comparator {
private List metaNames = new ArrayList();
private int sortSign = 1;
public ListComparatorByMetaList(List metaNames, int sortDir) {
if (metaNames != null) {
this.metaNames = metaNames;
}
else {
throw new IllegalArgumentException();
}
this.sortSign = sortDir;
}
public int compare(Object o1, Object o2) {
int ret = 0;
if (this.metaNames == null || this.metaNames.isEmpty())
return 0;
if (o1 instanceof WGDocument && o2 instanceof WGDocument) {
Iterator it = this.metaNames.iterator();
while (it.hasNext()) {
String metaName = (String) it.next();
Object value1 = null;
Object value2 = null;
try {
value1 = (Object) ((WGDocument) o1).getMetaData(metaName);
value2 = (Object) ((WGDocument) o2).getMetaData(metaName);
}
catch (WGAPIException e) {
RhinoContext.throwAsScriptRuntimeEx(e);
}
if (value1 instanceof Date && value2 instanceof Date) {
Long millis1 = new Long(((Date) value1).getTime());
Long millis2 = new Long(((Date) value2).getTime());
ret = millis1.compareTo(millis2);
}
else if (value1 instanceof Double && value2 instanceof Double) {
ret = ((Double) value1).compareTo(((Double) value2));
}
else if (value1 instanceof Integer && value2 instanceof Integer) {
ret = ((Integer) value1).compareTo(((Integer) value2));
}
else {
ret = ((String) value1).toLowerCase().compareTo(((String) value2).toLowerCase());
}
if (ret != 0)
break;
}
}
return ret * this.sortSign;
}
public boolean equals(Object o1) {
return this.equals(o1);
}
}
protected static VarArgParser _createObjectVarargs;
protected static VarArgParser _loadObjectDefVarags;
static VarArgParser _localLabelVarargs;
protected static VarArgParser _callActionVarargs;
private static VarArgParser _getLookupKeysVarargs;
private static VarArgParser _buildOptionsVarargs;
private static VarArgParser _singleDateParam;
private static VarArgParser _designVarargs;
private static VarArgParser _scopedVarargs;
private static VarArgParser _createCookieVarargs = VarArgParser.create("createCookie").add("name", String.class).add("value", String.class).pack();
static {
_callActionVarargs = VarArgParser.create("callAction")
.add("context", TMLContext.class, true)
.add("id", String.class)
.setUnwrapOverflowArgs(false)
.pack();
_loadObjectDefVarags = VarArgParser.create("loadObjectDefinition")
.add("currentObject", NativeObject.class, true)
.add("id", String.class)
.pack();
_createObjectVarargs = VarArgParser.create("createObject")
.add("currentObject", NativeObject.class, true)
.add("definition", new Class[] { Function.class, String.class })
.setUnwrapOverflowArgs(false)
.pack();
_getLookupKeysVarargs = VarArgParser.create("getLookupKeys")
.add("table", Map.class, false)
.pack();
_localLabelVarargs = VarArgParser.create("localLabel")
.add("container", String.class, true)
.add("file", String.class, true)
.add("key", String.class, false)
.add("params", List.class, true)
.pack();
_buildOptionsVarargs = VarArgParser.create("buildOptions")
.add("contents", Iterable.class, false)
.add("title", String.class, true)
.add("emptyTitle", String.class, true)
.pack();
_singleDateParam = VarArgParser.create("dateOnly/timeOnly/createCalendar")
.add("date", Date.class)
.pack();
_designVarargs = VarArgParser.create("design")
.add("ref", new Class[] { NativeObject.class, WGDatabase.class, String.class }, true)
.pack();
_scopedVarargs = VarArgParser.create("scoped")
.add("value", String.class, false)
.add("scope", String.class, true)
.pack();
}
public WGAGlobal() {
super();
// Functions on WGAGlobal object itself
String[] functions = {
"buildOptions",
"callAction",
"createCalendar",
"createCookie",
"createDate",
"createForm",
"createFormInfo",
"createImageScaler",
"createList",
"createLookupTable",
"createMail",
"createObject",
"dateOnly",
"db",
"deleteDoublets",
"deserializeObject",
"design",
"encode",
"format",
"getLookupKeys",
"hdb",
"javaObject",
"loadObjectDefinition",
"logException",
"lucene",
"parseDate",
"parseNumber",
"plugin",
"redirectTo",
"scoped",
"scriptObject",
"serializeObject",
"sortList",
"synchronizedFunction",
"timeOnly",
"urlBuilder"
};
defineFunctionProperties(functions, WGAGlobal.class, DONTENUM);
// Sub-Objects
put("Xml", this, _xml);
put("Html", this, _html);
put("Master", this, _master);
put("Auth", this, _auth);
}
@Override
public String getClassName() {
return "WGA";
}
public static Scriptable javaObject(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
if (args.length == 0 || args[0] == null) {
return null;
}
Object object = args[0];
if (object instanceof de.innovationgate.ext.org.mozilla.javascript.NativeJavaObject) {
object = ((de.innovationgate.ext.org.mozilla.javascript.NativeJavaObject) object).unwrap();
;
}
return new de.innovationgate.ext.org.mozilla.javascript.NativeJavaObject(thisObj, object, object.getClass());
}
public static Scriptable synchronizedFunction(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
if (args.length == 0) {
Context.reportError("No parameters specified for synchronizedFunction(.");
}
if (!(args[0] instanceof Function)) {
Context.reportError("The first argument for synchronizedFunction() must be a Function object");
}
if (args.length == 1) {
TMLContext context = fetchInitialContext(cx);
return new SynchronizedFunction((Function) args[0], context.getwgacore());
}
else {
return new SynchronizedFunction((Function) args[0], args[1]);
}
}
public static Scriptable scriptObject(Context cx, Scriptable thisObj, Object[] args, Function funObj) {
if (args.length == 0 || args[0] == null) {
return null;
}
else {
return Context.toObject(args[0], thisObj);
}
}
public static String format(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
Object toBeFormatted = args[0];
String formatString = null;
if (args.length >= 2 && args[1] != null) {
formatString = args[1].toString();
}
String formatTarget = null;
if (toBeFormatted instanceof NativeJavaObject) {
toBeFormatted = ((NativeJavaObject) toBeFormatted).unwrap();
}
else if (toBeFormatted instanceof Scriptable && toBeFormatted.getClass().getName().equals("de.innovationgate.ext.org.mozilla.javascript.NativeDate")) {
Scriptable jsDate = (Scriptable) toBeFormatted;
Double javaTime = (Double) ScriptableObject.callMethod(jsDate, "getTime", null);
toBeFormatted = new Date(javaTime.longValue());
}
else if (toBeFormatted instanceof Scriptable) {
toBeFormatted = ((Scriptable) toBeFormatted).getDefaultValue(null);
}
// Fetch locale to use
TMLContext context = fetchInitialContext(cx);
Locale locale = null;
if (context != null) {
locale = context.getPreferredLanguageLocale();
if (locale == null) {
locale = Locale.getDefault();
}
}
if (toBeFormatted instanceof Number) {
Number number = (Number) toBeFormatted;
NumberFormat numFormat = context.getNumberFormat(formatString);
return numFormat.format(number.doubleValue());
}
else if (toBeFormatted instanceof Date) {
Date date = (Date) toBeFormatted;
DateFormat dateFormat = context.getDateFormat(formatString);
return dateFormat.format(date);
}
else {
return null;
}
}
public static List sortList(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
Object listObj = args[0];
Object comparatorObj = null;
Object sortDirection = null;
int sortDir = 1;
if (args.length > 1) {
comparatorObj = args[1];
}
if (args.length > 2) {
sortDirection = args[2];
}
if (listObj instanceof NativeJavaObject) {
listObj = ((NativeJavaObject) listObj).unwrap();
}
if (comparatorObj != null && comparatorObj instanceof NativeJavaObject) {
comparatorObj = ((NativeJavaObject) comparatorObj).unwrap();
}
if (sortDirection != null) {
if (sortDirection instanceof NativeJavaObject) {
sortDirection = ((NativeJavaObject) sortDirection).unwrap();
}
if (((String) sortDirection).equalsIgnoreCase("descending") || ((String) sortDirection).equalsIgnoreCase("down") || ((String) sortDirection).equalsIgnoreCase("-")) {
sortDir = -1;
}
}
if (listObj instanceof WGStructEntryList) {
listObj = new ArrayList(((WGStructEntryList) listObj));
}
if (listObj instanceof List) {
List lObj = (List) listObj;
// List of metadata names
if (comparatorObj instanceof List) {
Collections.sort(lObj, new ListComparatorByMetaList((List) comparatorObj, sortDir));
}
// Javascript-Function retrieving the value to sort
else if (comparatorObj instanceof Function) {
Collections.sort(lObj, new JavascriptFunctionComparator((Function) comparatorObj, cx, thisObj));
}
// Single metadata name
else {
Collections.sort(lObj, new ListComparatorByMeta((String) comparatorObj, sortDir));
}
return lObj;
}
else {
return new ArrayList();
}
}
public static List deleteDoublets(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
Object listObj = args[0];
if (listObj == null)
return null;
if (listObj instanceof NativeJavaObject) {
listObj = ((NativeJavaObject) listObj).unwrap();
}
if (listObj instanceof List) {
List lObj = (List) listObj;
java.util.HashSet hObj = new java.util.HashSet(lObj);
lObj.clear();
lObj.addAll(hObj);
return lObj;
}
else {
return null;
}
}
public static Object callAction(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
VarArgParser.Arguments parsedArgs = _callActionVarargs.parse(args);
// Determine action id and action context
TMLContext context = (TMLContext) parsedArgs.get("context");
if (context == null) {
context = fetchInitialContext(cx);
}
String actionID = (String) parsedArgs.get("id");
List actionArgs = new ArrayList(parsedArgs.getOverflowArgs());
// Get the current action, to be able to expand local name and search
// the action to perform in it's database
TMLAction.Locator actionLocator = determineActionLocator(cx, thisObj, context, actionID);
TMLAction action = context.getActionByID(actionLocator.getId(), actionLocator.getDbkey());
if (action == null) {
throw new EvaluatorException("Could not retrieve action for ID '" + actionID + "'");
}
TMLScriptRootScope rootScope = fetchRootScope(cx);
// Call action
Object actionResult;
try {
actionResult = context.callCustomAction(action, actionArgs, rootScope.getData().getUnwrappedGlobalScopeObjects());
}
catch (WGAPIException e) {
throw Context.throwAsScriptRuntimeEx(e);
}
return Context.javaToJS(actionResult, thisObj);
}
/**
* Determines the complete locator of a TML Action (absolute ID, dbkey)
* based on the given actionID and the script environment
*
* @param cx
* The current rhino context
* @param thisObj
* The current this object
* @param context
* The TML Context
* @param actionID
* The given action ID
* @return
*/
protected static TMLAction.Locator determineActionLocator(Context cx, Scriptable thisObj, TMLContext context, String actionID) {
TMLAction.Locator actionLocator = null;
// Retrieve objects that may override the locator information from the current context
TMLAction.Locator currentLocator = currentActionLocator(cx, thisObj);
TMLAction currentAction = currentAction(cx, thisObj);
// A custom action locator was registered
if (currentLocator != null) {
actionLocator = new TMLAction.Locator(currentLocator.getDbkey(), context.resolveDesignReference(actionID, currentLocator.getId()));
}
// An action definition was registered
else if (currentAction != null) {
actionLocator = new TMLAction.Locator(currentAction.getModuleDatabase(), context.resolveDesignReference(actionID, currentAction.getModuleName()));
}
// Use TMLContext base reference information, try to extract dbkey information
else {
actionLocator = new TMLAction.Locator(null, context.resolveDesignReference(actionID));
}
return actionLocator;
}
static TMLAction currentAction(Context cx, Scriptable thisObj) {
// Retrieve action definition of the currently executed script code
TMLAction currentAction = (TMLAction) cx.getThreadLocal(RhinoExpressionEngine.TL_ACTIONDEFINITION);
// When inside the code of a TMLScript object, get locator information
// from stored action definition inside object
if (thisObj != null && thisObj.has(RhinoExpressionEngine.PARAM_ACTIONDEFINITION, thisObj)) {
currentAction = (TMLAction) thisObj.get(RhinoExpressionEngine.PARAM_ACTIONDEFINITION, thisObj);
}
return currentAction;
}
private static TMLAction.Locator currentActionLocator(Context cx, Scriptable thisObj) {
TMLAction.Locator currentActionLocator = (TMLAction.Locator) cx.getThreadLocal(RhinoExpressionEngine.TL_ACTIONLOCATOR);
return currentActionLocator;
}
public static Function loadObjectDefinition(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
VarArgParser.Arguments parsedArgs = _loadObjectDefVarags.parse(args);
TMLContext context = fetchInitialContext(cx);
String actionID = (String) parsedArgs.get("id");
NativeObject currentObject = (NativeObject) parsedArgs.get("currentObject");
// Get the function def (might need to expand local name by the name of
// the current action)
TMLAction.Locator actionLocator = determineActionLocator(cx, currentObject, context, actionID);
TMLAction action;
try {
action = context.getModuleActionByID(actionLocator.getId(), actionLocator.getDbkey());
}
catch (TMLActionException e) {
throw new EvaluatorException("Could not retrieve TMLScript module '" + args[0] + "': " + e.getMessage());
}
if (action == null) {
throw new EvaluatorException("Could not retrieve TMLScript module '" + args[0] + "'");
}
// Fetch runtime and return function object
RhinoExpressionEngineImpl runtime = fetchRuntime(cx);
// Use Context Redirector as scope, so the objects implicit context always directs to the current script's context
ContextRedirector redirector = new ContextRedirector();
// Preserve thread locals
ThreadLocalPreserver preserver = new ThreadLocalPreserver((RhinoContext) cx);
preserver.preserve(RhinoExpressionEngine.TL_ACTIONDEFINITION, action);
preserver.preserve(RhinoExpressionEngine.TL_SCRIPTNAME, "TMLScript-Object " + action.getModuleDatabase() + "/" + action.getModuleName());;
try {
Function func = runtime.getCompiledFunction(action.getCode(), (RhinoContext) cx, redirector);
func.put(RhinoExpressionEngine.PARAM_ACTIONDEFINITION, func, action);
return func;
}
finally {
preserver.restore();
}
}
protected static RhinoExpressionEngineImpl fetchRuntime(Context cx) {
NativeJavaObject runtimeObj = (NativeJavaObject) fetchRootScope(cx).getData().getScopeObject(RhinoExpressionEngineImpl.SCOPEOBJECT_RUNTIME);
return (RhinoExpressionEngineImpl) ((NativeJavaObject) runtimeObj).unwrap();
}
public static TMLContext fetchInitialContext(Context cx) throws JavaScriptException {
Object obj = cx.getThreadLocal(RhinoExpressionEngine.TL_INITIALCONTEXT);
if (!(obj instanceof TMLContext)) {
throw new EvaluatorException("Initial context not available");
}
TMLContext context = (TMLContext) obj;
return context;
}
public static TMLScriptRootScope fetchRootScope(Context cx) throws JavaScriptException {
Object obj = cx.getThreadLocal(RhinoExpressionEngine.TL_ROOTSCOPE);
return (TMLScriptRootScope) obj;
}
public static Scriptable createObject(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
VarArgParser.Arguments parsedArgs = _createObjectVarargs.parse(args);
// Retrieve object definition, either as script or as Function object
Object definition = parsedArgs.get("definition");
Function func;
if (definition instanceof Function) {
func = (Function) args[0];
}
else {
func = loadObjectDefinition(cx, thisObj, args, funObj);
}
// Construct the object
Scriptable obj = func.construct(cx, thisObj, new Object[] {});
Scriptable topLevelScope = ScriptableObject.getTopLevelScope(thisObj);
// Put the action definition to the object, so it "knows" where it's
// definition came from
TMLAction action = (TMLAction) func.get(RhinoExpressionEngine.PARAM_ACTIONDEFINITION, func);
if (action != null) {
obj.put(RhinoExpressionEngine.PARAM_ACTIONDEFINITION, obj, action);
}
// Execute constructor
Object initObj = obj.get("init", obj);
if (initObj != null && initObj instanceof Function) {
((Function) initObj).call(cx, thisObj, obj, new ArrayList(parsedArgs.getOverflowArgs()).toArray());
}
return obj;
}
public static void logException(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
TMLContext context = fetchInitialContext(cx);
// Determine parameters
String msg = null;
Object error = null;
if (args.length == 0) {
context.getlog().error("Unloggable TMLScript error because of too few arguments for logException");
return;
}
else if (args.length == 1) {
msg = "Error in TMLScript";
error = args[0];
}
else {
msg = (String) args[0];
error = args[1];
}
// Determine throwable to log and/or additional message to put out
Throwable throwable = null;
String additionalMsg = null;
if (error instanceof Throwable) {
throwable = (Throwable) error;
}
else if (error instanceof Scriptable) {
Scriptable nativeError = (Scriptable) error;
if (nativeError.has("rhinoException", nativeError)) {
throwable = (RhinoException) ((NativeJavaObject) nativeError.get("rhinoException", nativeError)).unwrap();
}
else if (nativeError.has("javaException", nativeError)) {
throwable = (Throwable) ((NativeJavaObject) nativeError.get("javaException", nativeError)).unwrap();
}
else if (nativeError.has("message", nativeError)) {
additionalMsg = (String) nativeError.get("message", nativeError);
}
else {
additionalMsg = "(scriptable error object without further information: " + nativeError.getClass().getName() + ")";
}
if (nativeError.has("lineNumber", nativeError) && !(throwable instanceof RhinoException)) {
additionalMsg += ". Line number: " + (Integer) nativeError.get("lineNumber", nativeError);
}
}
else {
additionalMsg = "(error object of invalid type: " + error.getClass().getName() + ")";
}
// Try to find job context. If available use the job log to put out error
Logger theLog = context.getlog();
JobContext jobContext = null;
Object jcObj = thisObj.get("jobContext", thisObj);
if (jcObj != null && jcObj instanceof NativeJavaObject) {
jcObj = ((NativeJavaObject) jcObj).unwrap();
if (jcObj instanceof JobContext) {
jobContext = (JobContext) jcObj;
theLog = jobContext.getLog();
}
}
// Put out
if (additionalMsg != null) {
msg += ": " + additionalMsg;
}
if (throwable != null) {
if (throwable instanceof RhinoException) {
RhinoException rhinoEx = (RhinoException) throwable;
if (rhinoEx.lineNumber() != 0) {
msg += ". Line Number " + rhinoEx.lineNumber();
}
if (rhinoEx.lineSource() != null) {
msg += ". Line source: " + rhinoEx.lineSource();
}
}
theLog.error(msg, throwable);
context.addwarning(msg + ". Exception message: " + throwable.getMessage() + ". Exception type: " + throwable.getClass().getName());
}
else {
theLog.error(msg);
context.addwarning(msg);
}
}
public static List getLookupKeys(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException {
VarArgParser.Arguments varArgs = _getLookupKeysVarargs.parse(args);
if (!varArgs.has("table")) {
throw new EvaluatorException("Function getLookupKeys() needs a lookup table as argument");
}
Map table = (Map) varArgs.get("table");
return new ArrayList(table.keySet());
}
public static String serializeObject(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
Object obj = args[0];
if (!(obj instanceof NativeJavaObject)) {
throw new EvaluatorException("Object to serialize must be a java object");
}
obj = ((NativeJavaObject) obj).unwrap();
try {
TMLContext context = fetchInitialContext(cx);
String xml = XStreamUtils.XSTREAM_CLONING.toXML(obj);
byte[] zipped = Zipper.zip(xml);
String encrypted = context.getwgacore().getDesEncrypter().encrypt(zipped);
return encrypted;
}
catch (UnsupportedEncodingException e) {
throw Context.throwAsScriptRuntimeEx(e);
}
}
public static Object deserializeObject(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
TMLContext context = fetchInitialContext(cx);
String encrypted = String.valueOf(args[0]);
byte[] zipped = context.getwgacore().getDesEncrypter().decrypt(encrypted);
String xml = Zipper.unzip(zipped);
Object obj = XStreamUtils.XSTREAM_CLONING.fromXML(xml);
return obj;
}
public static Object scoped(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
try {
Arguments varargs = _scopedVarargs.parse(args);
String str = (String) varargs.get("value");
TMLContext context = fetchInitialContext(cx);
if (varargs.has("scope")) {
String scope = (String) varargs.get("scope");
return context.getScopedString(str, scope);
}
else {
if (!context.iswebenvironment()) {
return str;
}
return context.gettag().getScopedString(str);
}
}
catch (Exception e) {
throw new WrappedException(e);
}
}
public static Plugin plugin(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws WGException {
if (args.length != 1) {
throw new EvaluatorException("Method WGA.plugin() needs a single parameter, either string or database");
}
Object arg1 = args[0];
if (arg1 instanceof Wrapper) {
arg1 = ((Wrapper) arg1).unwrap();
}
if (arg1 instanceof String) {
TMLContext con = fetchInitialContext(Context.getCurrentContext());
WGAPlugin plugin = con.getwgacore().getPluginSet().getPluginByUniqueName((String) arg1);
if (plugin == null || !plugin.isActive() || !plugin.isValid()) {
return null;
}
WGDatabase db = con.db(plugin.buildDatabaseKey());
if (db != null) {
return new Plugin(db);
}
else {
return null;
}
}
else if (arg1 instanceof WGDatabase) {
return new Plugin((WGDatabase) arg1);
}
else {
throw new EvaluatorException("Parameter of method WGA.plugin() must be either a plugin unique name (type String) or a database (type WGDatabase)");
}
}
public static Lucene lucene(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
TMLContext tmlCx;
if (args.length == 0) {
tmlCx = fetchInitialContext(cx);
}
else if (args.length == 1) {
Object arg = args[0];
if (arg instanceof Wrapper) {
arg = ((Wrapper) arg).unwrap();
}
if (!(arg instanceof TMLContext)) {
throw new EvaluatorException("Method WGA.lucene() needs either no or a single TMLContext parameter");
}
tmlCx = (TMLContext) arg;
}
else {
throw new EvaluatorException("Method WGA.lucene() needs either no or a single TMLContext parameter");
}
return new Lucene(tmlCx);
}
public static Date parseDate(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws WGException, JavaScriptException, ParseException {
if (args.length != 2) {
throw new EvaluatorException("Method WGA.parseDate() needs two string parameters");
}
return fetchInitialContext(cx).parsedate(String.valueOf(args[0]), String.valueOf(args[1]));
}
public static Date createDate(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws WGException {
boolean includeMillis = true;
if (args.length >= 1 && args[0] instanceof Boolean) {
includeMillis = ((Boolean) args[0]).booleanValue();
}
return fetchInitialContext(cx).createdate(includeMillis);
}
public static TMLForm createForm(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws WGException {
if (args.length != 1) {
throw new EvaluatorException("Method WGA.createForm() needs an FormInfo object as parameter");
}
Object arg = args[0];
if (arg instanceof Wrapper) {
arg = ((Wrapper) arg).unwrap();
}
if (!(arg instanceof FormInfo)) {
throw new EvaluatorException("Method WGA.createForm() needs an FormInfo object as parameter");
}
FormInfo formInfo = (FormInfo) arg;
return fetchInitialContext(cx).createform(formInfo);
}
public static FormInfo createFormInfo(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws WGException {
if (args.length != 1) {
throw new EvaluatorException("Method WGA.createFormInfo() needs a string as parameter");
}
String id = String.valueOf(args[0]);
return fetchInitialContext(cx).createforminfo(id);
}
public static ImageScaler createImageScaler(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws WGException, JavaScriptException, ModuleInstantiationException, IOException {
if (args.length != 1) {
throw new EvaluatorException("Method WGA.createImageScaler() needs either a file or an input stream as parameter");
}
Object arg = args[0];
if (arg instanceof Wrapper) {
arg = ((Wrapper) arg).unwrap();
}
if (arg instanceof File) {
return fetchInitialContext(cx).createimagescaler((File) arg);
}
else if (arg instanceof InputStream) {
return fetchInitialContext(cx).createimagescaler((InputStream) arg);
}
else {
throw new EvaluatorException("Method WGA.createImageScaler() needs either a file or an input stream as parameter");
}
}
public static List createList(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
if (args.length == 0) {
return fetchInitialContext(cx).createlist();
}
if (args.length == 1) {
Object arg = args[0];
if (arg instanceof NativeArray) {
arg = cx.jsToJava(arg, Object[].class);
}
if (!(arg instanceof Object[])) {
throw new EvaluatorException("Method WGA.createList() needs either no parameters, an array or two string parameters");
}
return fetchInitialContext(cx).createlist((Object[]) arg);
}
else if (args.length == 2) {
Object arg1 = args[0];
Object arg2 = args[1];
return fetchInitialContext(cx).createlist(String.valueOf(arg1), String.valueOf(arg2));
}
else {
throw new EvaluatorException("Method WGA.createList() needs either no parameters, an array or two string parameters");
}
}
public static Map createLookupTable(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) {
return fetchInitialContext(cx).createlookuptable();
}
public static Mail createMail(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, TMLException, UnsupportedEncodingException {
if (args.length == 0) {
return fetchInitialContext(cx).createmail();
}
else if (args.length == 3) {
Object arg1 = args[0];
Object arg2 = args[1];
Object arg3 = args[2];
return fetchInitialContext(cx).createmail(String.valueOf(arg1), String.valueOf(arg2), String.valueOf(arg3));
}
else {
throw new EvaluatorException("Method WGA.createMail) needs either no parameters or three string parameters");
}
}
public static Number parseNumber(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, ParseException {
if (args.length != 2) {
throw new EvaluatorException("Method WGA.parseNumber() needs two string parameters");
}
Number num = fetchInitialContext(cx).getNumberFormat(String.valueOf(args[1])).parse(String.valueOf(args[0]));
return num;
}
public static WGDatabase db(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, WGException {
if (args.length != 1) {
throw new EvaluatorException("Method WGA.db() needs one string parameter");
}
return fetchInitialContext(cx).db(String.valueOf(args[0]));
}
public static WGHierarchicalDatabase hdb(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, WGException {
if (args.length != 1) {
throw new EvaluatorException("Method WGA.hdb() needs one string parameter");
}
return fetchInitialContext(cx).hdb(String.valueOf(args[0]));
}
public static String encode(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException {
if (args.length != 2) {
throw new EvaluatorException("Method WGA.encode() needs a string and an object parameter");
}
return fetchInitialContext(cx).encode(String.valueOf(args[0]), args[1]);
}
@Override
public void setParentScope(Scriptable m) {
super.setParentScope(m);
// We need to set the parent scope of scriptable subobjects too
_master.setParentScope(m);
}
public static URLBuilder urlBuilder(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, WGAPIException, MalformedURLException, UnsupportedEncodingException {
TMLContext tmlContext = fetchInitialContext(cx);
URL wgaUrl = new URL((String) tmlContext.meta("request", "absolutewgaurl"));
String baseURL;
if (args.length >= 1) {
baseURL = String.valueOf(args[0]);
}
else {
baseURL = (String) tmlContext.meta("request", "url");
}
URL url = new URL(wgaUrl, baseURL);
return new URLBuilder(tmlContext, url);
}
public static void redirectTo(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, WGAPIException, IOException {
TMLContext tmlContext = fetchInitialContext(cx);
if (args.length < 1) {
throw new EvaluatorException("Method WGA.redirectTo() needs a string parameter");
}
Object arg = args[0];
if (arg instanceof Wrapper) {
arg = ((Wrapper) arg).unwrap();
}
String url = String.valueOf(arg);
tmlContext.redirectto(url);
}
public static List<String> buildOptions(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, WGAPIException, IOException {
Arguments parsedArgs = _buildOptionsVarargs.parse(args);
Iterable<WGContent> contents = (Iterable<WGContent>) parsedArgs.get("contents");
String titleExpr = (String) parsedArgs.get("title");
TMLContext context = fetchInitialContext(cx);
RhinoExpressionEngineImpl runtime = fetchRuntime(cx);
List<String> options = new ArrayList<String>();
if (parsedArgs.has("emptyTitle")) {
options.add(String.valueOf(parsedArgs.get("emptyTitle")) + "|" + TMLForm.RELATION_NULLPLACE_HOLDER);
}
for (WGContent content : contents) {
String title = content.getTitle();
if (titleExpr != null) {
TMLContext conContext = context.context(content);
ExpressionResult result = runtime.evaluateExpression(titleExpr, conContext, ExpressionEngine.TYPE_EXPRESSION, null);
if (!result.isError()) {
title = String.valueOf(result.getResult());
}
}
options.add(title + "|" + content.getStructKey());
}
return options;
}
public static Date dateOnly(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, WGAPIException, IOException {
Arguments arguments = _singleDateParam.parse(args);
Date date = (Date) arguments.get("date");
return fetchInitialContext(cx).dateonly(date);
}
public static Date timeOnly(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, WGAPIException, IOException {
Arguments arguments = _singleDateParam.parse(args);
Date date = (Date) arguments.get("date");
return fetchInitialContext(cx).timeonly(date);
}
public static Calendar createCalendar(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, WGAPIException, IOException {
Arguments arguments = _singleDateParam.parse(args);
Date date = (Date) arguments.get("date");
return fetchInitialContext(cx).createcalendar(date);
}
public static Design design(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, IOException, WGException {
Arguments arguments = _designVarargs.parse(args);
return new Design(arguments.get("ref"));
}
public static Cookie createCookie(Context cx, Scriptable thisObj, java.lang.Object[] args, Function funObj) throws JavaScriptException, FormattingException, IOException, WGException {
Arguments arguments = _createCookieVarargs.parse(args);
return new Cookie((String) arguments.get("name"), (String) arguments.get("value"));
}
}