1 /*
   2  * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package test.javafx.scene.effect;
  27 
  28 import static org.junit.Assert.assertEquals;
  29 import static org.junit.Assert.assertTrue;
  30 import static org.junit.Assert.fail;
  31 
  32 import java.lang.reflect.InvocationTargetException;
  33 import java.lang.reflect.Method;
  34 import java.util.ArrayList;
  35 import java.util.Collection;
  36 import java.util.List;
  37 
  38 import javafx.beans.property.ObjectProperty;
  39 import javafx.beans.property.SimpleObjectProperty;
  40 import javafx.scene.Group;
  41 import javafx.scene.Node;
  42 import javafx.scene.Scene;
  43 import javafx.scene.shape.Rectangle;
  44 import javafx.stage.Stage;
  45 
  46 import org.junit.Test;
  47 import org.junit.runner.RunWith;
  48 import org.junit.runners.Parameterized;
  49 import org.junit.runners.Parameterized.Parameters;
  50 
  51 import test.com.sun.javafx.pgstub.StubToolkit;
  52 import com.sun.javafx.tk.Toolkit;
  53 import javafx.scene.effect.Effect;
  54 
  55 @RunWith(Parameterized.class)
  56 public class EffectInputTest {
  57     private String effect1Name = null;
  58     private String effect2Name = null;
  59     private Node n = null;
  60     
  61     final static String[] effects = new String[] {
  62         "Bloom", "BoxBlur", "ColorAdjust", "DisplacementMap",
  63         "DropShadow", "GaussianBlur", "Glow", "InnerShadow",
  64         "MotionBlur", "PerspectiveTransform",
  65         "Reflection", "SepiaTone", "Shadow"
  66     };
  67     
  68     @Parameters
  69     public static Collection parameters() {
  70         List list = new ArrayList();
  71         for (int i = 0; i < effects.length; i++) {
  72             for (int j = i; j < effects.length; j++) {
  73                 list.add(new String[] { effects[i], effects[j] });
  74             }
  75         }
  76         return list;
  77     }
  78 
  79     public EffectInputTest(final String effect1,
  80                            final String effect2) {
  81         this.effect1Name = effect1;
  82         this.effect2Name = effect2;
  83         Group root = new Group();
  84         Scene scene = new Scene(root);
  85         Stage stage = new Stage();
  86         stage.setScene(scene);
  87         stage.show();
  88         n = new Rectangle();        
  89         root.getChildren().add(n);
  90     }
  91 
  92     private void pulse() {
  93        ((StubToolkit) Toolkit.getToolkit()).fireTestPulse();
  94     }
  95 
  96     private Method getPGInputMethod(String effectName) throws Exception {
  97         if (effectName.equals("Shadow")) {
  98             effectName = "GeneralShadow";
  99         }
 100         final Class pgEffectClass = Class.forName("com.sun.scenario.effect." + effectName);
 101         if (effectName.equals("InnerShadow")
 102                 || effectName.equals("DropShadow")
 103                 || effectName.equals("DisplacementMap")) {
 104             return pgEffectClass.getMethod("getContentInput");
 105         } else {
 106             return pgEffectClass.getMethod("getInput");
 107         }
 108     }
 109 
 110     @Test
 111     public void testInput() throws Exception  {
 112         final Class effect1Class = Class.forName("javafx.scene.effect." + effect1Name);
 113         final Class effect2Class = Class.forName("javafx.scene.effect." + effect2Name);
 114 
 115         Effect effect1 = (Effect) effect1Class.newInstance();
 116         Effect effect2 = (Effect) effect2Class.newInstance();
 117         final Method getInput1 = effect1Class.getMethod("getInput");
 118         final Method setInput1 = effect1Class.getMethod("setInput", Effect.class);
 119         final Method getInput2 = effect2Class.getMethod("getInput");
 120         final Method setInput2 = effect2Class.getMethod("setInput", Effect.class);
 121 
 122         final Method pgGetInput1 = getPGInputMethod(effect1Name);
 123         final Method pgGetInput2 = getPGInputMethod(effect2Name);
 124 
 125         n.setEffect(effect1);
 126         // try setting second effect as input for first
 127         setInput1.invoke(effect1, effect2);
 128         assertEquals(effect2, getInput1.invoke(effect1));
 129         pulse();
 130         assertEquals(effect2.impl_getImpl(), pgGetInput1.invoke(effect1.impl_getImpl()));
 131 
 132         // try resetting input of first effect to null
 133         setInput1.invoke(effect1, (java.lang.Object) null);
 134         assertEquals((java.lang.Object) null, getInput2.invoke(effect2));
 135         pulse();
 136         assertEquals((java.lang.Object) null, pgGetInput2.invoke(effect2.impl_getImpl()));
 137 
 138         // try setting first effect as input for second
 139         // but first try
 140         // e1.setInput(e2)
 141         // pulse()
 142         // e1.setInput(null)
 143         // e2.setInput(e1);
 144         // to see whether re-registring of listeners is working properly (no NPEs etc)
 145         setInput1.invoke(effect1, effect2);
 146         pulse();
 147         n.setEffect(effect2);
 148         setInput1.invoke(effect1, (java.lang.Object) null);
 149         setInput2.invoke(effect2, effect1);
 150         assertEquals(effect1, getInput2.invoke(effect2));
 151         pulse();
 152         assertEquals(effect1.impl_getImpl(), pgGetInput2.invoke(effect2.impl_getImpl()));
 153     }
 154 
 155     @Test
 156     public void testCycle() throws Exception  {
 157         final Class effect1Class = Class.forName("javafx.scene.effect." + effect1Name);
 158         final Class effect2Class = Class.forName("javafx.scene.effect." + effect2Name);
 159 
 160         Effect effect1 = (Effect) effect1Class.newInstance();
 161         Effect effect2 = (Effect) effect2Class.newInstance();
 162         final Method getInput1 = effect1Class.getMethod("getInput");
 163         final Method setInput1 = effect1Class.getMethod("setInput", Effect.class);
 164         final Method getInput2 = effect2Class.getMethod("getInput");
 165         final Method setInput2 = effect2Class.getMethod("setInput", Effect.class);
 166 
 167         // try setting first input as input for itself
 168         try {
 169             setInput1.invoke(effect1, effect1);
 170             fail("IllegalArgument should have been thrown."); 
 171         } catch (InvocationTargetException e) {
 172             assertTrue(e.getTargetException() instanceof IllegalArgumentException);
 173             assertEquals(null, getInput1.invoke(effect1));
 174         }
 175         
 176         // try setting up cycle from 1. and 2. effect
 177         try {
 178             setInput1.invoke(effect1, effect2);
 179             setInput2.invoke(effect2, effect1);
 180             fail("IllegalArgument should have been thrown."); 
 181         } catch (InvocationTargetException e) {
 182             assertTrue(e.getTargetException() instanceof IllegalArgumentException);
 183             assertEquals(null, getInput2.invoke(effect2));
 184         }
 185     }
 186 
 187     @Test
 188     public void testCycleForBoundInput() throws Exception  {
 189         final Class effect1Class = Class.forName("javafx.scene.effect." + effect1Name);
 190         final Class effect2Class = Class.forName("javafx.scene.effect." + effect2Name);
 191 
 192         Effect effect1 = (Effect) effect1Class.newInstance();
 193         Effect effect2 = (Effect) effect2Class.newInstance();
 194         final Method getInput1 = effect1Class.getMethod("getInput");
 195         final Method setInput2 = effect2Class.getMethod("setInput", Effect.class);
 196 
 197         ObjectProperty v = new SimpleObjectProperty();
 198         Method m = effect1Class.getMethod("inputProperty", new Class[] {});
 199 
 200         ((ObjectProperty)m.invoke(effect1)).bind(v);
 201 
 202         // try setting first input as input for itself
 203         v.set(effect1);
 204         assertEquals(null, getInput1.invoke(effect1));
 205         v.set(null);
 206         ((ObjectProperty)m.invoke(effect1)).bind(v);
 207 
 208         // try setting up cycle from 1. and 2. effect
 209         setInput2.invoke(effect2, effect1);
 210         v.set(effect2);
 211         assertEquals(null, getInput1.invoke(effect1));
 212     }
 213 }