X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.objmap2%2Fsrc%2Forg%2Fsimantics%2Fobjmap%2Fstructural%2Fschema%2FMappingSchemas.java;fp=bundles%2Forg.simantics.objmap2%2Fsrc%2Forg%2Fsimantics%2Fobjmap%2Fstructural%2Fschema%2FMappingSchemas.java;h=3f9169ec9f569bdbb57b42a5d8804114066ad87d;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.objmap2/src/org/simantics/objmap/structural/schema/MappingSchemas.java b/bundles/org.simantics.objmap2/src/org/simantics/objmap/structural/schema/MappingSchemas.java new file mode 100644 index 000000000..3f9169ec9 --- /dev/null +++ b/bundles/org.simantics.objmap2/src/org/simantics/objmap/structural/schema/MappingSchemas.java @@ -0,0 +1,266 @@ +/******************************************************************************* + * 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.objmap.structural.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.objmap.bidirectional.IBidirectionalMappingRule; +import org.simantics.objmap.graph.annotations.GraphType; +import org.simantics.objmap.graph.annotations.HasCollectionAdder; +import org.simantics.objmap.graph.annotations.HasCollectionRemover; +import org.simantics.objmap.graph.annotations.HasSetter; +import org.simantics.objmap.graph.annotations.OptionalRelatedElements; +import org.simantics.objmap.graph.annotations.OrderedSetType; +import org.simantics.objmap.graph.annotations.RelatedElements; +import org.simantics.objmap.graph.annotations.RelatedElementsGet; +import org.simantics.objmap.graph.annotations.RelatedGetObj; +import org.simantics.objmap.graph.annotations.RelatedGetValue; +import org.simantics.objmap.graph.annotations.RelatedOrderedSetElements; +import org.simantics.objmap.graph.annotations.RelatedValue; +import org.simantics.objmap.graph.annotations.UpdateMethod; +import org.simantics.objmap.graph.annotations.meta.IsClassRule; +import org.simantics.objmap.graph.annotations.meta.IsCollectionRule; +import org.simantics.objmap.graph.annotations.meta.IsFieldRule; +import org.simantics.objmap.graph.annotations.meta.IsGetSetRule; +import org.simantics.objmap.graph.annotations.meta.IsMethodRule; +import org.simantics.objmap.graph.rules.factory.IClassRuleFactory; +import org.simantics.objmap.graph.rules.factory.ICollectionRuleFactory; +import org.simantics.objmap.graph.rules.factory.IFieldRuleFactory; +import org.simantics.objmap.graph.rules.factory.IGetSetRuleFactory; +import org.simantics.objmap.graph.rules.factory.IMethodRuleFactory; +import org.simantics.objmap.structural.IStructuralObject; +import org.simantics.objmap.structural.StructuralResource; +import org.simantics.objmap.structural.annotations.StructuralRelatedElementsGet; +import org.simantics.objmap.structural.annotations.StructuralRelatedGetObj; +import org.simantics.objmap.structural.annotations.TypeRelatedElementsGet; +import org.simantics.objmap.structural.annotations.TypeRelatedGetObj; +import org.simantics.objmap.structural.annotations.TypeRelatedGetValue; +import org.simantics.objmap.structural.annotations.factories.OptionalRelatedElementsRuleFactory; +import org.simantics.objmap.structural.annotations.factories.RelatedElementsRuleFactory; +import org.simantics.objmap.structural.annotations.factories.RelatedElementsRuleFactory2; +import org.simantics.objmap.structural.annotations.factories.RelatedGetSetObjRuleFactory; +import org.simantics.objmap.structural.annotations.factories.RelatedGetSetValueRuleFactory; +import org.simantics.objmap.structural.annotations.factories.RelatedOrderedSetElementsRuleFactory; +import org.simantics.objmap.structural.annotations.factories.RelatedValueRuleFactory; +import org.simantics.objmap.structural.annotations.factories.StructuralRelatedElementsRuleFactory2; +import org.simantics.objmap.structural.annotations.factories.StructuralRelatedGetSetObjRuleFactory; +import org.simantics.objmap.structural.annotations.factories.TypeRelatedElementsRuleFactory2; +import org.simantics.objmap.structural.annotations.factories.TypeRelatedGetSetObjRuleFactory; +import org.simantics.objmap.structural.annotations.factories.TypeRelatedGetSetValueRuleFactory; +import org.simantics.objmap.structural.annotations.factories.UpdateMethodFactory; + + +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); + + if (graphType != null) { + ArrayList> rules = new ArrayList>(); + collectRulesFromAnnotations(g, clazz, rules); + + return new SimpleLinkType(g.getResource(graphType.value()), clazz, rules); + } + OrderedSetType orderedSetType = clazz.getAnnotation(OrderedSetType.class); + if (orderedSetType != null) { + ArrayList> rules = new ArrayList>(); + collectRulesFromAnnotations(g, clazz, rules); + + return new OrderedSetSimpleLinkType(g.getResource(orderedSetType.value()), clazz, rules); + } + throw new IllegalArgumentException("Class " + clazz.toString() + " does not contain annotations."); + } + + 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()) { + + IsClassRule tag = annotation.annotationType().getAnnotation(IsClassRule.class); + if(tag!= null) { + rules.add(createClassRule(g, annotation, clazz).create(g, annotation, clazz)); + } + } + + for(Field f : clazz.getDeclaredFields()) { + f.setAccessible(true); + + for(Annotation annotation : f.getAnnotations()) { + + IsFieldRule tag = annotation.annotationType().getAnnotation(IsFieldRule.class); + if(tag != null) { + rules.add(createFieldRule(g, annotation, f).create(g, annotation, f)); + } + } + } + + for(Method m : clazz.getDeclaredMethods()) { + m.setAccessible(true); + + for(Annotation annotation : m.getAnnotations()) { + IsMethodRule tag = + annotation.annotationType().getAnnotation(IsMethodRule.class); + if(tag != null) { + rules.add(createMethodRule(g, annotation, m).create(g, annotation, m)); + } + } + } + + for (Method m : clazz.getDeclaredMethods()) { + m.setAccessible(true); + for (Annotation annotation : m.getAnnotations()) { + Class annotationType = annotation.annotationType(); + + IsGetSetRule tag = + annotationType.getAnnotation(IsGetSetRule.class); + if (tag != null) { + + HasSetter setterAnnType = annotationType.getAnnotation(HasSetter.class); + + Class setterAnn = setterAnnType.value(); + + Method getter = m; + + IGetSetRuleFactory ruleFactory = createGetSetRuleFactory(g, annotation, getter); + + + 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(); + + IsCollectionRule tag = + annotationType.getAnnotation(IsCollectionRule.class); + if (tag != null) { + + HasCollectionAdder adderAnnType = annotationType.getAnnotation(HasCollectionAdder.class); + HasCollectionRemover removerAnnType = annotationType.getAnnotation(HasCollectionRemover.class); + + Class adderAnn = adderAnnType.value(); + Class removerAnn = removerAnnType.value(); + + Method getter = m; + + ICollectionRuleFactory ruleFactory = createCollectionRuleFactory(g, annotation, getter); + + + 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)); + } + + } + } + } + + public static IClassRuleFactory createClassRule(ReadGraph g, Annotation annotation, Class clazz) { + return null; + } + + public static IFieldRuleFactory createFieldRule(ReadGraph g, Annotation annotation, Field field) { + if (annotation.annotationType().equals(RelatedElements.class)) + return new RelatedElementsRuleFactory(); + if (annotation.annotationType().equals(RelatedValue.class)) + return new RelatedValueRuleFactory(); + if (annotation.annotationType().equals(OptionalRelatedElements.class)) + return new OptionalRelatedElementsRuleFactory(); + if (annotation.annotationType().equals(RelatedOrderedSetElements.class)) + return new RelatedOrderedSetElementsRuleFactory(); + return null; + } + + public static IMethodRuleFactory createMethodRule(ReadGraph g, Annotation annotation, Method m) { + if (annotation.annotationType().equals(UpdateMethod.class)) + return new UpdateMethodFactory(); + return null; + } + + public static IGetSetRuleFactory createGetSetRuleFactory(ReadGraph g, Annotation annotation, Method getter) { + if (annotation.annotationType().equals(RelatedGetValue.class)) + return new RelatedGetSetValueRuleFactory(); + if (annotation.annotationType().equals(RelatedGetObj.class)) + return new RelatedGetSetObjRuleFactory(); + if (annotation.annotationType().equals(TypeRelatedGetValue.class)) + return new TypeRelatedGetSetValueRuleFactory(); + if (annotation.annotationType().equals(TypeRelatedGetObj.class)) + return new TypeRelatedGetSetObjRuleFactory(); + if (annotation.annotationType().equals(StructuralRelatedGetObj.class)) + return new StructuralRelatedGetSetObjRuleFactory(); + return null; + } + + public static ICollectionRuleFactory createCollectionRuleFactory(ReadGraph g, Annotation annotation, Method getter) { + if (annotation.annotationType().equals(RelatedElementsGet.class)) + return new RelatedElementsRuleFactory2(); + if (annotation.annotationType().equals(TypeRelatedElementsGet.class)) + return new TypeRelatedElementsRuleFactory2(); + if (annotation.annotationType().equals(StructuralRelatedElementsGet.class)) + return new StructuralRelatedElementsRuleFactory2(); + return null; + } + + + /** + * 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); + } + + +}