Java tutorial
/* * 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 ""; } } */ }