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

com.anrisoftware.globalpom.reflection.annotationclass.AnnotationClass Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2014-2025 Erwin Müller 
 *
 * 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 com.anrisoftware.globalpom.reflection.annotationclass;

import static org.apache.commons.lang3.StringUtils.isEmpty;

import java.beans.PropertyVetoException;
import java.lang.annotation.Annotation;
import java.lang.reflect.AccessibleObject;

import jakarta.inject.Inject;

import org.apache.commons.lang3.builder.Builder;

import com.anrisoftware.globalpom.reflection.annotations.AnnotationAccess;
import com.anrisoftware.globalpom.reflection.annotations.AnnotationAccessFactory;
import com.anrisoftware.globalpom.reflection.beans.BeanAccess;
import com.anrisoftware.globalpom.reflection.beans.BeanAccessFactory;
import com.anrisoftware.globalpom.reflection.beans.BeanFactory;
import com.google.inject.assistedinject.Assisted;

/**
 * 

* Creates an instance from an annotation attribute. *

*

* If the parent object have a field that the attribute name references then the * field's value is returned. If the field have no instance, the instance is * created with the default constructor and the field is set. If the attribute * name is set to a class type, the class type is instantiated and returned. *

*

* The attribute is suffixed with "Class" so that it reference the class type * that should be instantiated. *

*

Examples

* *

With class type field

* *
 * class Bean {
 *
 *     @SomeAnnotation(model = "someModel")
 *     public Object someField;
 *
 *     public SomeModel someModel;
 * }
 *
 * public SomeModel createModel(Bean bean, Field someField) {
 *     return create(bean, SomeAnnotation.class, someField).forAttribute("model").build();
 * }
 * 
* *

With class type

* *
 * class Bean {
 *
 *     @SomeAnnotation(modelClass = SomeModel.class)
 *     public Object someField;
 * }
 *
 * public SomeModel createModel(Bean bean, Field someField) {
 *     return create(bean, SomeAnnotation.class, someField).forAttribute("model").build();
 * }
 * 
* * @author Erwin Mueller, [email protected] * @since 1.5 */ public class AnnotationClass implements Builder { /** * @see AnnotationClassFactory#create(Object, Class, AccessibleObject) * * @param parent the parent {@link Object} * * @param annotation the annotation {@link Class} * * @param object the {@link AccessibleObject} * * @param the class type. * * @return the {@link AnnotationClass} */ @SuppressWarnings("unchecked") public static AnnotationClass create(Object parent, Class annotation, AccessibleObject object) { return (AnnotationClass) AnnotationClassModule.getInjector() .getInstance(AnnotationClassFactory.class).create(parent, annotation, object); } private final AnnotationClassLogger log; private final BeanAccessFactory beanAccessFactory; private final AnnotationAccess fieldAnnotation; private final BeanFactory beanFactory; private String attributeName; private final Object parent; private ClassType defaultValue; /** * @see AnnotationClassFactory#create(Class, AccessibleObject) * * @param logger the {@link AnnotationClassLogger} * * @param accessFactory the {@link AnnotationAccessFactory} * * @param beanAccessFactory the {@link BeanAccessFactory} * * @param beanFactory the {@link BeanFactory} * * @param parent the parent {@link Object} * * @param annotation the annotation {@link Class} * * @param object the {@link AccessibleObject} * */ @Inject AnnotationClass(AnnotationClassLogger logger, AnnotationAccessFactory accessFactory, BeanAccessFactory beanAccessFactory, BeanFactory beanFactory, @Assisted Object parent, @Assisted Class annotation, @Assisted AccessibleObject object) { this.log = logger; this.parent = parent; this.fieldAnnotation = accessFactory.create(annotation, object); this.beanAccessFactory = beanAccessFactory; this.beanFactory = beanFactory; } /** * Sets the default value that is returned if neither the object field nor the * object class is set in the annotation. * * @param defaultValue the default value {@link Object} or {@code null}. * * @return this {@link AnnotationClass}. */ public AnnotationClass withDefault(ClassType defaultValue) { this.defaultValue = defaultValue; return this; } /** * Sets the attribute name of the annotation that is either the name of the * field or the class type. * * @param name the attribute name. * * @return this {@link AnnotationClass}. * * @throws NullPointerException if the specified name is {@code null}. * * @throws IllegalArgumentException if the specified name is empty. */ public AnnotationClass forAttribute(String name) { this.attributeName = name; return this; } /** * Returns the class type object. * * @return the field if the field name was specified; instantiates and returns * the class object if the class type was specified; {@code null} if * neither was specified in the annotation. * * @throws NullPointerException if the attribute name is {@code null}. * * @throws IllegalArgumentException if the specified attribute name is empty. */ @Override public ClassType build() { log.checkAttributeName(attributeName); return createInstance(); } private ClassType createInstance() { String fieldName = fieldAnnotation.getValue(attributeName); if (!isEmpty(fieldName)) { return createFromField(fieldName); } else { return createModelClass(); } } private ClassType createFromField(String fieldName) { BeanAccess access = beanAccessFactory.create(fieldName, parent); ClassType value = access.getValue(); return value == null ? createModelFromField(access) : value; } @SuppressWarnings("unchecked") private ClassType createModelFromField(BeanAccess access) { Class type; type = (Class) access.getType(); ClassType model = beanFactory.create(type); try { access.setValue(model); return model; } catch (PropertyVetoException e) { throw new NullPointerException(); } } private ClassType createModelClass() { ClassType model = null; String name = getAttributeClass(); if (fieldAnnotation.haveValue(name)) { model = createModelClass0(name); } return model; } private ClassType createModelClass0(String name) { Class[] type = fieldAnnotation.getValue(name); if (type.length < 1) { return defaultValue; } log.checkClassAttribute(type, attributeName); return beanFactory.create(type[0]); } private String getAttributeClass() { return attributeName + "Class"; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy