/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program 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. * This program 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 this program; if not, see http://www.gnu.org/licenses/ */ package com.bc.ceres.jai.js; import org.mozilla.javascript.Context; import org.mozilla.javascript.Function; import org.mozilla.javascript.Scriptable; import org.mozilla.javascript.ScriptableObject; import org.mozilla.javascript.WrappedException; import javax.media.jai.JAI; import javax.media.jai.OperationDescriptor; import javax.media.jai.ParameterBlockJAI; import javax.media.jai.ParameterListDescriptor; public class JsJaiFunction extends ScriptableObject implements Function { private final OperationDescriptor operationDescriptor; private final String name; public JsJaiFunction(OperationDescriptor operationDescriptor) { super(); this.operationDescriptor = operationDescriptor; this.name = operationDescriptor.getName().toLowerCase(); } public JsJaiFunction(Scriptable scope, Scriptable prototype, OperationDescriptor operationDescriptor) { super(scope, prototype); this.operationDescriptor = operationDescriptor; this.name = operationDescriptor.getName().toLowerCase(); } public OperationDescriptor getOperationDescriptor() { return operationDescriptor; } public String getClassName() { return name; } public Scriptable construct(Context context, Scriptable scope, Object[] args) { return new JsJaiFunction(operationDescriptor); } public Object call(Context context, Scriptable scope, Scriptable thisObj, Object[] args) { final ParameterBlockJAI pb = new ParameterBlockJAI(operationDescriptor); final int numSources = operationDescriptor.getNumSources(); final ParameterListDescriptor pld = operationDescriptor.getParameterListDescriptor("rendered"); final int numParams = pld.getNumParameters(); final String[] paramNames = pld.getParamNames(); final Class[] paramTypes = pld.getParamClasses(); try { for (int i = 0; i < numSources; i++) { if (i < args.length) { pb.addSource(args[i]); } else { final String[] sourceNames = operationDescriptor.getSourceNames(); throw new IllegalArgumentException("Missing argument #" + (i + 1) + " (" + sourceNames[i] + ")"); } } for (int i = 0; i < numParams; i++) { final String paramName = paramNames[i]; final Class paramType = paramTypes[i]; final Object paramValue; final int j = numSources + i; if (j < args.length) { paramValue = convertJsToJaiValue(args[j], paramType); } else { paramValue = pld.getParamDefaultValue(paramName); if (paramValue == ParameterListDescriptor.NO_PARAMETER_DEFAULT) { throw new IllegalArgumentException("Missing argument #" + (j + 1) + " (" + paramName + ")"); } } pb.setParameter(paramName, paramValue); } return JAI.create(getClassName(), pb); } catch (IllegalArgumentException t) { throw new WrappedException(t); } } private Object convertJsToJaiValue(Object arg, Class paramType) { if (Number.class.isAssignableFrom(paramType)) { if (paramType == Byte.class) { return (byte) Context.toNumber(arg); } else if (paramType == Short.class) { return (short) Context.toNumber(arg); } else if (paramType == Integer.class) { return (int) Context.toNumber(arg); } else if (paramType == Long.class) { return (long) Context.toNumber(arg); } else if (paramType == Float.class) { return (float) Context.toNumber(arg); } else { return Context.toNumber(arg); } } else if (Boolean.class.isAssignableFrom(paramType)) { return Context.toBoolean(arg); } else if (String.class.isAssignableFrom(paramType)) { return Context.toString(arg); } else { return Context.jsToJava(arg, paramType); } } @Override public Object getDefaultValue(Class aClass) { if (aClass == String.class) { return "[" + getClassName() + "]"; } else if (aClass == Boolean.class) { return false; } else if (aClass == Number.class) { return 0; } else if (aClass == Scriptable.class) { return this; } else { return null; } } }