http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/ObjectUtils.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/ObjectUtils.java b/bval-core/src/main/java/org/apache/bval/util/ObjectUtils.java deleted file mode 100644 index 1c5a728..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/ObjectUtils.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * 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.bval.util; - -import java.lang.annotation.Annotation; -import java.lang.reflect.Array; -import java.util.Objects; -import java.util.function.Predicate; -import java.util.stream.Stream; - -public final class ObjectUtils { - public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0]; - public static final String[] EMPTY_STRING_ARRAY = new String[0]; - public static final Annotation[] EMPTY_ANNOTATION_ARRAY = new Annotation[0]; - - private ObjectUtils() { - } - - /** - * <p>Returns a default value if the object passed is {@code null}.</p> - * - * <pre> - * ObjectUtils.defaultIfNull(null, null) = null - * ObjectUtils.defaultIfNull(null, "") = "" - * ObjectUtils.defaultIfNull(null, "zz") = "zz" - * ObjectUtils.defaultIfNull("abc", *) = "abc" - * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE - * </pre> - * - * @param <T> the type of the object - * @param object the {@code Object} to test, may be {@code null} - * @param defaultValue the default value to return, may be {@code null} - * @return {@code object} if it is not {@code null}, defaultValue otherwise - */ - public static <T> T defaultIfNull(final T object, final T defaultValue) { - return object == null ? defaultValue : object; - } - - public static <T> boolean isNotEmpty(final T[] array) { - return !isEmpty(array); - } - - public static boolean isEmpty(final Object[] array) { - return array == null || array.length == 0; - } - - /** - * <p>Checks if the object is in the given array. - * - * <p>The method returns {@code false} if a {@code null} array is passed in. - * - * @param array the array to search through - * @param objectToFind the object to find - * @return {@code true} if the array contains the object - */ - public static boolean arrayContains(final Object[] array, final Object objectToFind) { - if (array == null) { - return false; - } - return Stream.of(array).anyMatch(Predicate.isEqual(objectToFind)); - } - - public static int indexOf(final Object[] array, final Object objectToFind) { - for (int i = 0; i < array.length; i++) { - if (Objects.equals(array[i], objectToFind)) { - return i; - } - } - return -1; - } - - public static <T> T[] arrayAdd(T[] array, T objectToAdd) { - if (array == null && objectToAdd == null) { - throw new IllegalArgumentException("Arguments cannot both be null"); - } - final int arrayLength = Array.getLength(array); - @SuppressWarnings("unchecked") - T[] newArray = (T[]) Array.newInstance(array.getClass().getComponentType(), arrayLength + 1); - System.arraycopy(array, 0, newArray, 0, arrayLength); - newArray[newArray.length - 1] = objectToAdd; - - return newArray; - } -}
http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/ObjectWrapper.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/ObjectWrapper.java b/bval-core/src/main/java/org/apache/bval/util/ObjectWrapper.java deleted file mode 100644 index 8483745..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/ObjectWrapper.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.bval.util; - -import java.util.Optional; -import java.util.function.Consumer; -import java.util.function.Supplier; - -public class ObjectWrapper<T> implements Consumer<T>, Supplier<T> { - private T value; - - public ObjectWrapper() { - this(null); - } - - public ObjectWrapper(T value) { - super(); - this.value = value; - } - - @Override - public void accept(T value) { - this.value = value; - } - - @Override - public T get() { - return value; - } - - public Optional<T> optional() { - return Optional.ofNullable(value); - } -} http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/PropertyAccess.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/PropertyAccess.java b/bval-core/src/main/java/org/apache/bval/util/PropertyAccess.java deleted file mode 100644 index 481df3c..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/PropertyAccess.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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.bval.util; - -import org.apache.bval.util.reflection.Reflection; -import org.apache.commons.weaver.privilizer.Privilizing; -import org.apache.commons.weaver.privilizer.Privilizing.CallTo; - -import java.beans.BeanInfo; -import java.beans.IntrospectionException; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.annotation.ElementType; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Type; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * Description: Undefined dynamic strategy (FIELD or METHOD access). Uses Apache - * Commons BeanUtils (if present) to support its {@code DynaBean} type. Otherwise the - * {@code java.beans} APIs are used for Java bean property methods and we fall - * back to accessing field values directly. - */ -@Privilizing(@CallTo(Reflection.class)) -public class PropertyAccess extends AccessStrategy { - private static final Logger log = Logger.getLogger(PropertyAccess.class.getName()); - private static final String BEANUTILS = "org.apache.commons.beanutils.BeanUtils"; - private static final String BEANUTILS_PROPERTY_ACCESS = "org.apache.bval.util.BeanUtilsPropertyAccess"; - private static final Constructor<? extends PropertyAccess> BEANUTILS_PROPERTY_ACCESS_CTOR; - private static final ConcurrentMap<Class<?>, Map<String, PropertyDescriptor>> PROPERTY_DESCRIPTORS = - new ConcurrentHashMap<Class<?>, Map<String, PropertyDescriptor>>(); - - static { - final ClassLoader cl = Reflection.getClassLoader(PropertyAccess.class); - boolean useBeanUtils; - try { - Reflection.toClass(BEANUTILS, cl); - useBeanUtils = true; - } catch (Exception e) { - useBeanUtils = false; - } - Constructor<? extends PropertyAccess> ctor; - if (useBeanUtils) { - try { - final Class<?> beanUtilsPropertyAccess = Reflection.toClass(BEANUTILS_PROPERTY_ACCESS, cl); - - ctor = Reflection.getDeclaredConstructor(beanUtilsPropertyAccess.asSubclass(PropertyAccess.class), - Class.class, String.class); - - } catch (Exception e) { - ctor = null; - } - } else { - ctor = null; - } - BEANUTILS_PROPERTY_ACCESS_CTOR = ctor; - } - - /** - * Obtain a {@link PropertyAccess} instance. - * @param clazz - * @param propertyName - * @return PropertyAccess - * @since 1.1.2 - */ - public static PropertyAccess getInstance(Class<?> clazz, String propertyName) { - if (BEANUTILS_PROPERTY_ACCESS_CTOR != null) { - try { - return BEANUTILS_PROPERTY_ACCESS_CTOR.newInstance(clazz, propertyName); - } catch (Exception e) { - log.log(Level.WARNING, String.format("Exception encountered attempting to instantiate %s(%s, %s)", - BEANUTILS_PROPERTY_ACCESS_CTOR, clazz, propertyName), e); - } - } - return new PropertyAccess(clazz, propertyName); - } - - private final Class<?> beanClass; - private final String propertyName; - private Field rememberField; - - /** - * Create a new PropertyAccess instance. - * - * @param clazz - * @param propertyName - */ - @Deprecated - // keep as protected - public PropertyAccess(Class<?> clazz, String propertyName) { - this.beanClass = clazz; - this.propertyName = propertyName; - } - - /** - * {@inheritDoc} - */ - @Override - public ElementType getElementType() { - return rememberField != null ? ElementType.FIELD : ElementType.METHOD; - } - - protected Object getPublicProperty(Object bean) - throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { - if (bean instanceof Map<?, ?>) { - return ((Map<?, ?>) bean).get(propertyName); - } - final Method readMethod = getPropertyReadMethod(propertyName, bean.getClass()); - if (readMethod == null) { - throw new NoSuchMethodException(toString()); - } - final boolean unset = Reflection.setAccessible(readMethod, true); - try { - return readMethod.invoke(bean); - } finally { - if (unset) { - Reflection.setAccessible(readMethod, false); - } - } - } - - /** - * Get a named property from <code>bean</code>. - * - * @param bean - * @param propertyName - * @return Object found - * @throws InvocationTargetException - * @throws NoSuchMethodException - * @throws IllegalAccessException - */ - public static Object getProperty(Object bean, String propertyName) - throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { - return getInstance(bean.getClass(), propertyName).get(bean); - } - - /** - * {@inheritDoc} - */ - @Override - public String toString() { - return "Property{" + beanClass.getName() + '.' + propertyName + '}'; - } - - /** - * {@inheritDoc} - */ - @Override - public Type getJavaType() { - Type result = getTypeInner(); - return result == null ? Object.class : result; - } - - /** - * Learn whether this {@link PropertyAccess} references a known property. - * - * @return boolean - */ - public boolean isKnown() { - return getTypeInner() != null; - } - - /** - * Find out what, if any, type can be calculated. - * - * @return type found or <code>null</code> - */ - private Type getTypeInner() { - if (rememberField != null) { - return rememberField.getGenericType(); - } - Method readMethod = getPropertyReadMethod(propertyName, beanClass); - if (readMethod != null) { - return readMethod.getGenericReturnType(); - } - Field fld = getField(propertyName, beanClass); - if (fld != null) { - cacheField(fld); - return rememberField.getGenericType(); - } - return null; - } - - private static Method getPropertyReadMethod(String propertyName, Class<?> beanClass) { - final Map<String, PropertyDescriptor> propertyDescriptors = getPropertyDescriptors(beanClass); - if (propertyDescriptors.containsKey(propertyName)) { - return propertyDescriptors.get(propertyName).getReadMethod(); - } - return null; - } - - private static Field getField(String propertyName, Class<?> beanClass) { - try { // try public field - return beanClass.getField(propertyName); - } catch (NoSuchFieldException ex2) { - // search for private/protected field up the hierarchy - Class<?> theClass = beanClass; - while (theClass != null) { - try { - return theClass.getDeclaredField(propertyName); - } catch (NoSuchFieldException ex3) { - // do nothing - } - theClass = theClass.getSuperclass(); - } - } - return null; - } - - private static Object readField(Field field, Object bean) throws IllegalAccessException { - final boolean mustUnset = Reflection.setAccessible(field, true); - try { - return field.get(bean); - } finally { - if (mustUnset) { - Reflection.setAccessible(field, false); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public String getPropertyName() { - return propertyName; - } - - /** - * {@inheritDoc} - */ - @Override - public Object get(Object bean) { - try { - if (rememberField != null) { // cache field of previous access - return readField(rememberField, bean); - } - try { // try public method - return getPublicProperty(bean); - } catch (NoSuchMethodException ex) { - return getFieldValue(bean); - } - } catch (IllegalArgumentException e) { - throw e; - } catch (Exception e) { - throw new IllegalArgumentException("cannot access " + propertyName, e); - } - } - - private Object getFieldValue(Object bean) throws IllegalAccessException { - Field field = getField(propertyName, beanClass); - if (field != null) { - cacheField(field); - return readField(rememberField, bean); - } - throw new IllegalArgumentException("cannot access field " + propertyName); - } - - private void cacheField(Field field) { - this.rememberField = field; - } - - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - PropertyAccess that = (PropertyAccess) o; - - return beanClass.equals(that.beanClass) && propertyName.equals(that.propertyName); - } - - /** - * {@inheritDoc} - */ - @Override - public int hashCode() { - int result; - result = beanClass.hashCode(); - result = 31 * result + propertyName.hashCode(); - return result; - } - - private static Map<String, PropertyDescriptor> getPropertyDescriptors(Class<?> type) { - if (PROPERTY_DESCRIPTORS.containsKey(type)) { - return PROPERTY_DESCRIPTORS.get(type); - } - Map<String, PropertyDescriptor> m; - try { - final PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(type).getPropertyDescriptors(); - if (propertyDescriptors == null) { - m = Collections.emptyMap(); - } else { - m = new HashMap<String, PropertyDescriptor>(); - for (PropertyDescriptor pd : propertyDescriptors) { - m.put(pd.getName(), pd); - } - } - } catch (IntrospectionException e) { - log.log(Level.SEVERE, String.format("Cannot locate %s for ", BeanInfo.class.getSimpleName(), type), e); - m = Collections.emptyMap(); - } - final Map<String, PropertyDescriptor> faster = PROPERTY_DESCRIPTORS.putIfAbsent(type, m); - return faster == null ? m : faster; - } -} http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/StringUtils.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/StringUtils.java b/bval-core/src/main/java/org/apache/bval/util/StringUtils.java deleted file mode 100644 index 6b9c25d..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/StringUtils.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * 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.bval.util; - -import java.util.ArrayList; -import java.util.List; - -public final class StringUtils { - private StringUtils() { - } - - /** - * Taken from commons-lang3. - * <p> - * <p>Capitalizes a String changing the first character to title case as - * per {@link Character#toTitleCase(char)}. No other characters are changed.</p> - * <p> - * <p>For a word based algorithm, see {@link org.apache.commons.lang3.text.WordUtils#capitalize(String)}. - * A {@code null} input String returns {@code null}.</p> - * <p> - * <pre> - * StringUtils.capitalize(null) = null - * StringUtils.capitalize("") = "" - * StringUtils.capitalize("cat") = "Cat" - * StringUtils.capitalize("cAt") = "CAt" - * StringUtils.capitalize("'cat'") = "'cat'" - * </pre> - * - * @param str the String to capitalize, may be null - * @return the capitalized String, {@code null} if null String input - * @see org.apache.commons.lang3.text.WordUtils#capitalize(String) - */ - public static String capitalize(final String str) { - int strLen; - if (str == null || (strLen = str.length()) == 0) { - return str; - } - - final char firstChar = str.charAt(0); - final char newChar = Character.toTitleCase(firstChar); - if (firstChar == newChar) { - // already capitalized - return str; - } - - char[] newChars = new char[strLen]; - newChars[0] = newChar; - str.getChars(1, strLen, newChars, 1); - return String.valueOf(newChars); - } - - /** - * Taken from commons-lang3. - * <p>Checks if a CharSequence is whitespace, empty ("") or null.</p> - * <p> - * <pre> - * StringUtils.isBlank(null) = true - * StringUtils.isBlank("") = true - * StringUtils.isBlank(" ") = true - * StringUtils.isBlank("bob") = false - * StringUtils.isBlank(" bob ") = false - * </pre> - * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is null, empty or whitespace - */ - public static boolean isBlank(final CharSequence cs) { - int strLen; - if (cs == null || (strLen = cs.length()) == 0) { - return true; - } - for (int i = 0; i < strLen; i++) { - if (Character.isWhitespace(cs.charAt(i)) == false) { - return false; - } - } - return true; - } - - /** - * Taken from commons-lang3. - * <p>Checks if a CharSequence is not empty (""), not null and not whitespace only.</p> - * - * <pre> - * StringUtils.isNotBlank(null) = false - * StringUtils.isNotBlank("") = false - * StringUtils.isNotBlank(" ") = false - * StringUtils.isNotBlank("bob") = true - * StringUtils.isNotBlank(" bob ") = true - * </pre> - * - * @param cs the CharSequence to check, may be null - * @return {@code true} if the CharSequence is - * not empty and not null and not whitespace - */ - public static boolean isNotBlank(final CharSequence cs) { - return !isBlank(cs); - } - - /** - * <p>Splits the provided text into an array, separator is whitespace. - */ - public static String[] split(String str) { - return split(str, null); - } - - /** - * <p>Splits the provided text into an array, separator is whitespace. - */ - public static String[] split(String str, Character token) { - if (str == null || str.isEmpty()) { - return ObjectUtils.EMPTY_STRING_ARRAY; - } - - // split on token - List<String> ret = new ArrayList<>(); - StringBuilder sb = new StringBuilder(str.length()); - for (int pos = 0; pos < str.length(); pos++) { - char c = str.charAt(pos); - if ((token == null && Character.isWhitespace(c)) || (token != null && token.equals(c))) { - if (sb.length() > 0) { - ret.add(sb.toString()); - sb.setLength(0); // reset the string - } - } else { - sb.append(c); - } - } - if (sb.length() > 0) { - ret.add(sb.toString()); - } - return ret.toArray(new String[ret.size()]); - } - -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/Validate.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/Validate.java b/bval-core/src/main/java/org/apache/bval/util/Validate.java deleted file mode 100644 index 042dc1b..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/Validate.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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.bval.util; - -import java.util.function.Function; - -/** - * Some used validations from commons. - */ -public final class Validate { - private Validate() { - } - - public static <T> T notNull(final T object) { - return notNull(object, "The validated object is null"); - } - - public static <T> T notNull(final T object, final String message, final Object... values) { - return notNull(object, NullPointerException::new, message, values); - } - - public static <E extends Exception, T> T notNull(final T object, Function<? super String, ? extends E> fn, - final String message, final Object... values) throws E { - Exceptions.raiseIf(object == null, fn, message, values); - return object; - } - - public static void isTrue(final boolean expression, final String message, final Object... values) { - Exceptions.raiseUnless(expression, IllegalArgumentException::new, message, values); - } - - public static <T> T[] noNullElements(final T[] array, final String message, final Object... values) { - Validate.notNull(array); - - for (int i = 0; i < array.length; i++) { - Exceptions.raiseIf(array[i] == null, IllegalArgumentException::new, message, - ObjectUtils.arrayAdd(values, Integer.valueOf(i))); - } - return array; - } - - public static void validState(final boolean expression, final String message, final Object... values) { - Exceptions.raiseUnless(expression, IllegalStateException::new, message, values); - } -} http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/ValidationHelper.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/ValidationHelper.java b/bval-core/src/main/java/org/apache/bval/util/ValidationHelper.java deleted file mode 100644 index 16438ae..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/ValidationHelper.java +++ /dev/null @@ -1,239 +0,0 @@ -/* - * 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.bval.util; - -import org.apache.bval.DynamicMetaBean; -import org.apache.bval.model.MetaBean; -import org.apache.bval.model.MetaProperty; -import org.apache.bval.model.Validation; -import org.apache.bval.model.ValidationContext; -import org.apache.bval.model.ValidationListener; - -import java.util.List; -import java.util.Map; - -/** - * Stateless helper methods used by the validators. - * - * @author Carlos Vara - */ -public class ValidationHelper { - - /** - * Interface implemented by the call-back object passed to - * {@link ValidationHelper#validateContext(ValidationContext, ValidateCallback, boolean)} - * . Its {@link #validate()} method will be called accordingly for every - * dispatch. - */ - public static interface ValidateCallback { - void validate(); - } - - /** - * validate a complex 'bean' with related beans according to - * validation rules in 'metaBean' - * - * @param context - * - the context is initialized with: <br> - * bean - the root object start validation at - * or a collection of root objects <br> - * metaBean - the meta information for the root - * object(s) - * @param context - * The current validation context. - */ - public static void validateContext(ValidationContext<?> context, ValidateCallback s, boolean treatMapsLikeBeans) { - if (context.getBean() != null) { - if (!treatMapsLikeBeans && context.getBean() instanceof Map<?, ?>) { - validateMapInContext(context, s); - } else if (context.getBean() instanceof Iterable<?>) { - validateIterableInContext(context, s); - } else if (context.getBean() instanceof Object[]) { - validateArrayInContext(context, s); - } else { // to One Bean (or Map like Bean) - validateBeanInContext(context, s); - } - } - } - - /** - * Validates a single object. - * - * @param <VL> - * @param context - * The validation context, its current bean must be a single - * object. - * @param s - */ - protected static <VL extends ValidationListener> void validateBeanInContext(ValidationContext<VL> context, - ValidateCallback s) { - if (getDynamicMetaBean(context) != null) { - context.setMetaBean(getDynamicMetaBean(context).resolveMetaBean(context.getBean())); - } - s.validate(); - } - - /** - * Iterates the values of an array, setting the current context - * appropriately and validating each value. - * - * @param <VL> - * @param context - * The validation context, its current bean must be an array. - */ - protected static <VL extends ValidationListener> void validateArrayInContext(ValidationContext<VL> context, - ValidateCallback s) { - int index = 0; - DynamicMetaBean dyn = getDynamicMetaBean(context); - Object[] array = (Object[]) context.getBean(); - MetaBean metaBean = context.getMetaBean(); - context.setCurrentIndex(null); - - try { - for (Object each : array) { - context.setCurrentIndex(index++); - if (each == null) { - continue; // Null values are not validated - } - if (dyn == null) { - context.setBean(each); - } else { - context.setBean(each, dyn.resolveMetaBean(each)); - } - s.validate(); - } - } finally { - context.moveUp(array, metaBean); - } - } - - /** - * Iterates the values of an {@link Iterable} object, setting the current - * context appropriately and validating each value. - * - * @param <VL> - * @param context - * The validation context, its current bean must implement - * {@link Iterable}. - */ - protected static <VL extends ValidationListener> void validateIterableInContext(ValidationContext<VL> context, - ValidateCallback s) { - - final boolean positional = context.getBean() instanceof List<?>; - int index = 0; - Iterable<?> iterable = (Iterable<?>) context.getBean(); - MetaBean metaBean = context.getMetaBean(); - context.setCurrentIndex(null); - - try { - // jsr303 spec: Each object provided by the iterator is validated. - final DynamicMetaBean dyn = getDynamicMetaBean(context); - for (Object each : iterable) { - if (positional) { - context.setCurrentIndex(index++); - } - if (each == null) { - continue; // Null values are not validated - } - if (dyn == null) { - context.setBean(each); - } else { - context.setBean(each, dyn.resolveMetaBean(each)); - } - s.validate(); - } - } finally { - context.moveUp(iterable, metaBean); - } - } - - /** - * Iterates the values of a {@link Map}, setting the current context - * appropriately and validating each value. - * - * @param <VL> - * @param context - * The validation context, its current bean must implement - * {@link Map}. - */ - protected static <VL extends ValidationListener> void validateMapInContext(ValidationContext<VL> context, - ValidateCallback s) { - // jsr303 spec: For Map, the value of each Map.Entry is validated (key - // is not validated). - Map<?, ?> currentBean = (Map<?, ?>) context.getBean(); - MetaBean metaBean = context.getMetaBean(); - final DynamicMetaBean dyn = getDynamicMetaBean(context); - context.setCurrentKey(null); - try { - for (Map.Entry<?, ?> entry : currentBean.entrySet()) { - Object value = entry.getValue(); - if (value == null) { - continue; - } - context.setCurrentKey(entry.getKey()); - if (dyn == null) { - context.setBean(value); - } else { - context.setBean(value, dyn.resolveMetaBean(value)); - } - s.validate(); - } - } finally { - context.moveUp(currentBean, metaBean); - } - } - - /** - * @param <VL> - * @param context - * The current validation context. - * @return the current {@link DynamicMetaBean} in context, or - * <code>null</code> if the current meta bean is not dynamic. - */ - private static <VL extends ValidationListener> DynamicMetaBean getDynamicMetaBean(ValidationContext<VL> context) { - return context.getMetaBean() instanceof DynamicMetaBean ? (DynamicMetaBean) context.getMetaBean() : null; - } - - /** - * Validate a single bean only, no related beans will be validated. - */ - public static <VL extends ValidationListener> void validateBean(ValidationContext<VL> context) { - // execute all property level validations - for (MetaProperty prop : context.getMetaBean().getProperties()) { - context.setMetaProperty(prop); - validateProperty(context); - } - - // execute all bean level validations - context.setMetaProperty(null); - for (Validation validation : context.getMetaBean().getValidations()) { - validation.validate(context); - } - } - - /** - * Validate a single property only. Performs all validations - * for this property. - */ - public static <VL extends ValidationListener> void validateProperty(ValidationContext<VL> context) { - for (Validation validation : context.getMetaProperty().getValidations()) { - validation.validate(context); - } - } -} http://git-wip-us.apache.org/repos/asf/bval/blob/ed299e4f/bval-core/src/main/java/org/apache/bval/util/reflection/Reflection.java ---------------------------------------------------------------------- diff --git a/bval-core/src/main/java/org/apache/bval/util/reflection/Reflection.java b/bval-core/src/main/java/org/apache/bval/util/reflection/Reflection.java deleted file mode 100644 index 79e88fb..0000000 --- a/bval-core/src/main/java/org/apache/bval/util/reflection/Reflection.java +++ /dev/null @@ -1,457 +0,0 @@ -/* - * 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.bval.util.reflection; - -import java.lang.annotation.Annotation; -import java.lang.reflect.AccessibleObject; -import java.lang.reflect.Constructor; -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Member; -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashSet; -import java.util.Map; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; - -import org.apache.commons.weaver.privilizer.Privilizing; - -/** - * Security-agnostic "blueprint" class for reflection-related operations. Intended for use by Apache BVal code. - */ -public class Reflection { - /** - * Inclusivity literals for {@link #hierarchy(Class, Interfaces)}. - * Taken from commons-lang3. - */ - public enum Interfaces { - INCLUDE, EXCLUDE - } - - private static final Object[][] NATIVE_CODES = new Object[][]{ - { byte.class, "byte", "B" }, - { char.class, "char", "C" }, - { double.class, "double", "D" }, - { float.class, "float", "F" }, - { int.class, "int", "I" }, - { long.class, "long", "J" }, - { short.class, "short", "S" }, - { boolean.class, "boolean", "Z" }, - { void.class, "void", "V" } - }; - - /** - * Maps primitive {@code Class}es to their corresponding wrapper {@code Class}. - */ - private static final Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_MAP; - static { - final Map<Class<?>, Class<?>> m = new HashMap<>(); - m.put(Boolean.TYPE, Boolean.class); - m.put(Byte.TYPE, Byte.class); - m.put(Character.TYPE, Character.class); - m.put(Short.TYPE, Short.class); - m.put(Integer.TYPE, Integer.class); - m.put(Long.TYPE, Long.class); - m.put(Double.TYPE, Double.class); - m.put(Float.TYPE, Float.class); - m.put(Void.TYPE, Void.TYPE); - PRIMITIVE_WRAPPER_MAP = Collections.unmodifiableMap(m); - } - - /** - * <p>Converts the specified primitive Class object to its corresponding - * wrapper Class object.</p> - * - * <p>NOTE: From v2.2, this method handles {@code Void.TYPE}, - * returning {@code Void.TYPE}.</p> - * - * @param cls the class to convert, may be null - * @return the wrapper class for {@code cls} or {@code cls} if - * {@code cls} is not a primitive. {@code null} if null input. - * @since 2.1 - */ - public static Class<?> primitiveToWrapper(final Class<?> cls) { - Class<?> convertedClass = cls; - if (cls != null && cls.isPrimitive()) { - convertedClass = PRIMITIVE_WRAPPER_MAP.get(cls); - } - return convertedClass; - } - - public static Class<?> wrapperToPrimitive(final Class<?> cls) { - for (Map.Entry<Class<?>, Class<?>> primitiveEntry : PRIMITIVE_WRAPPER_MAP.entrySet()) { - if (primitiveEntry.getValue().equals(cls)) { - return primitiveEntry.getKey(); - } - } - return null; - } - - /** - * Get the named value from the specified {@link Annotation}. - * @param annotation - * @param name - * @return Object value - * @throws IllegalAccessException - * @throws InvocationTargetException - */ - public static Object getAnnotationValue(final Annotation annotation, final String name) - throws IllegalAccessException, InvocationTargetException { - final Method valueMethod; - try { - valueMethod = annotation.annotationType().getDeclaredMethod(name); - } catch (final NoSuchMethodException ex) { - // do nothing - return null; - } - final boolean mustUnset = setAccessible(valueMethod, true); - try { - return valueMethod.invoke(annotation); - } finally { - if (mustUnset) { - setAccessible(valueMethod, false); - } - } - } - - /** - * Get a usable {@link ClassLoader}: that of {@code clazz} if {@link Thread#getContextClassLoader()} returns {@code null}. - * @param clazz - * @return {@link ClassLoader} - */ - public static ClassLoader getClassLoader(final Class<?> clazz) { - final ClassLoader cl = Thread.currentThread().getContextClassLoader(); - return cl == null ? clazz.getClassLoader() : cl; - } - - public static Class<?> toClass(String className) throws ClassNotFoundException { - ClassLoader cl = getClassLoader(Reflection.class); - return toClass(className, cl); - } - - /** - * Return the class for the given string, correctly handling - * primitive types. If the given class loader is null, the context - * loader of the current thread will be used. - * - * @throws RuntimeException on load error - */ - public static Class<?> toClass(String className, ClassLoader loader) throws ClassNotFoundException { - return toClass(className, false, loader); - } - - /** - * Return the class for the given string, correctly handling - * primitive types. If the given class loader is null, the context - * loader of the current thread will be used. - * - * @throws RuntimeException on load error - */ - public static Class<?> toClass(String className, boolean resolve, ClassLoader loader) throws ClassNotFoundException { - if (className == null) { - throw new NullPointerException("className == null"); - } - - // array handling - int dims = 0; - while (className.endsWith("[]")) { - dims++; - className = className.substring(0, className.length() - 2); - } - - // check against primitive types - boolean primitive = false; - if (className.indexOf('.') == -1) { - for (int i = 0; !primitive && (i < NATIVE_CODES.length); i++) { - if (NATIVE_CODES[i][1].equals(className)) { - if (dims == 0) { - return (Class<?>) NATIVE_CODES[i][0]; - } - className = (String) NATIVE_CODES[i][2]; - primitive = true; - } - } - } - - if (dims > 0) { - StringBuilder buf = new StringBuilder(className.length() + dims + 2); - for (int i = 0; i < dims; i++) { - buf.append('['); - } - if (!primitive) { - buf.append('L'); - } - buf.append(className); - if (!primitive) { - buf.append(';'); - } - className = buf.toString(); - } - - if (loader == null) { - loader = Thread.currentThread().getContextClassLoader(); - } - - return Class.forName(className, resolve, loader); - } - - - /** - * Convenient point for {@link Privilizing} {@link System#getProperty(String)}. - * @param name - * @return String - */ - public static String getProperty(final String name) { - return System.getProperty(name); - } - - /** - * Get the declared field from {@code clazz}. - * @param clazz - * @param fieldName - * @return {@link Field} or {@code null} - */ - public static Field getDeclaredField(final Class<?> clazz, final String fieldName) { - try { - return clazz.getDeclaredField(fieldName); - } catch (final NoSuchFieldException e) { - return null; - } - } - - /** - * Convenient point for {@link Privilizing} {@link Class#getDeclaredFields()}. - * @param clazz - * @return {@link Field} array - */ - public static Field[] getDeclaredFields(final Class<?> clazz) { - return clazz.getDeclaredFields(); - } - - /** - * Get the declared constructor from {@code clazz}. - * @param clazz - * @param parameters - * @return {@link Constructor} or {@code null} - */ - public static <T> Constructor<T> getDeclaredConstructor(final Class<T> clazz, final Class<?>... parameters) { - try { - return clazz.getDeclaredConstructor(parameters); - } catch (final NoSuchMethodException e) { - return null; - } - } - - /** - * Get the declared method from {@code clazz}. - * @param clazz - * @param name - * @param parameters - * @return {@link Method} or {@code null} - */ - public static Method getDeclaredMethod(final Class<?> clazz, final String name, final Class<?>... parameters) { - try { - return clazz.getDeclaredMethod(name, parameters); - } catch (final NoSuchMethodException e) { - return null; - } - } - - /** - * Convenient point for {@link Privilizing} {@link Class#getDeclaredMethods()}. - * @param clazz - * @return {@link Method} array - */ - public static Method[] getDeclaredMethods(final Class<?> clazz) { - return clazz.getDeclaredMethods(); - } - - /** - * Convenient point for {@link Privilizing} {@link Class#getDeclaredConstructors()}. - * @param clazz - * @return {@link Constructor} array - */ - public static Constructor<?>[] getDeclaredConstructors(final Class<?> clazz) { - return clazz.getDeclaredConstructors(); - } - - /** - * Get the specified {@code public} {@link Method} from {@code clazz}. - * @param clazz - * @param methodName - * @return {@link Method} or {@code null} - */ - public static Method getPublicMethod(final Class<?> clazz, final String methodName, Class<?>... parameterTypes) { - try { - return clazz.getMethod(methodName, parameterTypes); - } catch (final NoSuchMethodException e) { - return null; - } - } - - /** - * Perform a search against the class hierarchy. - * @param clazz - * @param search - * @return T or {@code null} - */ - public static <T> T find(final Class<?> clazz, Function<Class<?>, T> search) { - for (Class<?> t : hierarchy(clazz, Interfaces.INCLUDE)) { - final T value = search.apply(t); - if (value != null) { - return value; - } - } - return null; - } - - /** - * Construct a new instance of {@code cls} using its default constructor. - * @param cls - * @return T - */ - public static <T> T newInstance(final Class<T> cls) { - try { - return cls.getConstructor().newInstance(); - } catch (final Exception ex) { - throw new RuntimeException("Cannot instantiate : " + cls, ex); - } - } - - /** - * Set the accessibility of {@code o} to {@code accessible}. If running without a {@link SecurityManager} - * and {@code accessible == false}, this call is ignored (because any code could reflectively make any - * object accessible at any time). - * @param o - * @param accessible - * @return whether a change was made. - */ - public static boolean setAccessible(final AccessibleObject o, boolean accessible) { - if (o == null || o.isAccessible() == accessible) { - return false; - } - if (!accessible && System.getSecurityManager() == null) { - return false; - } - final Member m = (Member) o; - - // For public members whose declaring classes are public, we need do nothing: - if (Modifier.isPublic(m.getModifiers()) && Modifier.isPublic(m.getDeclaringClass().getModifiers())) { - return false; - } - o.setAccessible(accessible); - return true; - } - - /** - * Get an {@link Iterable} that can iterate over a class hierarchy in ascending (subclass to superclass) order. - * Taken from commons-lang3. - * - * @param type the type to get the class hierarchy from - * @param interfacesBehavior switch indicating whether to include or exclude interfaces - * @return Iterable an Iterable over the class hierarchy of the given class - */ - public static Iterable<Class<?>> hierarchy(final Class<?> type, final Interfaces interfacesBehavior) { - if (type == null) { - return Collections.emptySet(); - } - final Iterable<Class<?>> classes = new Iterable<Class<?>>() { - - @Override - public Iterator<Class<?>> iterator() { - return new Iterator<Class<?>>() { - Optional<Class<?>> next; - { - next = Optional.of(type); - } - - @Override - public boolean hasNext() { - return next.isPresent(); - } - - @Override - public Class<?> next() { - final Class<?> result = next.orElseThrow(NoSuchElementException::new); - next = Optional.ofNullable(result.getSuperclass()); - return result; - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - }; - if (interfacesBehavior != Interfaces.INCLUDE) { - return classes; - } - return new Iterable<Class<?>>() { - - @Override - public Iterator<Class<?>> iterator() { - final Set<Class<?>> seenInterfaces = new HashSet<Class<?>>(); - final Iterator<Class<?>> wrapped = classes.iterator(); - - return new Iterator<Class<?>>() { - Iterator<Class<?>> interfaces = Collections.emptyIterator(); - - @Override - public boolean hasNext() { - return interfaces.hasNext() || wrapped.hasNext(); - } - - @Override - public Class<?> next() { - if (interfaces.hasNext()) { - final Class<?> nextInterface = interfaces.next(); - seenInterfaces.add(nextInterface); - return nextInterface; - } - final Class<?> nextSuperclass = wrapped.next(); - final Set<Class<?>> currentInterfaces = new LinkedHashSet<>(); - walkInterfaces(currentInterfaces, nextSuperclass); - interfaces = currentInterfaces.iterator(); - return nextSuperclass; - } - - private void walkInterfaces(final Set<Class<?>> addTo, final Class<?> c) { - for (final Class<?> iface : c.getInterfaces()) { - if (!seenInterfaces.contains(iface)) { - addTo.add(iface); - } - walkInterfaces(addTo, iface); - } - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } - }; - } - }; - } -}
