/*
* Copyright 2006 Luca Garulli (luca.garulli@assetdata.it)
*
* 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.romaframework.core.schema;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import org.romaframework.aspect.core.CoreAspect;
import org.romaframework.aspect.core.feature.CoreFieldFeatures;
import org.romaframework.aspect.view.ViewAspect;
import org.romaframework.core.aspect.Aspect;
import org.romaframework.core.aspect.AspectManager;
import org.romaframework.core.config.RomaApplicationContext;
import org.romaframework.core.exception.ConfigurationNotFoundException;
import org.romaframework.core.schema.config.EmbeddedSchemaConfiguration;
import org.romaframework.core.schema.config.SchemaConfiguration;
import org.romaframework.xml.config.XmlConfigClassType;
import org.romaframework.xml.config.XmlConfigFieldType;
/**
* Represent a form field for an entity.
*
* @author Luca Garulli (luca.garulli@assetdata.it)
*/
public class SchemaField extends SchemaElement {
private Class<?> typeClass;
private Field field;
private Method getterMethod;
private Method setterMethod;
private SchemaClassDefinition complexClass;
/**
* Return field's class information
*
* @return SchemaClass if found, otherwise null
*/
public SchemaClass getClassInfo() {
// TRY TO SEARCH FOR INLINE SCHEMA DECLARATION
if (complexClass != null)
return complexClass.getSchemaClass();
// SEARCH FOR CLASS DEFINITION
return RomaApplicationContext.getInstance().getBean(SchemaManager.class).getClassInfo(typeClass.getSimpleName());
}
public Method getGetterMethod() {
return getterMethod;
}
public Method getSetterMethod() {
return setterMethod;
}
public SchemaField(SchemaClassDefinition iEntity) {
super(iEntity);
}
@Override
public String toString() {
return name + " (field:" + field + ")";
}
@Override
public Object clone() throws CloneNotSupportedException {
SchemaField copy = (SchemaField) super.clone();
copy.complexClass = complexClass;
copy.typeClass = typeClass;
copy.field = field;
copy.getterMethod = getterMethod;
copy.setterMethod = setterMethod;
return copy;
}
public void configure(ViewAspect iComponentFactory, String iFieldName, Class<?> iFieldType, Field iField, Method iGetterMethod,
Method iSetterMethod) {
field = iField;
name = iFieldName;
typeClass = iFieldType;
getterMethod = iGetterMethod;
setterMethod = iSetterMethod;
processConfiguration();
if (getterMethod != null) {
if (!getEmbeddedType(getterMethod.getGenericReturnType()))
if (field != null)
getEmbeddedType(field.getGenericType());
}
}
/**
* Get embedded type using Generics Reflection.
*
* @param iType
* Type to check
* @return true if an embedded type was found, otherwise false
*/
private boolean getEmbeddedType(Type iType) {
Class<?> embClass = SchemaHelper.getGenericClass(iType);
if (embClass != null) {
setEmbeddedType(embClass);
}
return embClass != null;
}
@Override
protected void processConfiguration() {
// BROWSE ALL ASPECTS
Collection<Aspect> aspects = AspectManager.getInstance().getConfigurationValues();
String annotationName;
Annotation fieldAnnotation;
Annotation genericAnnotation;
Annotation getterAnnotation;
SchemaConfiguration classDescriptor = entity.getSchemaClass().getDescriptor();
XmlConfigFieldType parentDescriptor = null;
for (Aspect aspect : aspects) {
// COMPOSE ANNOTATION NAME BY ASPECT
annotationName = aspect.aspectName();
annotationName = Character.toUpperCase(annotationName.charAt(0)) + annotationName.substring(1);
if (field != null) {
fieldAnnotation = searchForAnnotation(field, annotationName + "Field", aspect.aspectName());
genericAnnotation = searchForAnnotation(field, annotationName, aspect.aspectName());
} else {
fieldAnnotation = null;
genericAnnotation = null;
}
if (getterMethod != null)
getterAnnotation = searchForAnnotation(getterMethod, annotationName + "Field", aspect.aspectName());
else
getterAnnotation = null;
parentDescriptor = null;
if (classDescriptor != null && classDescriptor.getType() != null && classDescriptor.getType().getFields() != null) {
// SEARCH FORM DEFINITION IN DESCRIPTOR
XmlConfigFieldType[] allFields = classDescriptor.getType().getFields().getFieldArray();
XmlConfigFieldType tmpDescr = null;
for (short fieldNum = 0; fieldNum < allFields.length; ++fieldNum) {
tmpDescr = allFields[fieldNum];
if (tmpDescr.getName().equals(name)) {
// FOUND XML NODE
parentDescriptor = tmpDescr;
break;
}
}
}
// CONFIGURE THE SCHEMA OBJECT WITH CURRENT ASPECT
aspect.configField(this, fieldAnnotation, genericAnnotation, getterAnnotation, parentDescriptor);
}
if (parentDescriptor != null) {
// CONFIGURE EMBEDDED CLASS IF ANY
XmlConfigClassType subClass = parentDescriptor.getClass1();
if (subClass != null) {
// INLINE DESCRIPTOR
SchemaConfiguration fieldSchemaDescr = null;
SchemaConfiguration sourceDescr = getEntity().getSchemaClass().getDescriptor();
if (sourceDescr != null)
fieldSchemaDescr = new EmbeddedSchemaConfiguration(subClass);
setComplexClass(RomaApplicationContext.getInstance().getBean(SchemaManager.class).createClassInfo(
getEntity().getSchemaClass().getName() + "." + getName(), getTypeClass(), fieldSchemaDescr));
}
}
if (complexClass == null) {
String className = getTypeClass().getName();
// NOT INLINE DESCRIPTOR
if (!getTypeClass().isPrimitive() && !className.startsWith("java.")
&& !(className.length() > 2 && className.indexOf("java.") > -1)) {
try {
setComplexClass(RomaApplicationContext.getInstance().getBean(SchemaManager.class).getClassInfo(
getTypeClass().getSimpleName()));
} catch (ConfigurationNotFoundException e) {
}
}
}
}
public SchemaClassDefinition getComplexClass() {
return complexClass;
}
public void setComplexClass(SchemaClassDefinition complexClass) {
this.complexClass = complexClass;
}
public XmlConfigFieldType getDescriptorInfo() {
SchemaConfiguration classDescriptor = entity.getSchemaClass().getDescriptor();
if (classDescriptor == null || classDescriptor.getType() == null || classDescriptor.getType().getFields() == null)
return null;
XmlConfigFieldType descriptor;
// SEARCH FORM DEFINITION IN DESCRIPTOR
XmlConfigFieldType[] allFields = classDescriptor.getType().getFields().getFieldArray();
for (short fieldNum = 0; fieldNum < allFields.length; ++fieldNum) {
descriptor = allFields[fieldNum];
if (descriptor.getName().equals(name)) {
// FOUND: SET THE ORDER AND RETURN IT
setOrder(fieldNum);
return descriptor;
}
}
return null;
}
public Class<?> getTypeClass() {
return typeClass;
}
public void setTypeClass(Class<?> clazz) {
typeClass = clazz;
}
public Field getField() {
return field;
}
public Type getEmbeddedType() {
return (Type) getFeature(CoreAspect.ASPECT_NAME, CoreFieldFeatures.EMBEDDED_TYPE);
}
public void setEmbeddedType(Type iEmbeddedType) {
setFeature(CoreAspect.ASPECT_NAME, CoreFieldFeatures.EMBEDDED_TYPE, iEmbeddedType);
}
}
|