/******************************************************************************* * Copyright (c) 2007, 2010 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.g2d.canvas.impl; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.simantics.g2d.canvas.ICanvasParticipant; import org.simantics.g2d.diagram.handler.DiagramHandler; /** * @author Toni Kalajainen */ public class DependencyReflection { private final static ReferenceDefinition[] EMPTY = new ReferenceDefinition[0]; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public static @interface Dependency {} @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public static @interface Reference {} /** * Scans an object with reflection for all dependencies *

* Example: * * @Dependency * ViewportInteractor vi; * * @param obj object to scan * @return an array of painters and their priorities */ public static ReferenceDefinition[] getDependencies(final Object obj, ReferenceType type) { List result = new ArrayList(); Class clazz = obj.getClass(); _addDependencies(clazz, result, type); //if (result==null) return EMPTY; return result.toArray(EMPTY); } private static void _addDependencies(Class clazz, Collection result, ReferenceType type) { for (final Field f : clazz.getDeclaredFields()) { Class c = f.getType(); Dependency dep = (Dependency) f.getAnnotation(Dependency.class); Reference ref = (Reference) f.getAnnotation(Reference.class); if (dep==null && ref==null) continue; ReferenceType referenceType = null; if ( ICanvasParticipant.class.isAssignableFrom( c ) ) referenceType = ReferenceType.CanvasParticipant; else if ( DiagramHandler.class.isAssignableFrom( c ) ) referenceType = ReferenceType.DiagramHandler; else assert(false); if (referenceType!=type) continue; assert(!(dep!=null && ref!=null)); ReferenceDefinition rd = new ReferenceDefinition(); rd.dependency = dep!=null; rd.field = f; rd.requirement = c; rd.referenceType = referenceType; f.setAccessible(true); result.add(rd); } Class superClass = clazz.getSuperclass(); if (superClass!=null) _addDependencies(superClass, result, type); } public final static class ReferenceDefinition { public Class requirement; public Field field; public boolean dependency; public ReferenceType referenceType; } public static enum ReferenceType { CanvasParticipant, DiagramHandler } }