diff --git a/core/src/main/java/org/fourthline/cling/controlpoint/SubscriptionCallback.java b/core/src/main/java/org/fourthline/cling/controlpoint/SubscriptionCallback.java index 5825a7607..542ea622e 100644 --- a/core/src/main/java/org/fourthline/cling/controlpoint/SubscriptionCallback.java +++ b/core/src/main/java/org/fourthline/cling/controlpoint/SubscriptionCallback.java @@ -25,11 +25,13 @@ import org.fourthline.cling.model.meta.LocalService; import org.fourthline.cling.model.meta.RemoteService; import org.fourthline.cling.model.meta.Service; +import org.fourthline.cling.model.state.StateVariableValue; import org.fourthline.cling.protocol.ProtocolCreationException; import org.fourthline.cling.protocol.sync.SendingSubscribe; import org.seamless.util.Exceptions; import java.util.Collections; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -162,10 +164,10 @@ public void ended(CancelReason reason) { } } - public void eventReceived() { + public void eventReceived(Map> changedValues) { synchronized (SubscriptionCallback.this) { log.fine("Local service state updated, notifying callback, sequence is: " + getCurrentSequence()); - SubscriptionCallback.this.eventReceived(this); + SubscriptionCallback.this.eventReceived(this, changedValues); incrementSequence(); } } @@ -178,7 +180,7 @@ public void eventReceived() { localSubscription.establish(); log.fine("Simulating first initial event for local subscription callback, sequence: " + localSubscription.getCurrentSequence()); - eventReceived(localSubscription); + eventReceived(localSubscription, getSubscription().getCurrentValues()); localSubscription.incrementSequence(); log.fine("Starting to monitor state changes of local service"); @@ -218,9 +220,9 @@ public void ended(CancelReason reason, UpnpResponse responseStatus) { } } - public void eventReceived() { + public void eventReceived(Map> changedValues) { synchronized (SubscriptionCallback.this) { - SubscriptionCallback.this.eventReceived(this); + SubscriptionCallback.this.eventReceived(this, changedValues); } } @@ -312,7 +314,7 @@ protected void failed(GENASubscription subscription, UpnpResponse responseStatus * * @param subscription The established subscription with fresh state variable values. */ - protected abstract void eventReceived(GENASubscription subscription); + protected abstract void eventReceived(GENASubscription subscription, Map> changedValues); /** * Called when a received event was out of sequence, indicating that events have been missed. diff --git a/core/src/main/java/org/fourthline/cling/model/gena/GENASubscription.java b/core/src/main/java/org/fourthline/cling/model/gena/GENASubscription.java index ade3ea42e..dbef9f505 100644 --- a/core/src/main/java/org/fourthline/cling/model/gena/GENASubscription.java +++ b/core/src/main/java/org/fourthline/cling/model/gena/GENASubscription.java @@ -15,14 +15,14 @@ package org.fourthline.cling.model.gena; -import java.util.LinkedHashMap; -import java.util.Map; - import org.fourthline.cling.model.UserConstants; import org.fourthline.cling.model.meta.Service; import org.fourthline.cling.model.state.StateVariableValue; import org.fourthline.cling.model.types.UnsignedIntegerFourBytes; +import java.util.LinkedHashMap; +import java.util.Map; + /** * An established subscription, with identifer, expiration duration, sequence handling, and state variable values. *

@@ -87,7 +87,7 @@ synchronized public Map> getCurrentValues() { } public abstract void established(); - public abstract void eventReceived(); + public abstract void eventReceived(Map> changedValues); @Override public String toString() { diff --git a/core/src/main/java/org/fourthline/cling/model/gena/LocalGENASubscription.java b/core/src/main/java/org/fourthline/cling/model/gena/LocalGENASubscription.java index 4b8a81153..caed03d62 100644 --- a/core/src/main/java/org/fourthline/cling/model/gena/LocalGENASubscription.java +++ b/core/src/main/java/org/fourthline/cling/model/gena/LocalGENASubscription.java @@ -27,14 +27,7 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.net.URL; -import java.util.Collection; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -46,9 +39,9 @@ * {@link #registerOnService()} method is called next, and from this point forward all * {@link org.fourthline.cling.model.ServiceManager#EVENTED_STATE_VARIABLES} property change * events are detected by this subscription. After moderation of state variable values - * (frequency and range of changes), the {@link #eventReceived()} method is called. + * (frequency and range of changes), the {@link #eventReceived(Map)} method is called. * Delivery of the event message to the subscriber is not part of this class, but the - * implementor of {@link #eventReceived()}. + * implementor of {@link #eventReceived(Map)}. *

* * @author Christian Bauer @@ -130,7 +123,7 @@ synchronized public void end(CancelReason reason) { /** * Moderates {@link org.fourthline.cling.model.ServiceManager#EVENTED_STATE_VARIABLES} events and state variable - * values, calls {@link #eventReceived()}. + * values, calls {@link #eventReceived(Map)}. */ synchronized public void propertyChange(PropertyChangeEvent e) { if (!e.getPropertyName().equals(ServiceManager.EVENTED_STATE_VARIABLES)) return; @@ -142,11 +135,12 @@ synchronized public void propertyChange(PropertyChangeEvent e) { Collection newValues = (Collection) e.getNewValue(); Set excludedVariables = moderateStateVariables(currentTime, newValues); - currentValues.clear(); + Map> changedValues = new HashMap<>(newValues.size()); for (StateVariableValue newValue : newValues) { String name = newValue.getStateVariable().getName(); if (!excludedVariables.contains(name)) { log.fine("Adding state variable value to current values of event: " + newValue.getStateVariable() + " = " + newValue); + changedValues.put(newValue.getStateVariable().getName(), newValue); currentValues.put(newValue.getStateVariable().getName(), newValue); // Preserve "last sent" state for future moderation @@ -162,7 +156,7 @@ synchronized public void propertyChange(PropertyChangeEvent e) { // TODO: I'm not happy with this design, this dispatches to a separate thread which _then_ // is supposed to lock and read the values off this instance. That obviously doesn't work // so it's currently a hack in SendingEvent.java - eventReceived(); + eventReceived(changedValues); } else { log.fine("No state variable values for event (all moderated out?), not triggering event"); } diff --git a/core/src/main/java/org/fourthline/cling/model/gena/RemoteGENASubscription.java b/core/src/main/java/org/fourthline/cling/model/gena/RemoteGENASubscription.java index 7a5520dad..c98762520 100644 --- a/core/src/main/java/org/fourthline/cling/model/gena/RemoteGENASubscription.java +++ b/core/src/main/java/org/fourthline/cling/model/gena/RemoteGENASubscription.java @@ -26,14 +26,12 @@ import java.beans.PropertyChangeSupport; import java.net.URL; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; +import java.util.*; /** * An outgoing subscription to a remote service. *

- * Once established, calls its {@link #eventReceived()} method whenever an event has + * Once established, calls its {@link #eventReceived(Map)} method whenever an event has * been received from the remote service. *

* @@ -107,13 +105,14 @@ synchronized public void receive(UnsignedIntegerFourBytes sequence, Collection> changedValues = new HashMap<>(newValues.size()); for (StateVariableValue newValue : newValues) { + changedValues.put(newValue.getStateVariable().getName(), newValue); currentValues.put(newValue.getStateVariable().getName(), newValue); } - - eventReceived(); + eventReceived(changedValues); } - + public abstract void invalidMessage(UnsupportedDataException ex); public abstract void failed(UpnpResponse responseStatus); diff --git a/core/src/main/java/org/fourthline/cling/protocol/sync/ReceivingSubscribe.java b/core/src/main/java/org/fourthline/cling/protocol/sync/ReceivingSubscribe.java index 143d5a31d..32f208614 100644 --- a/core/src/main/java/org/fourthline/cling/protocol/sync/ReceivingSubscribe.java +++ b/core/src/main/java/org/fourthline/cling/protocol/sync/ReceivingSubscribe.java @@ -25,12 +25,14 @@ import org.fourthline.cling.model.message.gena.OutgoingSubscribeResponseMessage; import org.fourthline.cling.model.meta.LocalService; import org.fourthline.cling.model.resource.ServiceEventSubscriptionResource; +import org.fourthline.cling.model.state.StateVariableValue; import org.fourthline.cling.protocol.ReceivingSync; import org.fourthline.cling.transport.RouterException; import org.seamless.util.Exceptions; import java.net.URL; import java.util.List; +import java.util.Map; import java.util.logging.Logger; /** @@ -135,13 +137,13 @@ protected OutgoingSubscribeResponseMessage processNewSubscription(LocalService s return new OutgoingSubscribeResponseMessage(UpnpResponse.Status.PRECONDITION_FAILED); } - Integer timeoutSeconds; + Integer timeoutSeconds; if(getUpnpService().getConfiguration().isReceivedSubscriptionTimeoutIgnored()) { timeoutSeconds = null; // Use default value } else { timeoutSeconds = requestMessage.getRequestedTimeoutSeconds(); } - + try { subscription = new LocalGENASubscription(service, timeoutSeconds, callbackURLs) { public void established() { @@ -150,7 +152,7 @@ public void established() { public void ended(CancelReason reason) { } - public void eventReceived() { + public void eventReceived(Map> changedValues) { // The only thing we are interested in, sending an event when the state changes getUpnpService().getConfiguration().getSyncProtocolExecutorService().execute( getUpnpService().getProtocolFactory().createSendingEvent(this) @@ -208,4 +210,4 @@ public void responseException(Throwable t) { log.fine("Response could not be send to subscriber, removing local GENA subscription: " + subscription); getUpnpService().getRegistry().removeLocalSubscription(subscription); } -} \ No newline at end of file +} diff --git a/core/src/test/java/example/controlpoint/EventSubscriptionTest.java b/core/src/test/java/example/controlpoint/EventSubscriptionTest.java index 7fd37d561..bb17ca976 100644 --- a/core/src/test/java/example/controlpoint/EventSubscriptionTest.java +++ b/core/src/test/java/example/controlpoint/EventSubscriptionTest.java @@ -134,7 +134,7 @@ public void ended(GENASubscription sub, } @Override - public void eventReceived(GENASubscription sub) { + public void eventReceived(GENASubscription sub, Map> changedValues) { System.out.println("Event: " + sub.getCurrentSequence().getValue()); @@ -226,4 +226,4 @@ protected StreamResponseMessage createUnsubscribeResponseMessage() { } -} \ No newline at end of file +} diff --git a/core/src/test/java/example/localservice/EventProviderTest.java b/core/src/test/java/example/localservice/EventProviderTest.java index f645cb7d5..5b7d39cb6 100644 --- a/core/src/test/java/example/localservice/EventProviderTest.java +++ b/core/src/test/java/example/localservice/EventProviderTest.java @@ -25,12 +25,14 @@ import org.fourthline.cling.model.message.UpnpResponse; import org.fourthline.cling.model.meta.LocalDevice; import org.fourthline.cling.model.meta.LocalService; +import org.fourthline.cling.model.state.StateVariableValue; import org.fourthline.cling.test.data.SampleData; import org.seamless.util.Reflections; import org.testng.annotations.Test; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static org.testng.Assert.*; @@ -121,7 +123,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(true); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { if (subscription.getCurrentSequence().getValue() == 0) { assertEquals(subscription.getCurrentValues().get("Status").toString(), "0"); testAssertions.add(true); @@ -194,7 +196,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(true); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { if (subscription.getCurrentSequence().getValue() == 0) { assertEquals(subscription.getCurrentValues().get("Target").toString(), "0"); assertEquals(subscription.getCurrentValues().get("Status").toString(), "0"); @@ -282,7 +284,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(true); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { if (subscription.getCurrentSequence().getValue() == 0) { // Initial event contains all evented variables, snapshot of the service state @@ -396,7 +398,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(true); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { if (subscription.getCurrentSequence().getValue() == 0) { // Initial event contains all evented variables, snapshot of the service state diff --git a/core/src/test/java/org/fourthline/cling/test/gena/EventXMLProcessingTest.java b/core/src/test/java/org/fourthline/cling/test/gena/EventXMLProcessingTest.java index db1dedb4e..9db1f6e6c 100644 --- a/core/src/test/java/org/fourthline/cling/test/gena/EventXMLProcessingTest.java +++ b/core/src/test/java/org/fourthline/cling/test/gena/EventXMLProcessingTest.java @@ -37,6 +37,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Map; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertTrue; @@ -96,7 +97,7 @@ public void writeReadRequest(MockUpnpService upnpService) throws Exception { List urls = new ArrayList() {{ add(SampleData.getLocalBaseURL()); }}; - + LocalGENASubscription subscription = new LocalGENASubscription(localService, 1800, urls) { public void failed(Exception ex) { @@ -111,7 +112,7 @@ public void established() { } - public void eventReceived() { + public void eventReceived(Map> changedValues) { } }; diff --git a/core/src/test/java/org/fourthline/cling/test/gena/InvalidEventXMLProcessingTest.java b/core/src/test/java/org/fourthline/cling/test/gena/InvalidEventXMLProcessingTest.java index 7be4dd5b3..8b7dc372e 100644 --- a/core/src/test/java/org/fourthline/cling/test/gena/InvalidEventXMLProcessingTest.java +++ b/core/src/test/java/org/fourthline/cling/test/gena/InvalidEventXMLProcessingTest.java @@ -156,7 +156,7 @@ public void eventsMissed(int numberOfMissedEvents) { public void established() { } - public void eventReceived() { + public void eventReceived(Map> changedValues) { } public void invalidMessage(UnsupportedDataException ex) { diff --git a/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionFailureTest.java b/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionFailureTest.java index 42a00de14..3b73e432b 100644 --- a/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionFailureTest.java +++ b/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionFailureTest.java @@ -38,7 +38,6 @@ import org.fourthline.cling.model.types.UnsignedIntegerFourBytes; import org.fourthline.cling.protocol.ReceivingSync; import org.fourthline.cling.test.data.SampleData; -import org.fourthline.cling.transport.Router; import org.seamless.util.URIUtil; import org.testng.annotations.Test; @@ -47,6 +46,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import static org.testng.Assert.assertEquals; @@ -109,7 +109,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(false); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { testAssertions.add(false); } @@ -177,7 +177,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(true); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { assertEquals(subscription.getCurrentValues().get("Status").toString(), "0"); assertEquals(subscription.getCurrentValues().get("Target").toString(), "1"); testAssertions.add(true); @@ -272,4 +272,4 @@ protected IncomingEventRequestMessage createEventRequestMessage(UpnpService upnp return new IncomingEventRequestMessage(outgoing, ((RemoteGENASubscription) callback.getSubscription()).getService()); } -} \ No newline at end of file +} diff --git a/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionLifecycleTest.java b/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionLifecycleTest.java index af9516656..27d25dd3f 100644 --- a/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionLifecycleTest.java +++ b/core/src/test/java/org/fourthline/cling/test/gena/OutgoingSubscriptionLifecycleTest.java @@ -39,7 +39,6 @@ import org.fourthline.cling.model.types.UnsignedIntegerFourBytes; import org.fourthline.cling.protocol.ProtocolCreationException; import org.fourthline.cling.test.data.SampleData; -import org.fourthline.cling.transport.RouterException; import org.seamless.util.URIUtil; import org.testng.annotations.Test; @@ -47,6 +46,7 @@ import java.net.URL; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.concurrent.Semaphore; import static org.testng.Assert.assertEquals; @@ -103,7 +103,7 @@ public void ended(GENASubscription subscription, CancelReason reason, UpnpRespon testAssertions.add(true); } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { assertEquals(subscription.getCurrentValues().get("Status").toString(), "0"); assertEquals(subscription.getCurrentValues().get("Target").toString(), "1"); testAssertions.add(true); @@ -223,7 +223,7 @@ public void established(GENASubscription subscription) { public void ended(GENASubscription subscription, CancelReason reason, UpnpResponse responseStatus) { } - public void eventReceived(GENASubscription subscription) { + public void eventReceived(GENASubscription subscription, Map> changedValues) { assertEquals(subscription.getCurrentValues().get("Status").toString(), "0"); assertEquals(subscription.getCurrentValues().get("Target").toString(), "1"); testAssertions.add(true); @@ -252,7 +252,7 @@ public void run() { public void established() { } @Override - public void eventReceived() { + public void eventReceived(Map> changedValues) { } @Override public void invalidMessage(UnsupportedDataException ex) {