| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.apache.taglibs.rdc; |
| |
| import java.io.IOException; |
| import java.lang.reflect.Field; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.text.MessageFormat; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.jar.JarFile; |
| import java.util.zip.ZipEntry; |
| |
| import javax.servlet.jsp.PageContext; |
| import javax.xml.parsers.DocumentBuilder; |
| import javax.xml.parsers.DocumentBuilderFactory; |
| import javax.xml.transform.TransformerException; |
| |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.taglibs.rdc.core.BaseModel; |
| import org.apache.taglibs.rdc.core.ComponentModel; |
| import org.apache.taglibs.rdc.core.Constants; |
| import org.apache.taglibs.rdc.core.GroupModel; |
| import org.apache.xpath.XPathAPI; |
| import org.apache.xpath.objects.XObject; |
| import org.w3c.dom.Document; |
| import org.w3c.dom.Node; |
| import org.w3c.dom.NodeList; |
| import org.xml.sax.InputSource; |
| |
| /** |
| * Utility methods for the rdc package |
| * |
| * @author Rahul Akolkar |
| */ |
| public class RDCUtils { |
| |
| // ****************** |
| // PRIVATE CONSTANTS |
| // ****************** |
| private static final String RDC_PREFIX = "__rdc"; |
| private static int varCounter = 71463; |
| |
| // Error messages (to be i18n'zed) |
| private static final String ERR_NO_SUCH_CLASS = "No class found with " + |
| "name \"{0}\""; |
| private static final String ERR_BAD_URI_SYNTAX = "Bad URI syntax in " + |
| "\"{0}\""; |
| private static final String ERR_COMP_CONFIGS = "Error while trying to " + |
| "obtain child component configuration files"; |
| private static final String ERR_TRANS_EXP = "Transformer Exception " + |
| "while trying to evaluate attributes 'id' and 'config' of " + |
| "<component>"; |
| private static final String ERR_NO_SUCH_ENTRY = "Could not locate jar " + |
| "entry: \"{0}\" in jar: \"{1}\""; |
| |
| // Logging |
| private static Log log = LogFactory.getLog(RDCUtils.class); |
| |
| // ****************** |
| // PUBLIC METHODS |
| // ****************** |
| /** |
| * Return true if the given class implements the given interface. |
| * |
| * @param clas The candidate class |
| * @param interfayce The given interface |
| */ |
| public static boolean implementsInterface(Class clas, Class interfayce) { |
| while (clas != null && clas != Object.class) { |
| Class[] implementedInterfaces = clas.getInterfaces(); |
| for (int j = 0; j < implementedInterfaces.length; j++) { |
| if (implementedInterfaces[j] == interfayce) { |
| // nemo ! |
| return true; |
| } |
| } |
| clas = clas.getSuperclass(); |
| } |
| return false; |
| } |
| |
| /** |
| * Return true if the given class defines or inherits the given field. |
| * |
| * @param clas The candidate class |
| * @param field The given field |
| */ |
| public static boolean hasField(Class clas, String field) { |
| while (clas != null && clas != Object.class) { |
| Field[] fields = clas.getDeclaredFields(); |
| for (int j = 0; j < fields.length; j++) { |
| if (((Field)fields[j]).getName() == field) { |
| return true; |
| } |
| } |
| clas = clas.getSuperclass(); |
| } |
| return false; |
| } |
| |
| |
| /** |
| * Return true if the given class defines or inherits the given method. |
| * |
| * @param clas The candidate class |
| * @param methodName The name of the given method |
| * @param paramTypes The array of parameter types the method accepts |
| */ |
| public static boolean hasMethod(Class clas, String methodName, |
| Class[] paramTypes) { |
| while (clas != null && clas != Object.class) { |
| try { |
| clas.getDeclaredMethod(methodName, paramTypes); |
| } catch (NoSuchMethodException nsme) { |
| clas = clas.getSuperclass(); |
| continue; |
| } |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Return the Class for this class name, if such a class exists, |
| * else return null. |
| * |
| * @param className The class name |
| */ |
| public static Class getClass(String className) { |
| try { |
| Class clas = Class.forName(className); |
| return clas; |
| } catch (Exception e) { |
| MessageFormat msgFormat = new MessageFormat(ERR_NO_SUCH_CLASS); |
| log.warn(msgFormat.format(new Object[] {className})); |
| return null; |
| } |
| } |
| |
| /** |
| * Log error if the supplied string is null or empty. |
| * |
| * @param str The supplied string |
| * @param err_msg The error message to log if null or empty |
| */ |
| public static void mustExist(String str, String err_msg) { |
| if (str == null || str.trim().length() == 0) { |
| log.error(err_msg); |
| } |
| } |
| |
| /** |
| * Log error if the supplied condition is not satisfied. |
| * |
| * @param cond The test condition |
| * @param err_msg The error message to log if test fails |
| */ |
| public static void mustSatisfy(boolean cond, String err_msg) { |
| if (!cond) { |
| log.error(err_msg); |
| } |
| } |
| |
| /** |
| * Print warning via if the supplied error condition holds, but move on. |
| * |
| * @param cond The test condition |
| * @param err_msg The warning message to log if test fails |
| */ |
| public static void warnIf(boolean cond, String err_msg) { |
| if (cond) { |
| log.warn(err_msg); |
| } |
| } |
| |
| /** |
| * Return true if this string contains non-white space characters. |
| * |
| * @param str The candidate string |
| */ |
| public static boolean isStringEmpty(String str) { |
| if (str == null || str.trim().length() == 0) { |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * Create a temporary variable name for this groupTag's page context |
| * |
| */ |
| public static String getNextRDCVarName() { |
| if (varCounter == Integer.MAX_VALUE) { |
| varCounter = 0; |
| } |
| varCounter++; |
| return RDC_PREFIX + varCounter; |
| } |
| |
| /** |
| * Return a nested data model |
| * |
| */ |
| public static BaseModel getChildDataModel(BaseModel parent, |
| String childId) { |
| Map localMap = null; |
| if (parent instanceof GroupModel) { |
| localMap = ((GroupModel) parent).getLocalMap(); |
| } else if (parent instanceof ComponentModel) { |
| localMap = ((ComponentModel) parent).getLocalMap(); |
| } else { |
| return null; |
| } |
| return (BaseModel) localMap.get(childId); |
| } |
| |
| /** |
| * Clear a nested data model |
| * |
| */ |
| public static boolean clearChildDataModel(BaseModel parent, |
| String childId) { |
| Map localMap = null; |
| if (parent instanceof GroupModel) { |
| localMap = ((GroupModel) parent).getLocalMap(); |
| } else if (parent instanceof ComponentModel) { |
| localMap = ((ComponentModel) parent).getLocalMap(); |
| } else { |
| return false; |
| } |
| if (localMap.containsKey(childId)) { |
| localMap.remove(childId); |
| return true; |
| } |
| return false; |
| } |
| |
| /** |
| * A config handler commonly used by composites for passing prompts |
| * down to their constituent components |
| * (such as mortgage and creditcardInfo). |
| * |
| * Stores the id and file attributes from the config xml to a Map. |
| * Composite config file should look like:<br> |
| * <br> |
| * <config><br> |
| * <componentConfigList><br> |
| * <component id="foo" config="dir/configfile.xml" /><br> |
| * <!-- More component elements here --><br> |
| * </componentConfigList><br> |
| * </config><br> |
| */ |
| public static Map configHandler(String config, PageContext context) { |
| if (isStringEmpty(config)) { |
| return null; |
| } |
| Map configMap = new HashMap(); |
| String uriPath = config; |
| DocumentBuilder builder = null; |
| Document doc = null; |
| XObject xPathResult = null; |
| NodeList nodelist = null; |
| Node node = null; |
| URI absTest = null; |
| |
| try { |
| absTest = new URI(uriPath); |
| } catch (URISyntaxException uriexp) { |
| MessageFormat msgFormat = new MessageFormat(ERR_BAD_URI_SYNTAX); |
| log.warn(msgFormat.format(new Object[] {uriPath})); |
| } |
| if (!absTest.isAbsolute()) { |
| uriPath = context.getServletContext().getRealPath(uriPath); |
| } |
| |
| try { |
| builder = DocumentBuilderFactory.newInstance(). |
| newDocumentBuilder(); |
| doc = builder.parse(uriPath); |
| xPathResult = |
| XPathAPI.eval(doc.getDocumentElement(), |
| Constants.XPATH_COMPONENT_CONFIG); |
| nodelist = xPathResult.nodelist(); |
| } catch (Exception e) { |
| log.warn(ERR_COMP_CONFIGS); |
| } |
| |
| XObject attrId = null, attrFile = null; |
| for (int i = 0; i < nodelist.getLength(); i++) { |
| node = nodelist.item(i); |
| if (node == null) { |
| continue; |
| } |
| try { |
| attrId = XPathAPI.eval(node, Constants.XPATH_ATTR_ID); |
| attrFile = XPathAPI.eval(node, Constants.XPATH_ATTR_FILE); |
| } catch (TransformerException te) { |
| log.warn(ERR_TRANS_EXP); |
| } |
| configMap.put(attrId.toString(), attrFile.toString()); |
| } |
| return configMap; |
| } |
| |
| /** |
| * Given a jar and a file location within the jar, extract the |
| * file as an InputSource |
| * |
| */ |
| public static InputSource extract(final String jar, final String file) |
| throws IOException { |
| JarFile j = new JarFile(jar); |
| ZipEntry e = j.getJarEntry(file); |
| if (e == null) { |
| MessageFormat msgFormat = new MessageFormat(ERR_NO_SUCH_ENTRY); |
| String errMsg = msgFormat.format(new Object[] {file, jar}); |
| // Log error and throw IOException |
| log.error(errMsg); |
| throw new IOException(errMsg); |
| } |
| return new InputSource(j.getInputStream(e)); |
| } |
| |
| } |