/******************************************************************************* * Copyright (c) 2012, 2013 Association for Decentralized Information Management in * Industry THTH ry. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * VTT Technical Research Centre of Finland - initial API and implementation *******************************************************************************/ package org.simantics.g3d.objmap.schema; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import org.simantics.db.ReadGraph; import org.simantics.db.exception.DatabaseException; import org.simantics.g3d.objmap.annotations.HasCollectionAdder; import org.simantics.g3d.objmap.annotations.HasCollectionRemover; import org.simantics.g3d.objmap.annotations.HasCollectionRuleFactory; import org.simantics.g3d.objmap.annotations.HasGetSetRuleFactory; import org.simantics.g3d.objmap.annotations.HasSetter; import org.simantics.g3d.objmap.rules.factory.ICollectionRuleFactory; import org.simantics.g3d.objmap.rules.factory.IGetSetRuleFactory; import org.simantics.objmap.ILinkType; import org.simantics.objmap.IMappingRule; import org.simantics.objmap.annotations.GraphType; import org.simantics.objmap.annotations.RelatedValue; import org.simantics.objmap.annotations.meta.HasClassRuleFactory; import org.simantics.objmap.annotations.meta.HasFieldRuleFactory; import org.simantics.objmap.annotations.meta.HasMethodRuleFactory; import org.simantics.objmap.schema.SimpleLinkType; public class MappingSchemas { /** * Creates a new SimpleLinkType based on the annotations in the given class. * @throws IllegalAccessException * @throws InstantiationException * @see GraphType * @see RelatedValue */ public static SimpleLinkType fromAnnotations(ReadGraph g, Class clazz) throws DatabaseException, InstantiationException, IllegalAccessException { GraphType graphType = clazz.getAnnotation(GraphType.class); ArrayList rules = new ArrayList(); collectRulesFromAnnotations(g, clazz, rules); return new SimpleLinkType( g.getResource(graphType.value()), clazz, rules); } public static void collectRulesFromAnnotations(ReadGraph g, Class clazz, Collection rules) throws DatabaseException, InstantiationException, IllegalAccessException { Class superclass = clazz.getSuperclass(); if(superclass != null) collectRulesFromAnnotations(g, superclass, rules); for(Annotation annotation : clazz.getAnnotations()) { HasClassRuleFactory factory = annotation.annotationType().getAnnotation(HasClassRuleFactory.class); if(factory != null) { rules.add(factory.value().newInstance() .create(g, annotation, clazz)); } } for(Field f : clazz.getDeclaredFields()) { f.setAccessible(true); for(Annotation annotation : f.getAnnotations()) { HasFieldRuleFactory factory = annotation.annotationType().getAnnotation(HasFieldRuleFactory.class); if(factory != null) { rules.add(factory.value().newInstance() .create(g, annotation, f)); } } } for(Method m : clazz.getDeclaredMethods()) { m.setAccessible(true); for(Annotation annotation : m.getAnnotations()) { HasMethodRuleFactory factory = annotation.annotationType().getAnnotation(HasMethodRuleFactory.class); if(factory != null) { rules.add(factory.value().newInstance().create(g, annotation, m)); } } } for (Method m : clazz.getDeclaredMethods()) { m.setAccessible(true); for (Annotation annotation : m.getAnnotations()) { Class annotationType = annotation.annotationType(); HasGetSetRuleFactory factory = annotationType.getAnnotation(HasGetSetRuleFactory.class); if (factory != null) { HasSetter setterAnnType = annotationType.getAnnotation(HasSetter.class); Class setterAnn = setterAnnType.value(); IGetSetRuleFactory ruleFactory = factory.value().newInstance(); Method getter = m; Method setter = null; for (Method m2 : clazz.getDeclaredMethods()) { Annotation set = m2.getAnnotation(setterAnn); if (set != null && ruleFactory.isSetter(annotation, set)) setter = m2; } rules.add(ruleFactory.create(g, annotation, getter, setter)); } } } for (Method m : clazz.getDeclaredMethods()) { m.setAccessible(true); for (Annotation annotation : m.getAnnotations()) { Class annotationType = annotation.annotationType(); HasCollectionRuleFactory factory = annotationType.getAnnotation(HasCollectionRuleFactory.class); if (factory != null) { HasCollectionAdder adderAnnType = annotationType.getAnnotation(HasCollectionAdder.class); HasCollectionRemover removerAnnType = annotationType.getAnnotation(HasCollectionRemover.class); Class adderAnn = adderAnnType.value(); Class removerAnn = removerAnnType.value(); ICollectionRuleFactory ruleFactory = factory.value().newInstance(); Method getter = m; Method adder = null; Method remover = null; for (Method m2 : clazz.getDeclaredMethods()) { Annotation add = m2.getAnnotation(adderAnn); Annotation rem = m2.getAnnotation(removerAnn); if (add != null && ruleFactory.isAdder(annotation, add)) adder = m2; if (rem != null && ruleFactory.isRemover(annotation, rem)) remover = m2; } rules.add(ruleFactory.create(g, annotation, getter,adder,remover)); } } } } /** * Creates a new SimpleLinkType based on the annotations in the given class. * @throws IllegalAccessException * @throws InstantiationException * @see GraphType * @see RelatedValue */ public static AdaptedLinkType fromAdaptable(ReadGraph g, String type, Class clazz) throws DatabaseException, InstantiationException, IllegalAccessException { return new AdaptedLinkType(g.getResource(type), clazz); } }