Java tutorial
/* * Copyright 2012 Eng Kam Hon (kamhon@gmail.com) * * 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 net.kamhon.ieagle.util; import java.beans.PropertyDescriptor; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.net.JarURLConnection; import java.net.URL; import java.net.URLDecoder; import java.util.Collection; import java.util.Date; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; import java.util.jar.JarEntry; import java.util.jar.JarFile; import net.kamhon.ieagle.exception.SystemErrorException; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.BeanUtils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; public class ReflectionUtil { private static final Log log = LogFactory.getLog(ReflectionUtil.class); public ReflectionUtil() { } /** * * get all properties and it value which is public method which name get* if obj is collection->no browser in the * collection. only go in object in objPath package. Other than that just get the value and no go in to it * preperties. * * @param obj * = object that needed to print all the properties. * @param objIndicator * = other object indication when vo contain other vo. * @param objPath * = only browse object which class path contain objPath string. * @return */ private static StringBuilder getAllProperties(Object obj, String objIndicator, String objPath) { StringBuilder retAllPreperties = new StringBuilder(); try { retAllPreperties.append("\n" + objIndicator + obj + "->"); BeanWrapper beanO1 = new BeanWrapperImpl(obj); PropertyDescriptor[] proDescriptorsO1 = beanO1.getPropertyDescriptors(); int propertyLength = proDescriptorsO1.length; for (int i = 0; i < propertyLength; i++) { String variable = proDescriptorsO1[i].getName(); // String clazz = // proDescriptorsO1[i].getPropertyType().toString(); try { Object propertyValueO1 = beanO1.getPropertyValue(variable); // compare whether it is vo. if not just print prepertie // else go in // if (propertyValueO1 == null){ // // continue; // // // go in vo // }else if (propertyValueO1 instanceof Collection){ // Collection collection = (Collection)propertyValueO1; // if (!collection.isEmpty()){ // collection.toArray()[0].getClass(); // } // } if (propertyValueO1 == null) { retAllPreperties.append(variable + "=" + propertyValueO1 + ";"); // /** for Set/List **/ // }else if (propertyValueO1 instanceof Collection){ // Collection collection = (Collection)propertyValueO1; // if (CollectionUtil.isNotEmpty(collection)) // for(Object obj2 : collection){ // getAllProperties(obj2, // objIndicator + objIndicator,objPath); // } } else if (propertyValueO1.getClass().toString().contains(objPath)) { retAllPreperties .append(getAllProperties(propertyValueO1, objIndicator + objIndicator, objPath)); retAllPreperties.append("\n" + objIndicator); } else { retAllPreperties.append(variable + "=" + propertyValueO1 + ";"); } } catch (Exception e) { } } } catch (Exception e) { } return retAllPreperties; } /** * if collection then iterate one by one to reflection else just pass to reflection. * * @param obj * @return */ public static StringBuffer getAllExProperties(Object obj, String objIndicator, String objPath) { StringBuffer stringBuffer = new StringBuffer(); if (obj != null) if (obj instanceof Collection<?>) { Collection<?> collection = (Collection<?>) obj; if (CollectionUtil.isNotEmpty(collection)) for (Object obj2 : collection) { stringBuffer.append(ReflectionUtil.getAllProperties(obj2, objIndicator, objPath)); } } else { stringBuffer.append(ReflectionUtil.getAllProperties(obj, objIndicator, objPath)); } else { stringBuffer.append(obj); } return stringBuffer; } /** * search String variavle inside the given object, if Empty then change it to Null. * * @param obj * = this object will not be changed, it will be close. * @return */ public static Object changeEmptyStrToNull(Object obj) { Object newObj = obj; // J.printLine(getAllExProperties(obj, " ", ".vo.")); // try { // newObj = BeanUtils.cloneBean(obj); // } catch (Exception e1) { // e1.printStackTrace(); // } // BeanWrapper beanO1 = new BeanWrapperImpl(newObj); PropertyDescriptor[] proDescriptorsO1 = beanO1.getPropertyDescriptors(); int propertyLength = proDescriptorsO1.length; for (int i = 0; i < propertyLength; i++) { try { Object propertyValueO1 = beanO1.getPropertyValue(proDescriptorsO1[i].getName()); if (propertyValueO1 instanceof String && StringUtils.isEmpty((String) propertyValueO1)) { // password is null. it will not come in because it is not // instance of String // J.printNegetif(proDescriptorsO1[i].getName()+"..."+(String)propertyValueO1); beanO1.setPropertyValue(proDescriptorsO1[i].getName(), null); } } catch (Exception e) { // [exec] java.lang.IllegalAccessException: Class // org.apache.commons.beanutils.BeanUtilsBean can not // access a member of class // com.foremobile.gateway.usermgmt.vo.User with modifiers // "private" // [exec] at sun.reflect.Reflection.ensureMemberAccess(Unknown // Source) } } return newObj; } public static void copyProperties(Object source, Object target, String... ignoreProperties) { if (ignoreProperties == null) BeanUtils.copyProperties(source, target); else BeanUtils.copyProperties(source, target, ignoreProperties); } public static void copyPropertiesWithPropertiesList(Object source, Object target, String... properties) { if (source == null) throw new SystemErrorException("source is null"); if (target == null) throw new SystemErrorException("target is null"); if (properties == null) { copyProperties(source, target); } else { for (String property : properties) { Object value; try { value = PropertyUtils.getProperty(source, property); } catch (Exception e) { throw new SystemErrorException("no property[" + property + "] for source[" + source + "]"); } try { PropertyUtils.setProperty(target, property, value); } catch (Exception e) { throw new SystemErrorException("no property[" + property + "] for target[" + target + "]"); } } } } /** * different with class.getDeclaredField(does not include the field in super class). this one include the field in * super class also. * * @return * @throws NoSuchFieldException */ public static Field getDeclaredField(Class<?> clazz, String fieldName) throws NoSuchFieldException { Field field = null; while (clazz != null && field == null) { try { field = clazz.getDeclaredField(fieldName); } catch (Exception e) { } clazz = clazz.getSuperclass(); } if (clazz == null && field == null) throw new NoSuchFieldException(clazz + ". Field name=" + fieldName); return field; } /** * This method finds the recursively scans the given <code>packageDirectory</code> for {@link Class} files and adds * their according Java names to the given <code>classSet</code>. * * @param packageDirectory * is the directory representing the {@link Package}. * @param classSet * is where to add the Java {@link Class}-names to. * @param qualifiedNameBuilder * is a {@link StringBuilder} containing the qualified prefix (the {@link Package} with a trailing dot). * @param qualifiedNamePrefixLength * the length of the prefix used to rest the string-builder after reuse. * @see http ://m-m-m.svn.sourceforge.net/svnroot/m-m-m/trunk/mmm-util/mmm-util * -reflect/src/main/java/net/sf/mmm/util/ reflect/ReflectionUtil.java */ private static void findClassNamesRecursive(File packageDirectory, Set<String> classSet, StringBuilder qualifiedNameBuilder, int qualifiedNamePrefixLength, String packagePattern) { for (File childFile : packageDirectory.listFiles()) { String fileName = childFile.getName(); if (childFile.isDirectory()) { qualifiedNameBuilder.setLength(qualifiedNamePrefixLength); StringBuilder subBuilder = new StringBuilder(qualifiedNameBuilder); subBuilder.append(fileName); subBuilder.append('.'); findClassNamesRecursive(childFile, classSet, subBuilder, subBuilder.length(), packagePattern); } else { String simpleClassName = fixClassName(fileName); if (simpleClassName != null) { qualifiedNameBuilder.setLength(qualifiedNamePrefixLength); qualifiedNameBuilder.append(simpleClassName); if (qualifiedNameBuilder.toString().matches(packagePattern)) classSet.add(qualifiedNameBuilder.toString()); } } } } /** * <pre> * This method finds all classes that are located in the package identified by * the given * <code> * packageName * </code> * . * <br> * <b>ATTENTION:</b> * <br> * This is a relative expensive operation. Depending on your classpath * multiple directories,JAR, and WAR files may need to scanned. * * @param packageName is the name of the {@link Package} to scan. * @param includeSubPackages - if * <code> * true * </code> * all sub-packages of the * specified {@link Package} will be included in the search. * @return a {@link Set} will the fully qualified names of all requested * classes. * @throws IOException if the operation failed with an I/O error. * @see http://m-m-m.svn.sourceforge.net/svnroot/m-m-m/trunk/mmm-util/mmm-util-reflect/src/main/java/net/sf/mmm/util/reflect/ReflectionUtil.java * </pre> */ public static Set<String> findFileNames(String packageName, boolean includeSubPackages, String packagePattern, String... endWiths) throws IOException { Set<String> classSet = new HashSet<String>(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); String path = packageName.replace('.', '/'); String pathWithPrefix = path + '/'; Enumeration<URL> urls = classLoader.getResources(path); StringBuilder qualifiedNameBuilder = new StringBuilder(packageName); qualifiedNameBuilder.append('.'); int qualifiedNamePrefixLength = qualifiedNameBuilder.length(); while (urls.hasMoreElements()) { URL packageUrl = urls.nextElement(); String urlString = URLDecoder.decode(packageUrl.getFile(), "UTF-8"); String protocol = packageUrl.getProtocol().toLowerCase(); log.debug(urlString); if ("file".equals(protocol)) { File packageDirectory = new File(urlString); if (packageDirectory.isDirectory()) { if (includeSubPackages) { findClassNamesRecursive(packageDirectory, classSet, qualifiedNameBuilder, qualifiedNamePrefixLength, packagePattern); } else { for (String fileName : packageDirectory.list()) { String simpleClassName = fixClassName(fileName); if (simpleClassName != null) { qualifiedNameBuilder.setLength(qualifiedNamePrefixLength); qualifiedNameBuilder.append(simpleClassName); if (qualifiedNameBuilder.toString().matches(packagePattern)) classSet.add(qualifiedNameBuilder.toString()); } } } } } else if ("jar".equals(protocol)) { // somehow the connection has no close method and can NOT be // disposed JarURLConnection connection = (JarURLConnection) packageUrl.openConnection(); JarFile jarFile = connection.getJarFile(); Enumeration<JarEntry> jarEntryEnumeration = jarFile.entries(); while (jarEntryEnumeration.hasMoreElements()) { JarEntry jarEntry = jarEntryEnumeration.nextElement(); String absoluteFileName = jarEntry.getName(); // if (absoluteFileName.endsWith(".class")) { //original if (endWith(absoluteFileName, endWiths)) { // modified if (absoluteFileName.startsWith("/")) { absoluteFileName.substring(1); } // special treatment for WAR files... // "WEB-INF/lib/" entries should be opened directly in // contained jar if (absoluteFileName.startsWith("WEB-INF/classes/")) { // "WEB-INF/classes/".length() == 16 absoluteFileName = absoluteFileName.substring(16); } boolean accept = true; if (absoluteFileName.startsWith(pathWithPrefix)) { String qualifiedName = absoluteFileName.replace('/', '.'); if (!includeSubPackages) { int index = absoluteFileName.indexOf('/', qualifiedNamePrefixLength + 1); if (index != -1) { accept = false; } } if (accept) { String className = fixClassName(qualifiedName); if (className != null) { if (qualifiedNameBuilder.toString().matches(packagePattern)) classSet.add(className); } } } } } } else { log.debug("unknown protocol -> " + protocol); } } return classSet; } private static boolean endWith(String str, String... endWiths) { for (String endWith : endWiths) { if (str.endsWith(endWith)) { return true; } } return false; } /** * <pre> * This method checks and transforms the filename of a potential {@link Class} * given by * <code> * fileName * </code> * . * </pre> * * @param fileName * is the filename. * @return the according Java {@link Class#getName() class-name} for the given <code>fileName</code> if it is a * class-file that is no anonymous {@link Class}, else <code>null</code>. * */ private static String fixClassName(String fileName) { if (fileName.endsWith(".class")) { // remove extension (".class".length() == 6) // String nameWithoutExtension = fileName.substring(0, // fileName.length() - 6); //original String nameWithoutExtension = fileName; // modified for include // extention. // handle inner classes... int lastDollar = nameWithoutExtension.lastIndexOf('$'); if (lastDollar > 0) { char innerClassStart = nameWithoutExtension.charAt(lastDollar + 1); if ((innerClassStart >= '0') && (innerClassStart <= '9')) { // ignore anonymous class } else { return nameWithoutExtension.replace('$', '.'); } } else { return nameWithoutExtension; } } return fileName; } /** * no collection * * @return */ public static boolean isJavaDataType(Object object) { if (object instanceof String || object instanceof Long || object instanceof Double || object instanceof Integer || object instanceof Boolean || object instanceof Date || object.getClass().isPrimitive()) { return true; } return false; } }