-
Notifications
You must be signed in to change notification settings - Fork 408
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce transactional listener to regroup notifications.
- Loading branch information
1 parent
6ef4932
commit b687e5c
Showing
2 changed files
with
197 additions
and
52 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
123 changes: 123 additions & 0 deletions
123
...nt-core/src/main/java/org/eclipse/leshan/client/resource/TransactionalObjectListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
/******************************************************************************* | ||
* Copyright (c) 2020 Sierra Wireless and others. | ||
* | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* and Eclipse Distribution License v1.0 which accompany this distribution. | ||
* | ||
* The Eclipse Public License is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
* and the Eclipse Distribution License is available at | ||
* http://www.eclipse.org/org/documents/edl-v10.html. | ||
* | ||
* Contributors: | ||
* Sierra Wireless - initial API and implementation | ||
*******************************************************************************/ | ||
package org.eclipse.leshan.client.resource; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.eclipse.leshan.client.resource.listener.ObjectListener; | ||
|
||
/** | ||
* An {@link ObjectListener} which is able to store notification during transaction and raise all grouped event at the | ||
* end of the transaction. | ||
* <p> | ||
* This class is not threadsafe. | ||
*/ | ||
public class TransactionalObjectListener implements ObjectListener { | ||
private boolean inTransaction = false; | ||
private List<Integer> instancesAdded = new ArrayList<>(); | ||
private List<Integer> instancesRemoved = new ArrayList<>(); | ||
private Map<Integer, List<Integer>> resourcesChangedByInstance = new HashMap<>(); | ||
|
||
private LwM2mObjectEnabler objectEnabler; | ||
private ObjectListener innerListener; | ||
|
||
public TransactionalObjectListener(LwM2mObjectEnabler objectEnabler, ObjectListener listener) { | ||
this.objectEnabler = objectEnabler; | ||
this.innerListener = listener; | ||
} | ||
|
||
public void beginTransaction() { | ||
inTransaction = true; | ||
} | ||
|
||
public void endTransaction() { | ||
fireStoredEvents(); | ||
instancesAdded.clear(); | ||
instancesRemoved.clear(); | ||
resourcesChangedByInstance.clear(); | ||
inTransaction = false; | ||
} | ||
|
||
private void fireStoredEvents() { | ||
if (!instancesAdded.isEmpty()) | ||
innerListener.objectInstancesAdded(objectEnabler, toIntArray(instancesAdded)); | ||
if (!instancesRemoved.isEmpty()) | ||
innerListener.objectInstancesRemoved(objectEnabler, toIntArray(instancesRemoved)); | ||
|
||
for (Map.Entry<Integer, List<Integer>> entry : resourcesChangedByInstance.entrySet()) { | ||
innerListener.resourceChanged(objectEnabler, entry.getKey(), toIntArray(entry.getValue())); | ||
} | ||
} | ||
|
||
@Override | ||
public void objectInstancesAdded(LwM2mObjectEnabler object, int... instanceIds) { | ||
if (!inTransaction) { | ||
innerListener.objectInstancesAdded(object, instanceIds); | ||
} else { | ||
// store additions | ||
for (int instanceId : instanceIds) { | ||
if (instancesRemoved.contains(instanceId)) { | ||
instancesRemoved.remove(instanceId); | ||
} else if (!instancesAdded.contains(instanceId)) { | ||
instancesAdded.add(instanceId); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void objectInstancesRemoved(LwM2mObjectEnabler object, int... instanceIds) { | ||
if (!inTransaction) { | ||
innerListener.objectInstancesRemoved(object, instanceIds); | ||
} else { | ||
// store deletion | ||
for (int instanceId : instanceIds) { | ||
if (instancesAdded.contains(instanceId)) { | ||
instancesAdded.remove(instanceId); | ||
} else if (!instancesRemoved.contains(instanceId)) { | ||
instancesRemoved.add(instanceId); | ||
} | ||
} | ||
} | ||
} | ||
|
||
@Override | ||
public void resourceChanged(LwM2mObjectEnabler object, int instanceId, int... resourcesIds) { | ||
if (!inTransaction) { | ||
innerListener.resourceChanged(object, instanceId, resourcesIds); | ||
} else { | ||
List<Integer> resourcesChanged = resourcesChangedByInstance.get(instanceId); | ||
if (resourcesChanged == null) { | ||
resourcesChanged = new ArrayList<Integer>(); | ||
resourcesChangedByInstance.put(instanceId, resourcesChanged); | ||
} | ||
for (int resourceId : resourcesIds) { | ||
resourcesChanged.add(resourceId); | ||
} | ||
} | ||
} | ||
|
||
private int[] toIntArray(List<Integer> list) { | ||
int[] ret = new int[list.size()]; | ||
int i = 0; | ||
for (Integer e : list) | ||
ret[i++] = e; | ||
return ret; | ||
} | ||
} |