/* * Copyright 2016 Red Hat, Inc. and/or its affiliates. * * 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.kie.workbench.common.screens.datamodeller.backend.server; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.Map; import org.apache.commons.lang3.ClassUtils; import org.kie.workbench.common.services.datamodeller.core.Annotation; import org.kie.workbench.common.services.datamodeller.core.AnnotationDefinition; import org.kie.workbench.common.services.datamodeller.core.DataModel; import org.kie.workbench.common.services.datamodeller.core.DataObject; import org.kie.workbench.common.services.datamodeller.core.HasAnnotations; import org.kie.workbench.common.services.datamodeller.core.ObjectProperty; import org.kie.workbench.common.services.datamodeller.core.Visibility; import org.kie.workbench.common.services.datamodeller.core.impl.AnnotationImpl; import org.kie.workbench.common.services.datamodeller.core.impl.DataModelImpl; import org.kie.workbench.common.services.datamodeller.core.impl.DataObjectImpl; import org.kie.workbench.common.services.datamodeller.core.impl.ObjectPropertyImpl; /** * Also used in org.jbpm.formModeler.panels.modeler.backend.indexing.IndexFormsTest */ public class DataModelTestUtil { private final Map<String, AnnotationDefinition> systemAnnotations; public DataModelTestUtil(Map<String, AnnotationDefinition> systemAnnos ) { this.systemAnnotations = systemAnnos; } public DataModel createModel(Class... classes) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { DataModel dataModel = new DataModelImpl(); for( Class clazz : classes ) { DataObject dataObject = createDataObject(clazz); dataModel.addDataObject( dataObject ); } return dataModel; } public DataObject createDataObject(Class clazz) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class superClass = clazz.getSuperclass(); String superClassName = null; if( superClass != null && ! superClass.equals(Object.class)) { superClassName = superClass.getCanonicalName(); } DataObject dataObj = createDataObject( clazz.getPackage().getName(), clazz.getSimpleName(), superClassName); addAnnotations(dataObj, clazz.getAnnotations()); for( Field field : clazz.getDeclaredFields() ) { String fieldName = field.getName(); String fieldType = field.getType().getCanonicalName(); ObjectProperty fieldProp = addProperty( dataObj, fieldName, fieldType, true, false, null ); addAnnotations(fieldProp, field.getAnnotations()); } return dataObj; } private static final String VALUE_METHOD_NAME = "value"; private void addAnnotations( HasAnnotations hasAnnos, java.lang.annotation.Annotation [] annos ) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { for( java.lang.annotation.Annotation anno : annos ) { String annoClassName = anno.annotationType().getCanonicalName(); String valueFieldName = null; Object value = getAnnotationValue(anno); if( value != null ) { valueFieldName = VALUE_METHOD_NAME; } Annotation annotation = createAnnotation( systemAnnotations, annoClassName, valueFieldName, value); hasAnnos.addAnnotation( annotation ); } } private static final Class<?> [] NO_CLASS_PARAMETERS = new Class[0]; private static final Object [] NO_PARAMETERS = new Object[0]; private Object getAnnotationValue(java.lang.annotation.Annotation anno) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { Class annoClass = anno.annotationType(); Object valueObj = null; try { Method valueMethod = annoClass.getDeclaredMethod(VALUE_METHOD_NAME, NO_CLASS_PARAMETERS ); // value should be accessible -- if not, there's something wrong with the anno, not with us! valueObj = valueMethod.invoke(anno, NO_PARAMETERS); } catch (NoSuchMethodException nsme) { // no-op -- no value in anno } // In this test, the DefaultJavaRoasterModelAnnotationDriver is being used // (instead of the DefaultJavaModelAnnotationDriver) // which means that annotation values are stored as strings if( valueObj != null ) { if( ! ClassUtils.isPrimitiveOrWrapper(valueObj.getClass()) && ! (valueObj instanceof String) ) { valueObj = valueObj.toString(); } } return valueObj; } public DataObject createDataObject( String packageName, String name, String superClassName ) { DataObject dataObject = new DataObjectImpl( packageName, name ); dataObject.setSuperClassName( superClassName ); return dataObject; } public ObjectProperty addProperty( DataObject dataObject, String name, String className, boolean baseType, boolean multiple, String bag ) { // TODO set modifiers. ObjectProperty property = new ObjectPropertyImpl( name, className, multiple,bag, Visibility.PUBLIC, false, false ); dataObject.addProperty( property ); return property; } public Annotation createAnnotation( Map<String, AnnotationDefinition> systemAnnotations, String className, String memberName, Object value ) { AnnotationDefinition annotationDefinition = systemAnnotations.get( className ); Annotation annotation = new AnnotationImpl( annotationDefinition ); if ( memberName != null ) { annotation.setValue( memberName, value ); } return annotation; } }