All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.joda.beans.impl.direct.DirectMetaProperty Maven / Gradle / Ivy

The newest version!
/*
 *  Copyright 2001-present Stephen Colebourne
 *
 *  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 org.joda.beans.impl.direct;

import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.NoSuchElementException;
import java.util.Optional;

import org.joda.beans.Bean;
import org.joda.beans.MetaBean;
import org.joda.beans.PropertyStyle;
import org.joda.beans.impl.BasicMetaProperty;

/**
 * A meta-property implementation designed for use by the code generator.
 * 

* This meta-property uses reflection to find the {@code Field} to obtain the annotations. * * @param

the type of the property content */ public final class DirectMetaProperty

extends BasicMetaProperty

{ /** The meta-bean. */ private final MetaBean metaBean; /** The property type. */ private final Class

propertyType; /** The declaring type. */ private final Class declaringType; /** The field or method implementing the property. */ private final AccessibleObject fieldOrMethod; /** The style. */ private final PropertyStyle style; /** * Factory to create a read-write meta-property avoiding duplicate generics. * * @param

the property type * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the type declaring the property, not null * @param propertyType the property type, not null * @return the property, not null */ public static

DirectMetaProperty

ofReadWrite( MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType) { Field field = findField(metaBean, propertyName); return new DirectMetaProperty<>(metaBean, propertyName, declaringType, propertyType, PropertyStyle.READ_WRITE, field); } /** * Factory to create a read-only meta-property avoiding duplicate generics. * * @param

the property type * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the type declaring the property, not null * @param propertyType the property type, not null * @return the property, not null */ public static

DirectMetaProperty

ofReadOnly( MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType) { Field field = findField(metaBean, propertyName); return new DirectMetaProperty<>(metaBean, propertyName, declaringType, propertyType, PropertyStyle.READ_ONLY, field); } /** * Factory to create a write-only meta-property avoiding duplicate generics. * * @param

the property type * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the type declaring the property, not null * @param propertyType the property type, not null * @return the property, not null */ public static

DirectMetaProperty

ofWriteOnly( MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType) { Field field = findField(metaBean, propertyName); return new DirectMetaProperty<>(metaBean, propertyName, declaringType, propertyType, PropertyStyle.WRITE_ONLY, field); } /** * Factory to create a buildable read-only meta-property avoiding duplicate generics. * * @param

the property type * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the type declaring the property, not null * @param propertyType the property type, not null * @return the property, not null */ public static

DirectMetaProperty

ofReadOnlyBuildable( MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType) { Field field = findField(metaBean, propertyName); return new DirectMetaProperty<>(metaBean, propertyName, declaringType, propertyType, PropertyStyle.READ_ONLY_BUILDABLE, field); } /** * Factory to create a derived read-only meta-property avoiding duplicate generics. * * @param

the property type * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the type declaring the property, not null * @param propertyType the property type, not null * @return the property, not null */ public static

DirectMetaProperty

ofDerived( MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType) { AccessibleObject method = findMethod(metaBean, propertyName); return new DirectMetaProperty<>(metaBean, propertyName, declaringType, propertyType, PropertyStyle.DERIVED, method); } /** * Factory to create an imutable meta-property avoiding duplicate generics. * * @param

the property type * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the type declaring the property, not null * @param propertyType the property type, not null * @return the property, not null */ public static

DirectMetaProperty

ofImmutable( MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType) { Field field = findField(metaBean, propertyName); return new DirectMetaProperty<>(metaBean, propertyName, declaringType, propertyType, PropertyStyle.IMMUTABLE, field); } private static Field findField(MetaBean metaBean, String propertyName) { Class cls = metaBean.beanType(); while (cls != DirectBean.class && cls != Object.class && cls != null) { try { return cls.getDeclaredField(propertyName); } catch (NoSuchFieldException ex) { try { return cls.getDeclaredField("_" + propertyName); } catch (NoSuchFieldException ex2) { cls = cls.getSuperclass(); } } } return null; } private static AccessibleObject findMethod(MetaBean metaBean, String propertyName) { String methodName = "get" + propertyName.substring(0, 1).toUpperCase(Locale.ENGLISH) + propertyName.substring(1); Class cls = metaBean.beanType(); while (cls != DirectBean.class && cls != Object.class && cls != null) { try { return cls.getDeclaredMethod(methodName); } catch (NoSuchMethodException ex) { cls = cls.getSuperclass(); } } return findField(metaBean, propertyName); // backwards compatibility } /** * Constructor. * * @param metaBean the meta-bean, not null * @param propertyName the property name, not empty * @param declaringType the declaring type, not null * @param propertyType the property type, not null * @param style the style, not null * @param fieldOrMethod the reflected field or method, not null */ private DirectMetaProperty(MetaBean metaBean, String propertyName, Class declaringType, Class

propertyType, PropertyStyle style, AccessibleObject fieldOrMethod) { super(propertyName); if (metaBean == null) { throw new NullPointerException("MetaBean must not be null"); } if (declaringType == null) { throw new NullPointerException("Declaring type must not be null"); } if (propertyType == null) { throw new NullPointerException("Property type must not be null"); } if (style == null) { throw new NullPointerException("PropertyStyle must not be null"); } this.metaBean = metaBean; this.propertyType = propertyType; this.declaringType = declaringType; this.style = style; this.fieldOrMethod = fieldOrMethod; // may be null } //----------------------------------------------------------------------- @Override public MetaBean metaBean() { return metaBean; } @Override public Class declaringType() { return declaringType; } @Override public Class

propertyType() { return propertyType; } @Override public Type propertyGenericType() { if (fieldOrMethod == null) { return propertyType; } return fieldOrMethod instanceof Field ? ((Field) fieldOrMethod).getGenericType() : ((Method) fieldOrMethod).getGenericReturnType(); } @Override public PropertyStyle style() { return style; } @Override public A annotation(Class annotationClass) { if (fieldOrMethod == null) { throw new UnsupportedOperationException("Field not found for property: " + name()); } A annotation = fieldOrMethod.getAnnotation(annotationClass); if (annotation == null) { throw new NoSuchElementException("Unknown annotation: " + annotationClass.getName()); } return annotation; } @Override public Optional annotationOpt(Class annotationClass) { return fieldOrMethod == null ? Optional.empty() : Optional.ofNullable(fieldOrMethod.getAnnotation(annotationClass)); } @Override public List annotations() { if (fieldOrMethod == null) { return Collections.emptyList(); } return Arrays.asList(fieldOrMethod.getDeclaredAnnotations()); } //----------------------------------------------------------------------- @SuppressWarnings("unchecked") @Override public P get(Bean bean) { DirectMetaBean meta = (DirectMetaBean) bean.metaBean(); return (P) meta.propertyGet(bean, name(), false); } @Override public void set(Bean bean, Object value) { DirectMetaBean meta = (DirectMetaBean) bean.metaBean(); meta.propertySet(bean, name(), value, false); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy