/* MiscUtil.java Purpose: Description: History: 2012/4/12 Created by dennis Copyright (C) 2011 Potix Corporation. All Rights Reserved. */ package org.zkoss.bind.impl; import java.lang.reflect.Method; import org.zkoss.lang.Classes; import org.zkoss.lang.Library; import org.zkoss.util.resource.Location; import org.zkoss.zk.ui.AbstractComponent; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.UiException; import org.zkoss.zk.ui.metainfo.Annotation; /** * internal use only misc util * * @author dennis * */ public class MiscUtil { public static String toSimpleMethodSignature(Method method) { // only keep the method name and parameter type StringBuilder sb = new StringBuilder(); sb.append(method.getName() + "("); Class<?>[] params = method.getParameterTypes(); for (int j = 0; j < params.length; j++) { sb.append(getTypeName(params[j])); if (j < (params.length - 1)) sb.append(","); } sb.append(")"); return sb.toString(); } @SuppressWarnings("rawtypes") static String getTypeName(Class type) { if (type.isArray()) { try { Class cl = type; int dimensions = 0; while (cl.isArray()) { dimensions++; cl = cl.getComponentType(); } StringBuilder sb = new StringBuilder(); sb.append(cl.getName()); for (int i = 0; i < dimensions; i++) { sb.append("[]"); } return sb.toString(); } catch (Throwable e) { /* FALLTHRU */ } } return type.getName(); } @SuppressWarnings("unchecked") public static <T> T newInstanceFromProperty(String key, String def, Class<T> type) { String clz = Library.getProperty(key, def); if (clz != null) { final Object v; try { v = Classes.newInstance(Classes.getContextClassLoader(type).loadClass(clz), null); } catch (Exception ex) { throw UiException.Aide.wrap(ex); } if (!type.isAssignableFrom(v.getClass())) throw new UiException(type + " must be implemented by " + v); return (T) v; } return null; } public static String formatLocationMessage(String message, Object obj) { if (obj == null) return message; if (obj instanceof Component) { return formatLocationMessage(message, (Component) obj); } else if (obj instanceof Annotation) { return formatLocationMessage(message, (Annotation) obj); } else if (obj instanceof Location) { return formatLocationMessage(message, (Location) obj); } else { return formatLocationMessage(message, (Location) null); } } public static String formatLocationMessage(String message, Component comp) { if (comp == null) return message; return formatLocationMessage(message, toComponentLocation(comp), false); } public static String formatLocationMessage(String message, Annotation anno) { if (anno == null) return message; return formatLocationMessage(message, anno.getLocation(), true); } public static String formatLocationMessage(String message, Location loc) { return formatLocationMessage(message, loc, true); } private static String formatLocationMessage(String message, Location loc, boolean showColumn) { if (loc == null) return message; String path = loc.getPath(); int ln = loc.getLineNumber(); int cn = loc.getColumnNumber(); StringBuilder sb = new StringBuilder(); if (message != null) { sb.append(message); } sb.append(" at [").append(path); if (ln >= 0) { sb.append(", line:").append(ln); if (showColumn && cn >= 0) { sb.append(", nearby column: ").append(cn); } } sb.append("]"); return sb.toString(); } private static Location toComponentLocation(Component comp) { if (comp instanceof AbstractComponent) { Annotation anno = ((AbstractComponent) comp).getAnnotation(null, "ZKLOC"); return anno == null ? null : anno.getLocation(); } return null; } //utility to prevent nested location info in exception public static RuntimeException mergeExceptionInfo(Exception ex, Object loc) { Location location = null; boolean showColumn = true; if (loc instanceof Component) { location = toComponentLocation((Component) loc); showColumn = false; } else if (loc instanceof Annotation) { location = ((Annotation) loc).getLocation(); } else if (loc instanceof Location) { location = (Location) loc; } if (location == null) { if (ex instanceof RuntimeException) { return (RuntimeException) ex; } else { throw UiException.Aide.wrap(ex, ex.getMessage()); } } else { String orgMsg = ex.getMessage(); String msg = formatLocationMessage(null, location, showColumn); if (orgMsg != null && orgMsg.endsWith(msg)) { //don't append if the location info is the same. if (ex instanceof RuntimeException) { return (RuntimeException) ex; } else { throw UiException.Aide.wrap(ex, ex.getMessage()); } } else { msg = ex.getClass().getName() + ": " + formatLocationMessage(orgMsg, location, showColumn); //no way to change exception's message, so use the most common UiException throw UiException.Aide.wrap(ex, msg); } } } }