Java tutorial
/** * XOR, empowering Model Driven Architecture in J2EE applications * * Copyright (c) 2012, Dilip Dalton * * 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 tools.xor.util; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import javax.persistence.Access; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.hibernate.proxy.HibernateProxy; import org.hibernate.proxy.LazyInitializer; import org.json.JSONArray; import org.json.JSONException; import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.stereotype.Component; import tools.xor.BusinessObject; import tools.xor.Settings; @Component public class ClassUtil { private static final Logger logger = LogManager.getLogger(new Exception().getStackTrace()[0].getClassName()); private static final String JAVASSIST_STARTWITH = "org.javassist.tmp."; private static final String JAVASSIST_INDEXOF = "_$$_javassist_"; private static boolean isJavassistEnhanced(Class<?> c) { String className = c.getName(); // pattern found in javassist ProxyFactory return className.startsWith(JAVASSIST_STARTWITH) || className.indexOf(JAVASSIST_INDEXOF) != -1; } public static Class<?> getUnEnhanced(Class<?> clazz) { if (isEnhanced(clazz)) return clazz.getSuperclass(); return clazz; } public static boolean isEnhanced(Class<?> c) { boolean result = false; if (isJavassistEnhanced(c)) { result = true; } /* * CGLIB support is deprecated so we won't support it. if (Enhancer.isEnhanced(c) || isJavassistEnhanced(c)) { result = true; } */ return result; } public static boolean isEnhanced(Object proxy) { boolean result = false; /* * CGLIB support is deprecated so we won't support it. if (Enhancer.isEnhanced(proxy.getClass()) || isJavassistEnhanced(proxy.getClass()) || AopUtils.isJdkDynamicProxy(proxy)) { result = true; } */ if (isJavassistEnhanced(proxy.getClass()) || AopUtils.isJdkDynamicProxy(proxy)) { result = true; } return result; } public static Object getTargetObject(Object object) { Object result = object; // Hibernate based implementation, safe to initialize the proxy since we need its data // Allow user to override this behavior if (object instanceof HibernateProxy) { while (object instanceof HibernateProxy) { HibernateProxy proxy = (HibernateProxy) object; LazyInitializer li = proxy.getHibernateLazyInitializer(); object = li.getImplementation(); } return object; } else if (AopUtils.isJdkDynamicProxy(object)) { try { return ((Advised) object).getTargetSource().getTarget(); } catch (Exception e) { throw wrapRun(e); } } return result; } /** * Invoke the given method as a privileged action, if necessary. * @param target the object on which the method needs to be invoked * @param method to invoke * @param args to the method * @return result of the invocation * @throws InvocationTargetException while invoking the method * @throws IllegalAccessException when accessing the meta data */ //public static Object invokeMethodAsPrivileged(final Object target, final Method method, final Object[] args) public static Object invokeMethodAsPrivileged(final Object target, final Method method, final Object... args) throws InvocationTargetException, IllegalAccessException { if (Modifier.isPublic(method.getModifiers())) if (args == null) return method.invoke(target); else return method.invoke(target, args); return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { method.setAccessible(true); Object result = null; try { if (args == null) result = method.invoke(target); else result = method.invoke(target, args); } catch (Exception e) { throw wrapRun(e); } return result; } }); } /** * Invoke the given method as a privileged action, if necessary. * @param target the object on which the method needs to be invoked * @param field we are reading or writing * @param value to set in the field * @param read true if this a read operation * @return result of the invocation * @throws InvocationTargetException while invoking the method * @throws IllegalAccessException when accessing the meta data */ public static Object invokeFieldAsPrivileged(final Object target, final Field field, final Object value, final boolean read) throws InvocationTargetException, IllegalAccessException { if (Modifier.isPublic(field.getModifiers())) { Object readValue = null; if (read) readValue = field.get(target); else field.set(target, value); return readValue; } else { return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { field.setAccessible(true); Object readValue = null; try { if (read) readValue = field.get(target); else field.set(target, value); } catch (Exception e) { throw wrapRun(e); } return readValue; } }); } } public static RuntimeException wrapRun(Exception e) { if (InvocationTargetException.class.isAssignableFrom(e.getClass())) { InvocationTargetException ite = (InvocationTargetException) e; Throwable cause = ite.getCause(); if (cause != null && Exception.class.isAssignableFrom(cause.getClass())) e = (Exception) cause; } if (RuntimeException.class.isAssignableFrom(e.getClass())) return (RuntimeException) e; else return new RuntimeException(e); } public static tools.xor.AccessType getAccessStrategy(org.hibernate.cfg.AccessType type) { if (org.hibernate.cfg.AccessType.PROPERTY.equals(type)) { return tools.xor.AccessType.PROPERTY; } else if (org.hibernate.cfg.AccessType.FIELD.equals(type)) { return tools.xor.AccessType.FIELD; } else { return tools.xor.AccessType.PROPERTY; } } public static PersistenceType getAccessStrategy(String accessType) { return PersistenceType.valueOf(accessType); } public static tools.xor.AccessType getHibernateAccessType(Class<?> instanceClass) { org.hibernate.cfg.AccessType classDefinedAccessType; org.hibernate.cfg.AccessType hibernateDefinedAccessType = org.hibernate.cfg.AccessType.DEFAULT; org.hibernate.cfg.AccessType jpaDefinedAccessType = org.hibernate.cfg.AccessType.DEFAULT; org.hibernate.annotations.AccessType accessTypeAnno = instanceClass .getAnnotation(org.hibernate.annotations.AccessType.class); if (accessTypeAnno != null) { hibernateDefinedAccessType = org.hibernate.cfg.AccessType.getAccessStrategy(accessTypeAnno.value()); } Access accessAnno = instanceClass.getAnnotation(Access.class); if (accessAnno != null) { jpaDefinedAccessType = org.hibernate.cfg.AccessType.getAccessStrategy(accessAnno.value()); } if (hibernateDefinedAccessType != org.hibernate.cfg.AccessType.DEFAULT && jpaDefinedAccessType != org.hibernate.cfg.AccessType.DEFAULT && hibernateDefinedAccessType != jpaDefinedAccessType) { throw new RuntimeException( "@PersistenceType and @Access specified with contradicting values. Use of @Access only is recommended. "); } if (hibernateDefinedAccessType != org.hibernate.cfg.AccessType.DEFAULT) { classDefinedAccessType = hibernateDefinedAccessType; } else { classDefinedAccessType = jpaDefinedAccessType; } return ClassUtil.getAccessStrategy(classDefinedAccessType); } public static int getDimensionCount(Object array) { int count = 0; Class<?> arrayClass = array.getClass(); while (arrayClass.isArray()) { count++; arrayClass = arrayClass.getComponentType(); } return count; } public static Object getInstance(Object dataObject) { if (dataObject == null) return null; Object instance = dataObject; // Using instanceof for performance reasons //if(BusinessObject.class.isAssignableFrom(dataObject.getClass())) if (dataObject instanceof BusinessObject) instance = ((BusinessObject) dataObject).getInstance(); return instance; } /** * Creates a non cglib/javassist enhanced instance of the given class, which * could itself be the class of a cglib/javassist enhanced object. * @param fromClass basis of the java class for the new instance * @return new object instance */ public static Object newInstance(Class<?> fromClass) { Class<?> toClass = ClassUtil.getUnEnhanced(fromClass); try { return newInstanceAsPrivileged(toClass); } catch (Exception e) { throw ClassUtil.wrapRun(e); } } /** * Creates a new instance of the given class via the no-arg constructor, * invoking the constructor as a privileged action if it is protected or * private. * * @param c given class * @return a new instance of the given class via the no-arg constructor * @throws Exception when creating the instance */ public static Object newInstanceAsPrivileged(final Class<?> c) throws Exception { try { return c.newInstance(); } catch (Exception e) { return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { try { final Constructor<?> constructor = c.getDeclaredConstructor(); constructor.setAccessible(true); return constructor.newInstance(); } catch (Exception e) { throw ClassUtil.wrapRun(e); } } }); } } public static String getBucketName(Class<?> clazz) { String name = clazz.getName(); return Settings.encodeParam(name); } public static Collection jsonArrayToCollection(JSONArray jsonArray) { Collection collection = new ArrayList<>(jsonArray.length()); try { for (int i = 0; i < jsonArray.length(); i++) { collection.add(jsonArray.get(i)); } } catch (JSONException e) { throw ClassUtil.wrapRun(e); } return collection; } public static boolean intersectsTags(String[] tags, String[] otherTags) { Set<String> commonTags = new HashSet<String>(Arrays.asList(tags)); commonTags.retainAll(new HashSet<String>(Arrays.asList(otherTags))); if (commonTags.isEmpty()) { // applies to different tags so they do not overlap return false; } return true; } }