Added workflow SPI (for locking and resuming widgets) git-svn-id: https://svn.apache.org/repos/asf/wookie/trunk@1641332 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/wookie-services/wookie-spi/src/main/java/org/apache/wookie/services/WorkflowService.java b/wookie-services/wookie-spi/src/main/java/org/apache/wookie/services/WorkflowService.java new file mode 100644 index 0000000..fd66d19 --- /dev/null +++ b/wookie-services/wookie-spi/src/main/java/org/apache/wookie/services/WorkflowService.java
@@ -0,0 +1,79 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.wookie.services; + +import java.util.ServiceLoader; + +import org.apache.wookie.services.impl.DefaultWorkflowService; + +/** + * The workflow service handles flow control properties related to widgets, such as locking down all + * widgets in a particular context to prevent modifying their state. + */ +public interface WorkflowService { + + /** + * Set the status to locked + * @param apiKey + * @param widgetId + * @param contextId + */ + public abstract void lock(String apiKey, String widgetId, String contextId); + + /** + * Set the status to unlocked + * @param apiKey + * @param widgetId + * @param contextId + */ + public abstract void unlock(String apiKey, String widgetId, String contextId); + + /** + * Get the current lock status + * @param apiKey + * @param widgetId + * @param contextId + * @return + */ + public abstract boolean isLocked(String apiKey, String widgetId, String contextId); + + public static class Factory { + + private static WorkflowService provider; + + public static WorkflowService getInstance() { + // + // Use the service loader to load an implementation if one is available + // + if (provider == null){ + ServiceLoader<WorkflowService> ldr = ServiceLoader.load(WorkflowService.class); + for (WorkflowService service : ldr) { + // We are only expecting one + provider = service; + } + } + // + // If no service provider is found, use the default + // + if (provider == null){ + provider = new DefaultWorkflowService(); + } + + return provider; + } + } +}
diff --git a/wookie-services/wookie-spi/src/main/java/org/apache/wookie/services/impl/DefaultWorkflowService.java b/wookie-services/wookie-spi/src/main/java/org/apache/wookie/services/impl/DefaultWorkflowService.java new file mode 100644 index 0000000..0389828 --- /dev/null +++ b/wookie-services/wookie-spi/src/main/java/org/apache/wookie/services/impl/DefaultWorkflowService.java
@@ -0,0 +1,140 @@ +/* + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.wookie.services.impl; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; + +import javax.swing.tree.DefaultMutableTreeNode; + +import org.apache.wookie.services.WorkflowService; + +/** + * Default workflow service implementation. Backed by a tree and hashmaps in memory. + */ +public class DefaultWorkflowService implements WorkflowService { + + + public DefaultWorkflowService(){ + root = new DefaultMutableTreeNode(); + } + + @Override + public void lock(String apiKey, String widgetId, String contextId) { + setProperty(apiKey, contextId, widgetId, "locked", true); + } + + @Override + public void unlock(String apiKey, String widgetId, String contextId) { + setProperty(apiKey, contextId, widgetId, "locked", false); + } + + @Override + public boolean isLocked(String apiKey, String widgetId, String contextId) { + Object property = getProperty(apiKey, contextId, widgetId, "locked"); + if (property == null) property = false; + return (Boolean) property; + } + + + ///// + + + // + // Tree structure APIKEY->CONTEXT->WIDGET->SharedContext + // + + DefaultMutableTreeNode root; + + @SuppressWarnings("rawtypes") + private DefaultMutableTreeNode getSharedContext(String apiKey, String contextId, String widgetId){ + + DefaultMutableTreeNode apiKeyNode = null; + + Enumeration apiKeys = root.children(); + while(apiKeys.hasMoreElements()){ + DefaultMutableTreeNode node = (DefaultMutableTreeNode) apiKeys.nextElement(); + if (node.getUserObject().equals(apiKey)){ + apiKeyNode = node; + } + } + if (apiKeyNode == null){ + apiKeyNode = new DefaultMutableTreeNode(apiKey); + root.add(apiKeyNode); + } + + // + // Context level + // + DefaultMutableTreeNode contextNode = null; + Enumeration contexts = apiKeyNode.children(); + while(contexts.hasMoreElements()){ + DefaultMutableTreeNode node = (DefaultMutableTreeNode) contexts.nextElement(); + if (node.getUserObject().equals(contextId)){ + contextNode = node; + } + } + if (contextNode == null){ + contextNode = new DefaultMutableTreeNode(contextId); + apiKeyNode.add(contextNode); + } + + // + // Widget level + // + DefaultMutableTreeNode widgetNode = null; + Enumeration widgets = contextNode.children(); + while(widgets.hasMoreElements()){ + DefaultMutableTreeNode node = (DefaultMutableTreeNode) widgets.nextElement(); + if (node.getUserObject().equals(widgetId)){ + widgetNode = node; + } else { + System.out.println(node.getUserObject()); + } + } + if (widgetNode == null){ + widgetNode = new DefaultMutableTreeNode(widgetId); + contextNode.add(widgetNode); + + // + // Add properties + // + Map<String, Object>tuples = new HashMap<String, Object>(); + widgetNode.add(new DefaultMutableTreeNode(tuples)); + } + contextNode.add(widgetNode); + return widgetNode; + } + + private Map<String, Object> getTuplesFromTree(String apiKey, String contextId, String widgetId){ + DefaultMutableTreeNode node = (DefaultMutableTreeNode) getSharedContext(apiKey, contextId, widgetId).getFirstChild(); + return (Map<String, Object>) node.getUserObject(); + } + + private Object getProperty(String apiKey, String contextId, String widgetId, String propertyName){ + Map<String, Object> tuples = getTuplesFromTree(apiKey, widgetId, contextId); + return tuples.get(propertyName); + } + + private void setProperty(String apiKey, String contextId, String widgetId, String propertyName, Object value){ + Map<String, Object> tuples = getTuplesFromTree(apiKey, widgetId, contextId); + tuples.put(propertyName, value); + } + +} +
diff --git a/wookie-services/wookie-spi/src/test/java/org/apache/wookie/services/AbstractWorkflowServiceTest.java b/wookie-services/wookie-spi/src/test/java/org/apache/wookie/services/AbstractWorkflowServiceTest.java new file mode 100644 index 0000000..c8c0fd0 --- /dev/null +++ b/wookie-services/wookie-spi/src/test/java/org/apache/wookie/services/AbstractWorkflowServiceTest.java
@@ -0,0 +1,36 @@ +/* + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.wookie.services; + +import static org.junit.Assert.*; + +import org.junit.Test; + +public abstract class AbstractWorkflowServiceTest { + + protected static WorkflowService svc; + + @Test + public void lockSession(){ + svc.lock("test-api", "test-widget", "test-context"); + assertTrue(svc.isLocked("test-api", "test-widget", "test-context")); + assertFalse(svc.isLocked("test-api", "test-widget", "test-other-context")); + + svc.unlock("test-api", "test-widget", "test-context"); + assertFalse(svc.isLocked("test-api", "test-widget", "test-context")); + assertFalse(svc.isLocked("test-api", "test-widget", "test-other-context")); + } + + +}
diff --git a/wookie-services/wookie-spi/src/test/java/org/apache/wookie/services/impl/DefaultWorkflowServiceTest.java b/wookie-services/wookie-spi/src/test/java/org/apache/wookie/services/impl/DefaultWorkflowServiceTest.java new file mode 100644 index 0000000..d26cfdf --- /dev/null +++ b/wookie-services/wookie-spi/src/test/java/org/apache/wookie/services/impl/DefaultWorkflowServiceTest.java
@@ -0,0 +1,18 @@ +package org.apache.wookie.services.impl; + +import org.apache.wookie.services.AbstractWorkflowServiceTest; +import org.junit.AfterClass; +import org.junit.BeforeClass; + +public class DefaultWorkflowServiceTest extends AbstractWorkflowServiceTest { + + @BeforeClass + public static void setup(){ + svc = new DefaultWorkflowService(); + } + + @AfterClass + public static void tearDown(){ + } + +}