org.seasar.mayaa.impl.cycle.script.rhino.RhinoUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.seasar.mayaa.impl.cycle.script.rhino.RhinoUtil.java

Source

/*
 * Copyright 2004-2012 the Seasar Foundation and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.seasar.mayaa.impl.cycle.script.rhino;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.JavaAdapter;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.Undefined;
import org.mozilla.javascript.WrapFactory;
import org.mozilla.javascript.WrappedException;
import org.seasar.mayaa.cycle.ServiceCycle;
import org.seasar.mayaa.cycle.scope.AttributeScope;
import org.seasar.mayaa.impl.cycle.CycleUtil;
import org.seasar.mayaa.impl.util.StringUtil;

/**
 * Rhino??????????
 *
 * @author Masataka Kurihara (Gluegent, Inc.)
 * @author Koji Suga (Gluegent Inc.)
 */
public class RhinoUtil {

    private static final Log LOG = LogFactory.getLog(RhinoUtil.class);

    /** ???? */
    private static final Class[] VOID_ARGS_CLASS = new Class[0];

    private RhinoUtil() {
        // no instantiation.
    }

    /**
     * ???Context????
     * ??ScriptEnvironment?WrapFactory???Context????
     * Rhino???Context.enter()??????
     * ???????try {} finally {} ?? Context.exit() 
     * ???????
     *
     * @return ???Context
     */
    public static Context enter() {
        Context cx = Context.enter();
        WrapFactory factory = ScriptEnvironmentImpl.getWrapFactory();
        if (factory != null) {
            cx.setWrapFactory(factory);
        }
        return cx;
    }

    /**
     * ???????
     *
     * @return ???
     */
    public static Scriptable getScope() {
        ServiceCycle cycle = CycleUtil.getServiceCycle();
        AttributeScope attrs = cycle.getPageScope();
        if (attrs instanceof PageAttributeScope) {
            attrs = (AttributeScope) attrs.getAttribute(PageAttributeScope.KEY_CURRENT);
        }
        if (attrs instanceof Scriptable) {
            return (Scriptable) attrs;
        }
        throw new IllegalStateException("script scope does not get");
    }

    /**
     * Rhino??Java????????
     * ?????3
     * <ul><li>boolean???JavaScript??undefined???=true?
     * ????????</li>
     * <li>??void?????undefined???null?</li>
     * <li>??????????? (Rhino?Double??????)</li>
     * </ul>
     *
     * @param cx ??
     * @param expectedClass ?
     * @param jsRet Rhino?
     * @return jsRetJava????????
     */
    public static Object convertResult(Context cx, Class expectedClass, Object jsRet) {
        Object ret;
        if (expectedClass.equals(Boolean.TYPE)) {
            // workaround to ECMA1.3
            ret = JavaAdapter.convertResult(jsRet, Object.class);
        } else if (expectedClass == Void.class || expectedClass == void.class || jsRet == Undefined.instance) {
            ret = null;
        } else {
            if (isNumber(expectedClass, jsRet)) {
                ret = jsRet;
            } else {
                ret = JavaAdapter.convertResult(jsRet, expectedClass);
            }
        }

        return ret;
    }

    /**
     * Rhino????wrap?????????
     * ?throw????wrap?????RuntimeException?????
     * RuntimeException?wrap??throw???
     *
     * @param e Rhino???
     */
    public static void removeWrappedException(WrappedException e) {
        Throwable t = e.getWrappedException();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        }
        throw new RuntimeException(t);
    }

    /**
     * Rhino????????????????
     * ??Number, Object??????????????
     * ?????
     *
     * @param expectedClass ?
     * @param jsRet Rhino??
     * @return ?????true
     */
    public static boolean isNumber(Class expectedClass, Object jsRet) {
        if (jsRet != null && expectedClass != null) {
            Class originalClass = jsRet.getClass();
            if (Number.class.isAssignableFrom(originalClass)) {
                if (Object.class.equals(expectedClass) || Number.class.equals(expectedClass)
                        || originalClass.equals(expectedClass)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * propertyName???????
     * ??????public?getter?public???
     * ????JavaBean????????
     * ???????????
     *
     * @param bean ???
     * @param propertyName ??
     * @return ?
     * @throws RuntimeException Reflection????
     *      IllegalAccessException, InvocationTargetException, NoSuchMethodException
     *      cause??RuntimeException
     */
    public static Object getSimpleProperty(Object bean, String propertyName) {
        Throwable noSuchMethod;
        try {
            return getWithGetterMethod(bean, propertyName);
        } catch (NoSuchMethodException e) {
            // try field
            noSuchMethod = e;
        }
        Object result = getFromPublicField(bean, propertyName);
        if (result != null) {
            return result;
        }

        throw new RuntimeException(noSuchMethod);
    }

    /**
     * ????????
     *
     * @param propertyName ??
     * @return ??????
     */
    protected static String capitalizePropertyName(String propertyName) {
        if (propertyName.length() == 0) {
            return propertyName;
        }

        char chars[] = propertyName.toCharArray();
        chars[0] = Character.toUpperCase(chars[0]);
        return new String(chars);
    }

    /**
     * getter??????
     * JavaBean????????
     *
     * @param bean ?
     * @param propertyName ??
     * @return ?????????null
     * @throws NoSuchMethodException getter??????
     */
    protected static Object getWithGetterMethod(Object bean, String propertyName) throws NoSuchMethodException {
        Class beanClass = bean.getClass();
        String baseName = capitalizePropertyName(propertyName);
        Method getter = null;
        try {
            getter = beanClass.getMethod("get" + baseName, VOID_ARGS_CLASS);
        } catch (NoSuchMethodException ignore) {
            // try boolean
        }
        if (getter == null) {
            try {
                // TODO Method
                Method booleanGetter = beanClass.getMethod("is" + baseName, VOID_ARGS_CLASS);
                if (booleanGetter != null) {
                    Class returnType = booleanGetter.getReturnType();
                    if (returnType.equals(Boolean.class) || returnType.equals(Boolean.TYPE)) {
                        getter = booleanGetter;
                    }
                }
            } catch (NoSuchMethodException ignore) {
                // throw new exception for "getXxx"
            }
        }
        if (getter == null || Modifier.isPublic(getter.getModifiers()) == false) {
            throw new NoSuchMethodException(beanClass.toString() + ".get" + baseName + "()");
        }

        if (getter.isAccessible() == false) {
            getter.setAccessible(true);
        }
        try {
            return getter.invoke(bean, null);
        } catch (IllegalAccessException e) {
            LOG.debug(StringUtil.getMessage(RhinoUtil.class, 1, propertyName, beanClass.getName()));
        } catch (InvocationTargetException e) {
            LOG.debug(StringUtil.getMessage(RhinoUtil.class, 1, propertyName, beanClass.getName()));
        }
        return null;
    }

    /**
     * public??????
     *
     * @param bean 
     * @param propertyName ??
     * @return ?????null
     */
    protected static Object getFromPublicField(Object bean, String propertyName) {
        try {
            // TODO Field
            Class beanClass = bean.getClass();
            Field field = beanClass.getField(propertyName);
            if (Modifier.isPublic(field.getModifiers())) {
                if (field.isAccessible() == false) {
                    field.setAccessible(true);
                }
                return field.get(bean);
            }
        } catch (SecurityException ignore) {
            // no-op
        } catch (NoSuchFieldException ignore) {
            // no-op
        } catch (IllegalArgumentException ignore) {
            // no-op
        } catch (IllegalAccessException eignore) {
            // no-op
        }

        return null;
    }

    /**
     * Rhino????
     * @return Rhino??
     */
    public static String getRhinoVersion() {
        return Context.getCurrentContext().getImplementationVersion();
    }

    /*
    public static class NativeEmpty extends NativeJavaObject {
        
    private static final long serialVersionUID = 7282176381199691056L;
        
    public static final NativeEmpty instance = new NativeEmpty();
        
    private NativeEmpty() {
        // singleton
    }
        
    public String getClassName() {
        return "undefined";
    }
        
    public String toString() {
        return "";
    }
    }
    */

}