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

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

/*
 * Copyright 2016 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 javax.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) */ @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) */ @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. * * @returns 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