-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- * VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-/*\r
- *\r
- * @author Toni Kalajainen\r
- */\r
-package org.simantics.g2d.canvas.impl;\r
-\r
-import java.lang.annotation.ElementType;\r
-import java.lang.annotation.Retention;\r
-import java.lang.annotation.RetentionPolicy;\r
-import java.lang.annotation.Target;\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-\r
-import org.simantics.g2d.canvas.SGDesignation;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-\r
-\r
-public class SGNodeReflection {\r
-\r
- @Retention(RetentionPolicy.RUNTIME)\r
- @Target(ElementType.METHOD)\r
- public static @interface SGInit {\r
- SGDesignation designation() default SGDesignation.CANVAS;\r
- }\r
-\r
- @Retention(RetentionPolicy.RUNTIME)\r
- @Target(ElementType.METHOD)\r
- public static @interface SGCleanup {\r
- }\r
-\r
- /**\r
- * Scans an object with reflection for all painter methods and returns\r
- * an array of ICanvasPainters and priorities.\r
- * <p>\r
- * The corresponding class of obj must contain methods that meet the following\r
- * criteria:\r
- * 1) no return value\r
- * 2) 1 argument, which is Graphics2D\r
- * 3) has annotation Painter\r
- * 4) may not throw any Exception\r
- * 5) method must be accessible\r
- * <p>\r
- * Example:\r
- *\r
- * @Painter(priority = Integer.MIN_VALUE)\r
- * public void prePaint(GraphicsContext gc) {\r
- * }\r
- *\r
- * @param obj object to scan\r
- * @return an array of painters and their priorities\r
- */\r
- public static CanvasSGNodeDefinition[] getSGHandlers(final Object obj)\r
- {\r
- List<CanvasSGNodeDefinition> result = new ArrayList<CanvasSGNodeDefinition>();\r
- Class<?> clazz = obj.getClass();\r
-\r
- for (final Method m : clazz.getMethods()) {\r
- SGInit initAnno = m.getAnnotation(SGInit.class);\r
- if (initAnno==null) continue;\r
-\r
- SGDesignation initDesignation = initAnno.designation();\r
-\r
- Class<?> returnType = m.getReturnType();\r
- if (!returnType.equals(void.class))\r
- throw new RuntimeException(clazz.getName()+"."+m.getName()+" return type is invalid");\r
-\r
- @SuppressWarnings("rawtypes")\r
- Class[] argTypes = m.getParameterTypes();\r
- if (argTypes.length!=1 || !argTypes[0].equals(G2DParentNode.class))\r
- throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid arguments");\r
-\r
- @SuppressWarnings("rawtypes")\r
- Class[] exceptionTypes = m.getExceptionTypes();\r
- if (exceptionTypes.length!=0)\r
- throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid exceptions");\r
-\r
- try {\r
- m.setAccessible(true);\r
- } catch (Throwable t)\r
- {\r
- t.printStackTrace();\r
- throw new Error(t);\r
- }\r
-\r
- CanvasSGNodeDefinition def = new CanvasSGNodeDefinition(m, initDesignation, null, obj);\r
- result.add(def);\r
- }\r
-\r
- for (final Method m : clazz.getMethods()) {\r
- SGCleanup cleanupAnno = m.getAnnotation(SGCleanup.class);\r
- if (cleanupAnno==null) continue;\r
-\r
- Class<?> returnType = m.getReturnType();\r
- if (!returnType.equals(void.class))\r
- throw new RuntimeException(clazz.getName()+"."+m.getName()+" return type is invalid");\r
-\r
- @SuppressWarnings("rawtypes")\r
- Class[] argTypes = m.getParameterTypes();\r
- if (argTypes.length!=0)\r
- throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid arguments");\r
-\r
- @SuppressWarnings("rawtypes")\r
- Class[] exceptionTypes = m.getExceptionTypes();\r
- if (exceptionTypes.length!=0)\r
- throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid exceptions");\r
-\r
- try {\r
- m.setAccessible(true);\r
- } catch (Throwable t)\r
- {\r
- t.printStackTrace();\r
- throw new Error(t);\r
- }\r
-\r
- CanvasSGNodeDefinition def = new CanvasSGNodeDefinition(null, null, m, obj);\r
- result.add(def);\r
- }\r
-\r
- return result.toArray(new CanvasSGNodeDefinition[0]);\r
- }\r
-\r
- public static class CanvasSGNodeDefinition { // FIXME: own classes for init and cleanup\r
- public final Method initMethod;\r
- public final SGDesignation initDesignation;\r
- public final Method cleanupMethod;\r
- public final Object obj;\r
-\r
- public void init(G2DParentNode parent) {\r
- if(initMethod == null) return;\r
- try {\r
- initMethod.invoke(obj, parent);\r
- } catch (IllegalArgumentException e) {\r
- throw new Error(e);\r
- } catch (IllegalAccessException e) {\r
- throw new Error(e);\r
- } catch (InvocationTargetException e) {\r
- throw new RuntimeException(e.getCause());\r
- }\r
- }\r
- public void cleanup() {\r
- if(cleanupMethod == null) return;\r
- try {\r
- cleanupMethod.invoke(obj);\r
- } catch (IllegalArgumentException e) {\r
- throw new Error(e);\r
- } catch (IllegalAccessException e) {\r
- throw new Error(e);\r
- } catch (InvocationTargetException e) {\r
- throw new RuntimeException(e.getCause());\r
- }\r
- }\r
- public CanvasSGNodeDefinition(Method initMethod, SGDesignation initDesignation, Method cleanupMethod, Object obj) {\r
- this.initMethod = initMethod;\r
- this.initDesignation = initDesignation;\r
- this.cleanupMethod = cleanupMethod;\r
- this.obj = obj;\r
- }\r
- @Override\r
- public String toString() {\r
- return String.format("%s %s %s %s",\r
- obj.getClass().getSimpleName(),\r
- initMethod != null ? initMethod.getName() : "no init method",\r
- initDesignation != null ? initDesignation.toString() : "no init designation",\r
- cleanupMethod != null ? cleanupMethod.getName() : "no cleanup method");\r
- }\r
- }\r
-}\r
+/*******************************************************************************
+ * 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
+ *******************************************************************************/
+/*
+ *
+ * @author Toni Kalajainen
+ */
+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.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.simantics.g2d.canvas.SGDesignation;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+
+
+public class SGNodeReflection {
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public static @interface SGInit {
+ SGDesignation designation() default SGDesignation.CANVAS;
+ }
+
+ @Retention(RetentionPolicy.RUNTIME)
+ @Target(ElementType.METHOD)
+ public static @interface SGCleanup {
+ }
+
+ /**
+ * Scans an object with reflection for all painter methods and returns
+ * an array of ICanvasPainters and priorities.
+ * <p>
+ * The corresponding class of obj must contain methods that meet the following
+ * criteria:
+ * 1) no return value
+ * 2) 1 argument, which is Graphics2D
+ * 3) has annotation Painter
+ * 4) may not throw any Exception
+ * 5) method must be accessible
+ * <p>
+ * Example:
+ *
+ * @Painter(priority = Integer.MIN_VALUE)
+ * public void prePaint(GraphicsContext gc) {
+ * }
+ *
+ * @param obj object to scan
+ * @return an array of painters and their priorities
+ */
+ public static CanvasSGNodeDefinition[] getSGHandlers(final Object obj)
+ {
+ List<CanvasSGNodeDefinition> result = new ArrayList<CanvasSGNodeDefinition>();
+ Class<?> clazz = obj.getClass();
+
+ for (final Method m : clazz.getMethods()) {
+ SGInit initAnno = m.getAnnotation(SGInit.class);
+ if (initAnno==null) continue;
+
+ SGDesignation initDesignation = initAnno.designation();
+
+ Class<?> returnType = m.getReturnType();
+ if (!returnType.equals(void.class))
+ throw new RuntimeException(clazz.getName()+"."+m.getName()+" return type is invalid");
+
+ @SuppressWarnings("rawtypes")
+ Class[] argTypes = m.getParameterTypes();
+ if (argTypes.length!=1 || !argTypes[0].equals(G2DParentNode.class))
+ throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid arguments");
+
+ @SuppressWarnings("rawtypes")
+ Class[] exceptionTypes = m.getExceptionTypes();
+ if (exceptionTypes.length!=0)
+ throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid exceptions");
+
+ try {
+ m.setAccessible(true);
+ } catch (Throwable t)
+ {
+ t.printStackTrace();
+ throw new Error(t);
+ }
+
+ CanvasSGNodeDefinition def = new CanvasSGNodeDefinition(m, initDesignation, null, obj);
+ result.add(def);
+ }
+
+ for (final Method m : clazz.getMethods()) {
+ SGCleanup cleanupAnno = m.getAnnotation(SGCleanup.class);
+ if (cleanupAnno==null) continue;
+
+ Class<?> returnType = m.getReturnType();
+ if (!returnType.equals(void.class))
+ throw new RuntimeException(clazz.getName()+"."+m.getName()+" return type is invalid");
+
+ @SuppressWarnings("rawtypes")
+ Class[] argTypes = m.getParameterTypes();
+ if (argTypes.length!=0)
+ throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid arguments");
+
+ @SuppressWarnings("rawtypes")
+ Class[] exceptionTypes = m.getExceptionTypes();
+ if (exceptionTypes.length!=0)
+ throw new RuntimeException(clazz.getName()+"."+m.getName()+" invalid exceptions");
+
+ try {
+ m.setAccessible(true);
+ } catch (Throwable t)
+ {
+ t.printStackTrace();
+ throw new Error(t);
+ }
+
+ CanvasSGNodeDefinition def = new CanvasSGNodeDefinition(null, null, m, obj);
+ result.add(def);
+ }
+
+ return result.toArray(new CanvasSGNodeDefinition[0]);
+ }
+
+ public static class CanvasSGNodeDefinition { // FIXME: own classes for init and cleanup
+ public final Method initMethod;
+ public final SGDesignation initDesignation;
+ public final Method cleanupMethod;
+ public final Object obj;
+
+ public void init(G2DParentNode parent) {
+ if(initMethod == null) return;
+ try {
+ initMethod.invoke(obj, parent);
+ } catch (IllegalArgumentException e) {
+ throw new Error(e);
+ } catch (IllegalAccessException e) {
+ throw new Error(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getCause());
+ }
+ }
+ public void cleanup() {
+ if(cleanupMethod == null) return;
+ try {
+ cleanupMethod.invoke(obj);
+ } catch (IllegalArgumentException e) {
+ throw new Error(e);
+ } catch (IllegalAccessException e) {
+ throw new Error(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e.getCause());
+ }
+ }
+ public CanvasSGNodeDefinition(Method initMethod, SGDesignation initDesignation, Method cleanupMethod, Object obj) {
+ this.initMethod = initMethod;
+ this.initDesignation = initDesignation;
+ this.cleanupMethod = cleanupMethod;
+ this.obj = obj;
+ }
+ @Override
+ public String toString() {
+ return String.format("%s %s %s %s",
+ obj.getClass().getSimpleName(),
+ initMethod != null ? initMethod.getName() : "no init method",
+ initDesignation != null ? initDesignation.toString() : "no init designation",
+ cleanupMethod != null ? cleanupMethod.getName() : "no cleanup method");
+ }
+ }
+}