diff --git a/JACP.API/src/main/java/org/jacpfx/api/message/MessageLogger.java b/JACP.API/src/main/java/org/jacpfx/api/message/MessageLogger.java index 3515e481..5c3e8bd8 100644 --- a/JACP.API/src/main/java/org/jacpfx/api/message/MessageLogger.java +++ b/JACP.API/src/main/java/org/jacpfx/api/message/MessageLogger.java @@ -35,15 +35,15 @@ public interface MessageLogger { * Log message when send by any compinent/perspective/workbench * @param m */ - void onSend(Message m); + void onSend(final Message m); - void handleActive(Message m); + void handleActive(final Message m); - void handleInactive(Message m); + void handleInactive(final Message m); - void handleInCurrentPerspective(Message m); + void handleInCurrentPerspective(final Message m); - void delegate(Message m); + void delegate(final Message m); - void receive(Message m); + void receive(final Message m); } diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/context/JacpContextImpl.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/context/JacpContextImpl.java index 4beb8a7d..41dce8de 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/context/JacpContextImpl.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/context/JacpContextImpl.java @@ -17,6 +17,7 @@ import org.jacpfx.rcp.perspective.FXPerspective; import org.jacpfx.rcp.util.AccessUtil; import org.jacpfx.rcp.util.FXUtil; +import org.jacpfx.rcp.util.MessageLoggerService; import org.jacpfx.rcp.util.PerspectiveUtil; import org.jacpfx.rcp.workbench.FXWorkbench; import org.jacpfx.rcp.worker.AComponentWorker; @@ -102,12 +103,17 @@ public final EventHandler getEventHandler( @Override public final void send(final String targetId, final Object message) { try { - this.globalMessageQueue.put(new MessageImpl(this.fullyQualifiedId, targetId, message, null)); + logAndPutMessage(new MessageImpl(this.fullyQualifiedId, targetId, message, null)); } catch (InterruptedException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } + private void logAndPutMessage(Message m ) throws InterruptedException { + MessageLoggerService.getInstance().onSend(m); + this.globalMessageQueue.transfer(m); + } + /** * {@inheritDoc} */ @@ -117,8 +123,7 @@ public final void send(final Object message) { if (AccessUtil.hasAccess(callerClassName, FXWorkbench.class)) throw new IllegalStateException(" a FXWorkbench is no valid message target"); try { - this.globalMessageQueue.transfer(new MessageImpl(this.fullyQualifiedId,this.id, message, null)); - + logAndPutMessage(new MessageImpl(this.fullyQualifiedId, this.id, message, null)); } catch (InterruptedException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/coordinator/MessageCoordinator.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/coordinator/MessageCoordinator.java index e827486f..2d8040b5 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/coordinator/MessageCoordinator.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/coordinator/MessageCoordinator.java @@ -18,6 +18,7 @@ import org.jacpfx.rcp.registry.ComponentRegistry; import org.jacpfx.rcp.registry.PerspectiveRegistry; import org.jacpfx.rcp.util.FXUtil; +import org.jacpfx.rcp.util.MessageLoggerService; import org.jacpfx.rcp.util.PerspectiveUtil; import org.jacpfx.rcp.util.ShutdownThreadsHandler; @@ -79,17 +80,21 @@ public TransferQueue> getMessageQueue() { @Override public void handleMessage(final String targetId, final Message message) { final MessageCoordinatorExecutionResult result = executeMessageHandling(targetId, message); + final Message messageObject = result.getMessage(); switch (result.getState()) { case HANDLE_ACTIVE: - handleActive(result.getTargetComponent(), result.getMessage()); + MessageLoggerService.getInstance().handleActive(message); + handleActive(result.getTargetComponent(), messageObject); break; case HANDLE_INACTIVE: - handleInActive(result.getTargetComponent(), result.getParentPerspective(), result.getMessage()); + MessageLoggerService.getInstance().handleInactive(message); + handleInActive(result.getTargetComponent(), result.getParentPerspective(), messageObject); break; case HANDLE_CURRENT_PERSPECTIVE: - handleCurrentPerspective(result.getTargetId(), result.getMessage()); + handleCurrentPerspective(result.getTargetId(), message); break; case DELEGATE: + MessageLoggerService.getInstance().delegate(message); delegateMessageToCorrectPerspective(result.getDto()); break; default: diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/handler/PerspectiveHandlerImpl.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/handler/PerspectiveHandlerImpl.java index 9500941f..a0ceff42 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/handler/PerspectiveHandlerImpl.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/handler/PerspectiveHandlerImpl.java @@ -52,6 +52,7 @@ import org.jacpfx.rcp.perspective.AFXPerspective; import org.jacpfx.rcp.registry.PerspectiveRegistry; import org.jacpfx.rcp.util.FXUtil; +import org.jacpfx.rcp.util.MessageLoggerService; import org.jacpfx.rcp.util.TearDownHandler; import org.jacpfx.rcp.workbench.GlobalMediator; @@ -379,6 +380,7 @@ private void handlePerspective(final Message action, // execute OnShow onShow(perspective); } + MessageLoggerService.getInstance().receive(action); if (FXUtil.getTargetPerspectiveId(action.getTargetId()).equals(perspective.getContext().getId())) { this.log("3.4.3.1: perspective handle with custom message"); perspective.handlePerspective(action); diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/ActionListenerImpl.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/ActionListenerImpl.java index 3e86ffbe..52251874 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/ActionListenerImpl.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/ActionListenerImpl.java @@ -26,6 +26,7 @@ import javafx.event.EventHandler; import org.jacpfx.api.message.ActionListener; import org.jacpfx.api.message.Message; +import org.jacpfx.rcp.util.MessageLoggerService; import java.util.Objects; import java.util.concurrent.TransferQueue; @@ -52,13 +53,18 @@ public ActionListenerImpl(final Message action, public void notifyComponents(final Message action) { Objects.requireNonNull(action,"message cannot be null"); try { - this.globalMessageQueue.transfer(action); + logAndPutMessage(action); } catch (InterruptedException e) { e.printStackTrace(); //TODO handle exception global } } + private void logAndPutMessage(Message m ) throws InterruptedException { + MessageLoggerService.getInstance().onSend(m); + this.globalMessageQueue.transfer(m); + } + @Override public void handle(final Event t) { diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/MessageImpl.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/MessageImpl.java index 826195bd..62a38942 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/MessageImpl.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/message/MessageImpl.java @@ -1,5 +1,4 @@ /************************************************************************ - * * Copyright (C) 2010 - 2014 * * [FX2Action.java] @@ -8,17 +7,15 @@ * * 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 + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * 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 + * 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.jacpfx.rcp.message; @@ -28,83 +25,95 @@ /** * represents an message which is fired by an component, has a target and a * message targeting the component itself or an other component - * + * * @author Andy Moncsek */ public final class MessageImpl implements Message { - private Object message; - private final String sourceId; - private final Event event; - private String target; - - public MessageImpl(final String sourceId) { - this.sourceId = sourceId; - this.event = null; - } - - public MessageImpl(final String sourceId, final Event event) { - this.sourceId = sourceId; - this.event = event; - } - - public MessageImpl(final String sourceId, final Object message) { - this.sourceId = sourceId; - this.setMessageBody(message); - this.event = null; - } - - public MessageImpl(final String sourceId, final String targetId, + private Object message; + private final String sourceId; + private final Event event; + private String target; + + public MessageImpl(final String sourceId) { + this.sourceId = sourceId; + this.event = null; + } + + public MessageImpl(final String sourceId, final Event event) { + this.sourceId = sourceId; + this.event = event; + } + + public MessageImpl(final String sourceId, final Object message) { + this.sourceId = sourceId; + this.setMessageBody(message); + this.event = null; + } + + public MessageImpl(final String sourceId, final String targetId, final Object message, final Event event) { - this.sourceId = sourceId; - this.target = targetId; - this.event = event; - this.setMessageBody(message); - } - - - private void setMessageBody(final Object message) { - this.message = message; - this.target = this.target != null ? this.target : this.sourceId; - } - - - @Override - public Object getMessageBody() { - return this.message; - } - - @Override - public String getSourceId() { - return this.sourceId; - } - - @Override - public Event getSourceEvent() { - return this.event; - } - - @Override - public Message cloneMessage() { - return new MessageImpl(this.sourceId,this.target, this.message, this.event); - } - - @Override - public String getTargetId() { - return this.target; - } + this.sourceId = sourceId; + this.target = targetId; + this.event = event; + this.setMessageBody(message); + } + + + private void setMessageBody(final Object message) { + this.message = message; + this.target = this.target != null ? this.target : this.sourceId; + } + + + @Override + public Object getMessageBody() { + return this.message; + } + + @Override + public String getSourceId() { + return this.sourceId; + } + + @Override + public Event getSourceEvent() { + return this.event; + } + + @Override + public Message cloneMessage() { + return new MessageImpl(this.sourceId, this.target, this.message, this.event); + } + + @Override + public String getTargetId() { + return this.target; + } @Override public boolean isMessageBodyTypeOf(final Class clazz) { return clazz.isAssignableFrom(this.message.getClass()); } + @Override public T getTypedMessageBody(final Class clazz) { return clazz.cast(this.message); } + @Override public boolean messageBodyEquals(Object object) { return object.equals(this.message); } + + @Override + public String toString() { + return "MessageImpl{" + + "message=" + message + + ", sourceId='" + sourceId + '\'' + + ", event=" + event + + ", target='" + target + '\'' + + '}'; + } } diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/util/MessageLoggerService.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/util/MessageLoggerService.java new file mode 100644 index 00000000..5f390657 --- /dev/null +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/util/MessageLoggerService.java @@ -0,0 +1,129 @@ +/* + * ********************************************************************** + * + * Copyright (C) 2010 - 2015 + * + * [Component.java] + * JACPFX Project (https://github.com/JacpFX/JacpFX/) + * All rights reserved. + * + * 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.jacpfx.rcp.util; + +import org.jacpfx.api.message.Message; +import org.jacpfx.api.message.MessageLogger; + +import java.util.ArrayList; +import java.util.List; +import java.util.ServiceLoader; +import java.util.function.Consumer; + +/** + * Created by Andy Moncsek on 14.07.15. + */ +public class MessageLoggerService implements MessageLogger { + private static MessageLoggerService service; + private ServiceLoader loader; + private final List logger = new ArrayList(); + + private MessageLoggerService() { + loader = ServiceLoader.load(MessageLogger.class); + if (loader.iterator().hasNext()) { + loader.forEach(logger::add); + } else { + logger.add(new EmptyLogger()); + } + + } + + public static synchronized MessageLoggerService getInstance() { + if (service == null) { + service = new MessageLoggerService(); + } + return service; + } + + @Override + public void onSend(Message m) { + execute((consumer -> consumer.onSend(m))); + } + + + @Override + public void handleActive(Message m) { + execute((consumer -> consumer.handleActive(m))); + } + + @Override + public void handleInactive(Message m) { + execute((consumer -> consumer.handleInactive(m))); + } + + @Override + public void handleInCurrentPerspective(Message m) { + execute((consumer -> consumer.handleInCurrentPerspective(m))); + } + + @Override + public void delegate(Message m) { + execute((consumer -> consumer.delegate(m))); + } + + @Override + public void receive(Message m) { + execute((consumer -> consumer.receive(m))); + } + + private void execute(Consumer c) { + logger.forEach(c::accept); + } + + + private static class EmptyLogger implements MessageLogger { + + @Override + public void onSend(Message m) { + + } + + @Override + public void handleActive(Message m) { + + } + + @Override + public void handleInactive(Message m) { + + } + + @Override + public void handleInCurrentPerspective(Message m) { + + } + + @Override + public void delegate(Message m) { + + } + + @Override + public void receive(Message m) { + + } + } +} diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedCallbackComponentWorker.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedCallbackComponentWorker.java index e4d90e9a..812d065c 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedCallbackComponentWorker.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedCallbackComponentWorker.java @@ -34,6 +34,7 @@ import org.jacpfx.rcp.context.InternalContext; import org.jacpfx.rcp.registry.ComponentRegistry; import org.jacpfx.rcp.registry.PerspectiveRegistry; +import org.jacpfx.rcp.util.MessageLoggerService; import org.jacpfx.rcp.util.ShutdownThreadsHandler; import org.jacpfx.rcp.util.TearDownHandler; import org.jacpfx.rcp.util.WorkerUtil; @@ -71,6 +72,7 @@ public void run() { final Message myAction = this.component .getNextIncomingMessage(); this.component.lock(); + MessageLoggerService.getInstance().receive(myAction); checkValidComponent(this.component); wasExecuted = true; final InternalContext context = InternalContext.class.cast(this.component.getContext()); diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedFXComponentWorker.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedFXComponentWorker.java index 3822317c..99752a3a 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedFXComponentWorker.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/EmbeddedFXComponentWorker.java @@ -90,6 +90,7 @@ private void handleComponentExecution(final EmbeddedFXComponent component, final try { final Message myAction = component .getNextIncomingMessage(); + MessageLoggerService.getInstance().receive(myAction); final Node previousContainer = component.getRoot(); final InternalContext contextImpl = InternalContext.class.cast(component.getContext()); final String currentTargetLayout = contextImpl.getTargetLayout(); diff --git a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/StateLessComponentRunWorker.java b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/StateLessComponentRunWorker.java index 7f22fbf0..e357a0e4 100644 --- a/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/StateLessComponentRunWorker.java +++ b/JACP.JavaFX/src/main/java/org/jacpfx/rcp/worker/StateLessComponentRunWorker.java @@ -33,6 +33,7 @@ import org.jacpfx.rcp.component.ASubComponent; import org.jacpfx.rcp.context.InternalContext; import org.jacpfx.rcp.registry.PerspectiveRegistry; +import org.jacpfx.rcp.util.MessageLoggerService; import org.jacpfx.rcp.util.TearDownHandler; import org.jacpfx.rcp.util.WorkerUtil; @@ -67,6 +68,7 @@ protected SubComponent, Event, Object> call() while (this.component.hasIncomingMessage()) { final Message myAction = this.component .getNextIncomingMessage(); + MessageLoggerService.getInstance().receive(myAction); final InternalContext context = InternalContext.class.cast(this.component.getContext()); context.updateActiveState(true); context.updateReturnTarget(myAction.getSourceId()); diff --git a/JacpFX-TestCases/src/main/java/org/jacp/logger/CustomLogger.java b/JacpFX-TestCases/src/main/java/org/jacp/logger/CustomLogger.java new file mode 100644 index 00000000..497f2989 --- /dev/null +++ b/JacpFX-TestCases/src/main/java/org/jacp/logger/CustomLogger.java @@ -0,0 +1,64 @@ +/* + * ********************************************************************** + * + * Copyright (C) 2010 - 2015 + * + * [Component.java] + * JACPFX Project (https://github.com/JacpFX/JacpFX/) + * All rights reserved. + * + * 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.jacp.logger; + +import org.jacpfx.api.message.Message; +import org.jacpfx.api.message.MessageLogger; + +/** + * Created by Andy Moncsek on 15.07.15. + */ +public class CustomLogger implements MessageLogger { + @Override + public void onSend(Message m) { + System.out.println("onsend: "+m); + } + + @Override + public void handleActive(Message m) { + System.out.println("handleActive: "+m); + } + + @Override + public void handleInactive(Message m) { + System.out.println("handleInactive: "+m); + } + + @Override + public void handleInCurrentPerspective(Message m) { + System.out.println("handleInCurrentPerspective: "+m); + } + + @Override + public void delegate(Message m) { + System.out.println("delegate: "+m); + } + + @Override + public void receive(Message m) { + System.out.println("receive: "+m); + } +} diff --git a/JacpFX-TestCases/src/main/resources/services/org.jacpfx.api.message.MessageLogger b/JacpFX-TestCases/src/main/resources/services/org.jacpfx.api.message.MessageLogger new file mode 100644 index 00000000..26500e26 --- /dev/null +++ b/JacpFX-TestCases/src/main/resources/services/org.jacpfx.api.message.MessageLogger @@ -0,0 +1 @@ +#org.jacp.logger.CustomLogger \ No newline at end of file diff --git a/JacpFX-TestCases/src/test/java/org/jacp/test/lifecycle/LoggerServiceTest.java b/JacpFX-TestCases/src/test/java/org/jacp/test/lifecycle/LoggerServiceTest.java new file mode 100644 index 00000000..41361ae3 --- /dev/null +++ b/JacpFX-TestCases/src/test/java/org/jacp/test/lifecycle/LoggerServiceTest.java @@ -0,0 +1,32 @@ +/* + * ********************************************************************** + * + * Copyright (C) 2010 - 2015 + * + * [Component.java] + * JACPFX Project (https://github.com/JacpFX/JacpFX/) + * All rights reserved. + * + * 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.jacp.test.lifecycle; + +/** + * Created by Andy Moncsek on 15.07.15. + */ +public class LoggerServiceTest { +} diff --git a/JacpFX-TestCases/src/test/resources/META-INF/services/org.jacpfx.api.message.MessageLogger b/JacpFX-TestCases/src/test/resources/META-INF/services/org.jacpfx.api.message.MessageLogger new file mode 100644 index 00000000..26500e26 --- /dev/null +++ b/JacpFX-TestCases/src/test/resources/META-INF/services/org.jacpfx.api.message.MessageLogger @@ -0,0 +1 @@ +#org.jacp.logger.CustomLogger \ No newline at end of file