Java tutorial
/** * Copyright (c) 1997-2013, www.tinygroup.org (luo_guo@icloud.com). * <p/> * Licensed under the GPL, Version 3.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * <p/> * http://www.gnu.org/licenses/gpl.html * <p/> * 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.tinygroup.template.rumtime; import org.apache.commons.beanutils.MethodUtils; import org.apache.commons.beanutils.PropertyUtilsBean; import org.apache.commons.lang.StringUtils; import org.tinygroup.beancontainer.BeanContainer; import org.tinygroup.beancontainer.BeanContainerFactory; import org.tinygroup.commons.tools.ArrayUtil; import org.tinygroup.commons.tools.Enumerator; import org.tinygroup.context.Context; import org.tinygroup.template.*; import java.beans.PropertyDescriptor; import java.lang.reflect.*; import java.math.BigDecimal; import java.net.URI; import java.util.*; /** * ?? * Created by luoguo on 2014/6/4. */ public final class TemplateUtil { private static Map<Class, Map<String, Method>> methodCache = new HashMap<Class, Map<String, Method>>(); private static Map<Class, Map<String, Field>> fieldCache = new HashMap<Class, Map<String, Field>>(); private static PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean(); private static String[] tabCache = new String[31]; private static boolean safeVariable = false; private static BeanContainer<?> container = BeanContainerFactory .getBeanContainer(TemplateUtil.class.getClassLoader()); static { tabCache[0] = ""; for (int i = 1; i < tabCache.length; i++) { tabCache[i] = String.format("%" + i * 4 + "s", ""); } } private TemplateUtil() { } public static boolean isSafeVariable() { return safeVariable; } public static void setSafeVariable(boolean safeVariable) { TemplateUtil.safeVariable = safeVariable; } /** * ? * * @param object * @param name * @return * @throws TemplateException */ public static Object getAttribute(Object object, Object name) throws TemplateException { try { if (object instanceof Map) { Object value = ((Map) object).get(name); if (value != null) { return value; } } String fieldName = name.toString(); Map<String, Method> stringMethodMap = methodCache.get(object.getClass()); Method method = null; if (stringMethodMap != null) { method = stringMethodMap.get(fieldName); } if (method == null) { PropertyDescriptor descriptor = propertyUtilsBean.getPropertyDescriptor(object, fieldName); if (descriptor != null && descriptor.getReadMethod() != null) { method = object.getClass().getMethod(descriptor.getReadMethod().getName()); method.setAccessible(true); if (stringMethodMap == null) { stringMethodMap = new HashMap<String, Method>(); methodCache.put(object.getClass(), stringMethodMap); } stringMethodMap.put(fieldName, method); } } if (method != null) { return method.invoke(object); } Map<String, Field> stringFieldMap = fieldCache.get(fieldName); Field field = null; if (stringFieldMap != null) { field = stringFieldMap.get(fieldName); } if (field == null) { field = object.getClass().getField(fieldName); if (field != null) { if ((field.getModifiers() & Modifier.PUBLIC) == Modifier.PUBLIC) { field.setAccessible(true); if (stringFieldMap == null) { stringFieldMap = new HashMap<String, Field>(); fieldCache.put(object.getClass(), stringFieldMap); } stringFieldMap.put(fieldName, field); } else { field = null; } } } if (field != null) { return field.get(object); } throw new TemplateException( object.getClass().getName() + "?" + fieldName + "?"); } catch (Exception e) { throw new TemplateException(e); } } public static Object sp(Object object, Object name) throws TemplateException { if (object != null) { try { return getAttribute(object, name); } catch (TemplateException e) { if (e.getCause().getClass() == NullPointerException.class || e.getCause().getClass() == NoSuchFieldException.class || e.getMessage().indexOf("?") > 0) { return null; } else { throw e; } } } return null; } /** * ? * * @param i18nVistor * @param key * @return */ public static String getI18n(I18nVisitor i18nVistor, TemplateContext context, String key) { if (key == null) { return null; } if (i18nVistor == null) { return key; } else { return i18nVistor.getI18nMessage(context, key); } } /** * * * @param object * @param methodName * @param parameters * @return * @throws TemplateException */ public static Object callMethod(Template template, TemplateContext context, Object object, String methodName, Object... parameters) throws TemplateException { try { TemplateFunction function = template.getTemplateEngine().getTemplateFunction(object, methodName); if (function != null) { return executeExtendFunction(template, context, object, function, parameters); } else { //? return executeClassMethod(object, methodName, parameters); } } catch (Exception e) { //?? if (e instanceof InvocationTargetException) { InvocationTargetException e1 = (InvocationTargetException) e; throw new TemplateException(e1.getTargetException()); } throw new TemplateException(e); } } public static Object executeClassMethod(Object object, String methodName, Object[] parameters) throws Exception { Method method = getMethodByName(object, methodName, parameters); //? if (method != null) { return method.invoke(object, parameters); } if (object instanceof StaticClassOperator) { return ((StaticClassOperator) object).invokeStaticMethod(methodName, parameters); } else { return MethodUtils.invokeMethod(object, methodName, parameters); } } private static Method getMethodByName(Object object, String methodName, Object[] parameters) { Method method = null; Map<String, Method> stringMethodMap = methodCache.get(object.getClass()); if (stringMethodMap != null) { method = stringMethodMap.get(methodName); } if (method == null) { List<Method> methods = getMethodList(object.getClass(), methodName); if (methods.size() == 1) { method = methods.get(0); if (stringMethodMap == null) { stringMethodMap = new HashMap<String, Method>(); methodCache.put(object.getClass(), stringMethodMap); } stringMethodMap.put(methodName, method); } else { for (Method method1 : methods) { if (method1.getParameterTypes().length != parameters.length) { continue; } int count = 0; for (int i = 0; i < method1.getParameterTypes().length; i++) { if (parameters[i] == null || parameters[i].getClass().equals(method1.getParameterTypes()[i].getClass())) { count++; } } if (count == method1.getParameterTypes().length) { return method1; } } } } return method; } private static List<Method> getMethodList(Class clz, String methodName) { List<Method> methods = new ArrayList<Method>(); for (Method method : clz.getMethods()) { if (method.getName().equals(methodName)) { methods.add(method); } } return methods; } private static Object executeExtendFunction(Template template, TemplateContext context, Object object, TemplateFunction function, Object[] parameters) throws TemplateException { Object[] newParameters = new Object[(parameters == null ? 1 : parameters.length) + 1]; newParameters[0] = object; if (parameters != null && parameters.length > 0) { System.arraycopy(parameters, 0, newParameters, 1, parameters.length); } return function.execute(template, context, newParameters); } /** * * * @param object * @param methodName * @param parameters * @return * @throws TemplateException */ public static Object safeCallMethod(Template template, TemplateContext context, Object object, String methodName, Object... parameters) throws TemplateException { if (object != null) { try { return callMethod(template, context, object, methodName, parameters); } catch (TemplateException e) { if (e.getCause().getClass() == NoSuchMethodException.class) { return null; } else { throw e; } } } return null; } public static Class<?>[] getParameterTypes(Class clazz, String methodName) throws TemplateException { for (Method method : clazz.getMethods()) { if (method.getName().equals(methodName)) { return method.getParameterTypes(); } } throw new TemplateException(clazz.getName() + "?:" + methodName); } /** * ? * * @param context * @param key * @return */ public static Object getValueFromContext(Context context, Object key) { return context.get(key.toString()); } /** * Bean * @param key * @return */ public static Object getValueFromBean(Object key) { try { return container.getBean(key.toString()); } catch (Exception e) { return null; } } /** * ?? * @param context * @param key * @return */ public static Object getVariableValue(Context context, Object key) { Object value = getValueFromContext(context, key); if (value == null) { value = getValueFromBean(key); } return value; } /** * ??? * * @param currentPath * @param newPath * @return */ public static String getPath(String currentPath, String newPath) { String path = newPath; URI uri = URI.create(currentPath); path = path.replaceAll("[\\\\]", "/"); URI newUri = uri.resolve(path); return newUri.getPath(); } public static void dent(TemplateContext context) { Boolean compactMode = context.get("$compactMode"); //? if (compactMode != null && compactMode) { return; } Integer tab = context.get("$tab"); if (tab != null) { context.put("$tab", tab + 1); } else { context.put("$tab", 1); } } public static void indent(TemplateContext context) { //? Boolean compactMode = context.get("$compactMode"); if (compactMode != null && compactMode) { return; } Integer tab = context.get("$tab"); if (tab != null) { context.put("$tab", tab - 1); } else { context.put("$tab", 0); } } public static String getBlanks(TemplateContext context) { //? Boolean compactMode = context.get("$compactMode"); if (compactMode != null && compactMode) { return null; } Integer tab = context.get("$tab"); if (tab != null) { if (tab < tabCache.length) { return tabCache[tab]; } else { return tabCache[tabCache.length - 1]; } } return null; } /** * Html * * @param object * @return */ public static String escapeHtml(Object object) { if (object == null) { return null; } return StringUtils.replaceEach(object.toString(), new String[] { "&", "\"", "<", ">" }, new String[] { "&", """, "<", ">" }); } /** * ?? * * @param object * @return */ public static boolean getBooleanValue(Object object) { if (object == null) { return false; } if (object.getClass() == Boolean.class) { return ((Boolean) object).booleanValue(); } else if (object.getClass() == String.class) { return ((String) object).length() > 0; } else if (object instanceof Collection) { return ((Collection) object).size() > 0; } else if (object.getClass().isArray()) { return ArrayUtil.arrayLength(object) > 0; } else if (object instanceof Iterator) { return ((Iterator) object).hasNext(); } else if (object instanceof Enumerator) { Enumerator e = (Enumerator) object; return e.hasMoreElements(); } else if (object instanceof Map) { Map e = (Map) object; return e.size() > 0; } return true; } /** * * * @param object * @param indexObject * @return * @throws Exception */ public static Object getSafeArrayValue(Object object, Object indexObject) throws TemplateException { if (object == null) { return null; } else { try { return getArrayValue(object, indexObject); } catch (Exception e) { return null; } } } public static Object getArrayValue(Object object, Object indexObject) throws TemplateException { int index; try { if (object instanceof Map) { Map map = (Map) object; return map.get(indexObject); } if (indexObject instanceof Integer) { index = ((Integer) indexObject).intValue(); } else if (indexObject instanceof Long) { index = ((Long) indexObject).intValue(); } else if (indexObject instanceof Double) { index = ((Double) indexObject).intValue(); } else if (indexObject instanceof Float) { index = ((Float) indexObject).intValue(); } else if (indexObject instanceof Byte) { index = ((Byte) indexObject).intValue(); } else if (indexObject instanceof BigDecimal) { index = ((BigDecimal) indexObject).intValue(); } else { index = Integer.parseInt(indexObject.toString()); } if (object.getClass().isArray()) { return Array.get(object, index); } else if (object instanceof Collection) { Collection c = (Collection) object; int i = 0; Iterator it = c.iterator(); while (i < c.size()) { Object o = it.next(); if (i == index) { return o; } i++; } return null; } else { String o = object.toString(); return o.charAt(index); } } catch (Exception e) { throw new IllegalArgumentException(String.format("%s%s??", object.getClass().getName(), indexObject.toString()), e); } //throw new TemplateException(object.getClass().getName() + "??"); } /** * ? * @param path * @param locale * @return */ public static String getLocalePath(String path, Locale locale) { if (locale != null) { int pos = path.lastIndexOf("."); String localePath = path.substring(0, pos) + "_" + locale.getLanguage() + "_" + locale.getCountry() + path.substring(pos); return localePath; } return path; } /** * * @param str ?? * @param stripChars ?<code>null</code> * @return */ public static String trimStart(String str, String[] stripChars) { if (stripChars == null || stripChars.length == 0) return str; int strLen; if (str != null && (strLen = str.length()) != 0) { int start = 0; while (start < strLen && isStripChar(str.charAt(start), stripChars)) { ++start; } return str.substring(start); } return str; } /** * * @param str ?? * @param stripChars ?<code>null</code> * @return */ public static String trimEnd(String str, String[] stripChars) { int end; if (str != null && (end = str.length()) != 0) { while (end != 0 && isStripChar(str.charAt(end - 1), stripChars)) { --end; } return str.substring(0, end); } return str; } /** * ?? * @param charStr ? * @param stripChars ? * @return */ private static boolean isStripChar(char charStr, String[] stripChars) { for (int i = 0; i < stripChars.length; i++) { if (stripChars[i].indexOf(charStr) != -1) return true; } return false; } }