This is an automated email from the ASF dual-hosted git repository. juanpablo pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/jspwiki.git
commit cbbb8d39963a54f07f17aacce372b4c5b6c352dd Author: juanpablo <[email protected]> AuthorDate: Sun May 3 19:56:04 2020 +0200 Generalize WorkflowEventEmitter to WikiEventEmitter and move it to jspwiki-event module. All fireEvent methods scattered throughout the code should be slowly moved to this class. --- .../org/apache/wiki/event/WikiEventEmitter.java | 82 ++++++++++++++++++++++ .../apache/wiki/event/WikiEventEmitterTest.java | 61 ++++++++++++++++ .../java/org/apache/wiki/workflow/Decision.java | 5 +- .../wiki/workflow/DefaultWorkflowManager.java | 3 +- .../java/org/apache/wiki/workflow/Workflow.java | 19 ++--- .../apache/wiki/workflow/WorkflowEventEmitter.java | 55 --------------- 6 files changed, 158 insertions(+), 67 deletions(-) diff --git a/jspwiki-event/src/main/java/org/apache/wiki/event/WikiEventEmitter.java b/jspwiki-event/src/main/java/org/apache/wiki/event/WikiEventEmitter.java new file mode 100644 index 0000000..579f7c0 --- /dev/null +++ b/jspwiki-event/src/main/java/org/apache/wiki/event/WikiEventEmitter.java @@ -0,0 +1,82 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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.wiki.event; + +import java.util.Set; + + +/** + * Emits all kind of {@link org.apache.wiki.event.WikiEvent}s. + */ +public enum WikiEventEmitter { + + INSTANCE; + + public static WikiEventEmitter get() { + return INSTANCE; + } + + /** + * Fires a Workflow Event from provided source and workflow type. + * + * @param src the source of the event, which can be any object: a wiki page, group or authentication/authentication/group manager. + * @param type the type of event + * @return fired {@link WorkflowEvent} or {@code null} if the {@link WikiEventEmitter} instance hasn't listeners attached. + */ + public static WorkflowEvent fireWorkflowEvent( final Object src, final int type ) { + return fireEvent( new WorkflowEvent( src, type ) ); + } + + static < T extends WikiEvent > T fireEvent( final T event ) { + if( WikiEventManager.isListening( WikiEventEmitter.get() ) ) { + WikiEventManager.fireEvent( WikiEventEmitter.get(), event ); + return event; + } + return null; + } + + /** + * Registers a {@link WikiEventListener} so it listens events fired from the {@link WikiEventEmitter} instance. Every other + * {@link WikiEventListener} of the same type, listening events from the {@link WikiEventEmitter} instance will stop listening events + * from it. This ensures events received by the {@link WikiEventListener} will only process the events once. + * + * @param listener {@link WikiEventListener} + */ + public static void attach( final WikiEventListener listener ) { + if( WikiEventManager.isListening( get() ) ) { + final Set< WikiEventListener > attachedListeners = WikiEventManager.getWikiEventListeners( WikiEventEmitter.get() ); + attachedListeners.stream() + .filter( l -> listener.getClass().isAssignableFrom( l.getClass() ) ) + .forEach( WikiEventManager::removeWikiEventListener ); + } + register( listener ); + } + + /** + * Registers a {@link WikiEventListener} so it listens events fired from the {@link WikiEventEmitter} instance. Events received by the + * {@link WikiEventListener} could process the events more than once or, several instances of the same {@link WikiEventListener} would + * be able to receive the same event. + * + * @param listener {@link WikiEventListener} + */ + public static void register( final WikiEventListener listener ) { + WikiEventManager.addWikiEventListener( WikiEventEmitter.get(), listener ); + } + +} diff --git a/jspwiki-event/src/test/java/org/apache/wiki/event/WikiEventEmitterTest.java b/jspwiki-event/src/test/java/org/apache/wiki/event/WikiEventEmitterTest.java new file mode 100644 index 0000000..40cf552 --- /dev/null +++ b/jspwiki-event/src/test/java/org/apache/wiki/event/WikiEventEmitterTest.java @@ -0,0 +1,61 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you 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.wiki.event; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + + +public class WikiEventEmitterTest { + + @BeforeEach + public void setUp() { + // Ensure no listeners are attached to WikiEventEmitter instance + WikiEventManager.getWikiEventListeners( WikiEventEmitter.get() ).forEach( WikiEventManager::removeWikiEventListener ); + } + + @Test + public void shouldCheckFireWorkflowEvent() { + Assertions.assertNull( WikiEventEmitter.fireWorkflowEvent( "test", WorkflowEvent.CREATED ) ); + + WikiEventEmitter.attach( new TestWikiEventListener() ); + final WorkflowEvent we = WikiEventEmitter.fireWorkflowEvent( "test", WorkflowEvent.CREATED ); + Assertions.assertNotNull( we ); + Assertions.assertEquals( WorkflowEvent.CREATED, we.getType() ); + Assertions.assertEquals( "test", we.getSource() ); + } + + @Test + public void shouldCheckAttach() { + Assertions.assertEquals( 0, WikiEventManager.getWikiEventListeners( WikiEventEmitter.get() ).size() ); + WikiEventEmitter.attach( new TestWikiEventListener() ); + WikiEventEmitter.attach( new TestWikiEventListener() ); + Assertions.assertEquals( 1, WikiEventManager.getWikiEventListeners( WikiEventEmitter.get() ).size() ); + } + + @Test + public void shouldCheckRegister() { + Assertions.assertEquals( 0, WikiEventManager.getWikiEventListeners( WikiEventEmitter.get() ).size() ); + WikiEventEmitter.register( new TestWikiEventListener() ); + WikiEventEmitter.register( new TestWikiEventListener() ); + Assertions.assertEquals( 2, WikiEventManager.getWikiEventListeners( WikiEventEmitter.get() ).size() ); + } + +} diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/Decision.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/Decision.java index 9e4f97e..a4e145c 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/Decision.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/Decision.java @@ -19,6 +19,7 @@ package org.apache.wiki.workflow; import org.apache.wiki.api.exceptions.WikiException; +import org.apache.wiki.event.WikiEventEmitter; import org.apache.wiki.event.WorkflowEvent; import java.io.Serializable; @@ -107,7 +108,7 @@ public abstract class Decision extends AbstractStep { */ public void decide( final Outcome outcome ) throws WikiException { super.setOutcome( outcome ); - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.DQ_REMOVAL ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.DQ_REMOVAL ); } /** @@ -124,7 +125,7 @@ public abstract class Decision extends AbstractStep { } // Put decision in the DecisionQueue - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.DQ_ADDITION ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.DQ_ADDITION ); // Indicate we are waiting for user input return Outcome.STEP_CONTINUE; diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java index 723b5c0..7efeaaf 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/DefaultWorkflowManager.java @@ -25,6 +25,7 @@ import org.apache.wiki.api.exceptions.WikiException; import org.apache.wiki.auth.AuthorizationManager; import org.apache.wiki.auth.acl.UnresolvedPrincipal; import org.apache.wiki.event.WikiEvent; +import org.apache.wiki.event.WikiEventEmitter; import org.apache.wiki.event.WorkflowEvent; import java.security.Principal; @@ -61,7 +62,7 @@ public class DefaultWorkflowManager implements WorkflowManager { m_workflows = ConcurrentHashMap.newKeySet(); m_approvers = new ConcurrentHashMap<>(); m_completed = new CopyOnWriteArrayList<>(); - WorkflowEventEmitter.registerListener( this ); + WikiEventEmitter.attach( this ); } /** diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/Workflow.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/Workflow.java index f06dc16..10386c6 100644 --- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/Workflow.java +++ b/jspwiki-main/src/main/java/org/apache/wiki/workflow/Workflow.java @@ -19,6 +19,7 @@ package org.apache.wiki.workflow; import org.apache.wiki.api.exceptions.WikiException; +import org.apache.wiki.event.WikiEventEmitter; import org.apache.wiki.event.WorkflowEvent; import java.io.Serializable; @@ -226,7 +227,7 @@ public class Workflow implements Serializable { m_owner = owner; m_started = false; m_state = CREATED; - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.CREATED ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.CREATED ); } /** @@ -247,13 +248,13 @@ public class Workflow implements Serializable { if( m_currentStep != null ) { if( m_currentStep instanceof Decision ) { - WorkflowEventEmitter.fireEvent( m_currentStep, WorkflowEvent.DQ_REMOVAL ); + WikiEventEmitter.fireWorkflowEvent( m_currentStep, WorkflowEvent.DQ_REMOVAL ); } m_currentStep.setOutcome( Outcome.STEP_ABORT ); m_history.addLast( m_currentStep ); } m_state = ABORTED; - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.ABORTED ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.ABORTED ); cleanup(); } @@ -474,9 +475,9 @@ public class Workflow implements Serializable { if( m_state != WAITING ) { throw new IllegalStateException( "Workflow is not paused; cannot restart." ); } - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.STARTED ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.STARTED ); m_state = RUNNING; - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.RUNNING ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.RUNNING ); // Process current step try { @@ -536,11 +537,11 @@ public class Workflow implements Serializable { if( m_started ) { throw new IllegalStateException( "Workflow has already started." ); } - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.STARTED ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.STARTED ); m_started = true; m_state = RUNNING; - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.RUNNING ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.RUNNING ); // Mark the first step as the current one & add to history m_currentStep = m_firstStep; m_history.add( m_currentStep ); @@ -563,7 +564,7 @@ public class Workflow implements Serializable { throw new IllegalStateException( "Workflow is not running; cannot pause." ); } m_state = WAITING; - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.WAITING ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.WAITING ); } /** @@ -581,7 +582,7 @@ public class Workflow implements Serializable { protected final synchronized void complete() { if( !isCompleted() ) { m_state = COMPLETED; - WorkflowEventEmitter.fireEvent( this, WorkflowEvent.COMPLETED ); + WikiEventEmitter.fireWorkflowEvent( this, WorkflowEvent.COMPLETED ); cleanup(); } } diff --git a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowEventEmitter.java b/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowEventEmitter.java deleted file mode 100644 index 8ecabd5..0000000 --- a/jspwiki-main/src/main/java/org/apache/wiki/workflow/WorkflowEventEmitter.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you 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.wiki.workflow; - -import org.apache.wiki.event.WikiEventListener; -import org.apache.wiki.event.WikiEventManager; -import org.apache.wiki.event.WorkflowEvent; - -import java.util.Set; - - -/** - * Emits all kind of {@link WorkflowEvent}s. - */ -public enum WorkflowEventEmitter { - - INSTANCE; - - public static WorkflowEventEmitter get() { - return INSTANCE; - } - - public static void fireEvent( final Object src, final int type ) { - if ( WikiEventManager.isListening( get() ) ) { - WikiEventManager.fireEvent( get(), new WorkflowEvent( src, type ) ); - } - } - - public static void registerListener( final WikiEventListener listener ) { - if ( WikiEventManager.isListening( get() ) ) { - final Set< WikiEventListener > attachedListeners = WikiEventManager.getWikiEventListeners( get() ); - attachedListeners.stream() - .filter( l -> listener.getClass().isAssignableFrom( l.getClass() ) ) - .forEach( WikiEventManager::removeWikiEventListener ); - } - WikiEventManager.addWikiEventListener( WorkflowEventEmitter.get(), listener ); - } - -}
