001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2007
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.tests.embedded.jsf.bean;
034:
035: import com.flexive.faces.beans.PluginRegistryBean;
036: import com.flexive.faces.plugin.ExtensionPoint;
037: import com.flexive.faces.plugin.Plugin;
038: import com.flexive.faces.plugin.PluginExecutor;
039: import com.flexive.shared.exceptions.FxRuntimeException;
040: import static org.testng.Assert.assertEquals;
041: import org.testng.annotations.Test;
042:
043: import java.util.Stack;
044:
045: /**
046: * Plugin registry tests.
047: *
048: * @author Daniel Lichtenberger (daniel.lichtenberger@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
049: * @version $Rev: 1 $
050: */
051: public class PluginRegistryBeanTest {
052: /**
053: * A primitive PluginExecutor that collects plugin results in a stack.
054: */
055: private static interface TestExecutor extends PluginExecutor {
056: /**
057: * Push a result to the executor.
058: *
059: * @param result the result to be added
060: */
061: void pushResult(int result);
062: }
063:
064: /**
065: * A "NOP-Executor" that simply won't take any commands.
066: */
067: private static interface NullExecutor extends PluginExecutor {
068: }
069:
070: /**
071: * TestExecutor implementation that stores the results in a stack.
072: */
073: private static class TestExecutorImpl implements TestExecutor {
074: private final Stack<Integer> results = new Stack<Integer>();
075:
076: public void pushResult(int result) {
077: results.push(result);
078: }
079:
080: public int popResult() {
081: return results.isEmpty() ? -1 : results.pop();
082: }
083: }
084:
085: /**
086: * A demo plugin that always pushes "42" to the TestExecutor
087: */
088: private static class TestPlugin implements Plugin<TestExecutor> {
089: public void apply(TestExecutor executor) {
090: executor.pushResult(42);
091: }
092: }
093:
094: /**
095: * A demo plugin that always pushes "21" to the TestExecutor
096: */
097: private static class TestPluginCallback2 implements
098: Plugin<TestExecutor> {
099: public void apply(TestExecutor executor) {
100: executor.pushResult(21);
101: }
102: }
103:
104: /**
105: * Our test extension point instance
106: */
107: private static class NamedTestExtension extends
108: ExtensionPoint<TestExecutor> {
109: public NamedTestExtension(String name) {
110: super (name);
111: }
112: }
113:
114: /**
115: * A generic extension point without a bound type parameter (shouldn't work
116: * with the current PluginRegistry implementation).
117: */
118: private static class UnboundExtension<P extends PluginExecutor>
119: extends ExtensionPoint<P> {
120: public UnboundExtension(String name) {
121: super (name);
122: }
123: }
124:
125: private static NamedTestExtension EP = new NamedTestExtension(
126: "testExtension");
127: private PluginRegistryBean pluginRegistry = new PluginRegistryBean();
128:
129: @Test(groups="jsf")
130: public void registerTestPlugin() {
131: pluginRegistry.clearPlugins(EP);
132: pluginRegistry.registerPlugin(EP, new TestPlugin());
133: // register another plugin for another extension point of the same class
134: pluginRegistry.registerPlugin(new ExtensionPoint<TestExecutor>(
135: "bla") {
136: }, new TestPlugin());
137: assertEquals(pluginRegistry.getPlugins(EP).size(), 1);
138: final Plugin<TestExecutor> callback = pluginRegistry
139: .getPlugins(EP).get(0);
140: final TestExecutorImpl exec = new TestExecutorImpl();
141: callback.apply(exec);
142: assertEquals(exec.popResult(), 42);
143: }
144:
145: @Test(groups="jsf")
146: public void heteroPluginList() {
147: pluginRegistry.clearPlugins(EP);
148: // register two callbacks of different classes
149: pluginRegistry.registerPlugin(EP, new TestPlugin());
150: // also test that lookup is implemented by name comparison, not be object/class identity
151: pluginRegistry.registerPlugin(new ExtensionPoint<TestExecutor>(
152: "testExtension") {
153: }, new TestPluginCallback2());
154: assertEquals(pluginRegistry.getPlugins(EP).size(), 2);
155:
156: // execute plugins
157: final TestExecutorImpl exec = new TestExecutorImpl();
158: pluginRegistry.getPlugins(EP).get(0).apply(exec);
159: pluginRegistry.getPlugins(
160: new NamedTestExtension("testExtension")).get(1).apply(
161: exec);
162: checkHeteroResults(exec);
163:
164: // execute plugins via registry's execute method
165: pluginRegistry.execute(EP, exec);
166: checkHeteroResults(exec);
167: pluginRegistry.execute(new NamedTestExtension("testExtension"),
168: exec);
169: checkHeteroResults(exec);
170: }
171:
172: private void checkHeteroResults(TestExecutorImpl exec) {
173: // check results
174: assertEquals(exec.popResult(), 21);
175: assertEquals(exec.popResult(), 42);
176: }
177:
178: @Test(groups="jsf")
179: public void incompatiblePluginList() {
180: pluginRegistry.clearPlugins(EP);
181: pluginRegistry.registerPlugin(EP, new TestPlugin());
182: try {
183: pluginRegistry.registerPlugin(
184: new ExtensionPoint<NullExecutor>("testExtension") {
185: }, new Plugin<NullExecutor>() {
186: public void apply(NullExecutor executor) {
187: }
188: });
189: assertEquals(pluginRegistry.getPlugins(EP).size(), 2);
190: assert false : "Plugin registry allowed to register incompatible types.";
191: } catch (FxRuntimeException e) {
192: // pass
193: assertEquals(pluginRegistry.getPlugins(EP).size(), 1);
194: }
195:
196: }
197:
198: @Test(groups="jsf")
199: public void unboundExecutorTest() {
200: // due to generic handling it is not safe
201: // to use extension points without statically bound type variables
202: try {
203: pluginRegistry.registerPlugin(
204: new UnboundExtension<NullExecutor>("bla"),
205: new Plugin<NullExecutor>() {
206: public void apply(NullExecutor executor) {
207: }
208: });
209: assert false : "Unbound type variables should be rejected";
210: } catch (FxRuntimeException e) {
211: // pass
212: }
213: }
214: }
|