Author: jawi
Date: Fri Apr 13 09:15:10 2012
New Revision: 1325679
URL: http://svn.apache.org/viewvc?rev=1325679&view=rev
Log:
ACE-258: fixed some concurrency issues on the repository admin (related)
classes.
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminLoginContextImpl.java
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySerializer.java
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySet.java
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ArtifactTest.java
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ModelTest.java
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/ArtifactRepositoryImpl.java
Fri Apr 13 09:15:10 2012
@@ -18,7 +18,6 @@
*/
package org.apache.ace.client.repository.impl;
-import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminImpl.java
Fri Apr 13 09:15:10 2012
@@ -141,23 +141,27 @@ public class RepositoryAdminImpl impleme
@SuppressWarnings("unchecked")
public void start() {
- initialize(publishRepositories());
+ synchronized (m_lock) {
+ initialize(publishRepositories());
+ }
}
public void stop() {
pullRepositories();
- if (loggedIn()) {
- try {
- logout(true);
- }
- catch (IOException ioe) {
- m_log.log(LogService.LOG_ERROR, "Failed to log out of the
repositories.", ioe);
+ synchronized (m_lock) {
+ if (loggedIn()) {
+ try {
+ logout(true);
+ }
+ catch (IOException ioe) {
+ m_log.log(LogService.LOG_ERROR, "Failed to log out of the
repositories.", ioe);
+ }
}
}
}
@SuppressWarnings("unchecked")
- synchronized Map<Class<? extends ObjectRepository>, ObjectRepositoryImpl>
publishRepositories() {
+ private Map<Class<? extends ObjectRepository>, ObjectRepositoryImpl>
publishRepositories() {
// create the repository objects, if this is the first time this
method is called.
if (m_artifactRepositoryImpl == null) {
m_artifactRepositoryImpl = new
ArtifactRepositoryImpl(m_changeNotifierManager.getConfiguredNotifier(RepositoryObject.PRIVATE_TOPIC_ROOT,
RepositoryObject.PUBLIC_TOPIC_ROOT, ArtifactObject.TOPIC_ENTITY_ROOT,
m_sessionID));
@@ -210,10 +214,11 @@ public class RepositoryAdminImpl impleme
return result;
}
+
/**
* Pulls all repository services; is used to make sure the repositories go
away before the RepositoryAdmin does.
*/
- synchronized void pullRepositories() {
+ private void pullRepositories() {
for (Component[] services : m_services) {
for (Component service : services) {
m_manager.remove(service);
@@ -278,8 +283,8 @@ public class RepositoryAdminImpl impleme
}
public void revert() throws IOException {
- ensureLogin();
synchronized (m_lock) {
+ ensureLogin();
for (RepositorySet set : m_repositorySets) {
set.revert();
}
@@ -288,8 +293,8 @@ public class RepositoryAdminImpl impleme
}
public boolean isCurrent() throws IOException {
- ensureLogin();
synchronized (m_lock) {
+ ensureLogin();
boolean result = true;
for (RepositorySet set : m_repositorySets) {
result &= (set.isCurrent() || !set.writeAccess());
@@ -299,12 +304,15 @@ public class RepositoryAdminImpl impleme
}
public boolean isModified() {
- ensureLogin();
- boolean result = false;
- for (RepositorySet set : m_repositorySets) {
- result |= set.isModified();
+ synchronized (m_lock) {
+ ensureLogin();
+ for (RepositorySet set : m_repositorySets) {
+ if (set.isModified()) {
+ return true;
+ }
+ }
+ return false;
}
- return result;
}
public RepositoryAdminLoginContext createLoginContext(User user) {
@@ -321,9 +329,12 @@ public class RepositoryAdminImpl impleme
RepositoryAdminLoginContextImpl impl =
((RepositoryAdminLoginContextImpl) context);
RepositorySet[] repositorySets = getRepositorySets(impl);
- // TODO I don't like this line, it should not be here...
- ((ArtifactRepositoryImpl)
m_repositories.get(ArtifactRepository.class)).setObrBase(impl.getObrBase());
- login(impl.getUser(), repositorySets);
+
+ synchronized(m_lock) {
+ // TODO I don't like this line, it should not be here...
+ ((ArtifactRepositoryImpl)
m_repositories.get(ArtifactRepository.class)).setObrBase(impl.getObrBase());
+ login(impl.getUser(), repositorySets);
+ }
}
/**
@@ -331,7 +342,7 @@ public class RepositoryAdminImpl impleme
* testing purposes.
* @throws IOException
*/
- void login(User user, RepositorySet[] sets) throws IOException {
+ private void login(User user, RepositorySet[] sets) throws IOException {
synchronized(m_lock) {
if (m_user != null) {
throw new IllegalStateException("Another user is logged in.");
@@ -379,7 +390,7 @@ public class RepositoryAdminImpl impleme
}
}
- boolean loggedIn() {
+ private boolean loggedIn() {
return m_user != null;
}
@@ -528,20 +539,25 @@ public class RepositoryAdminImpl impleme
public int getNumberWithWorkingState(Class<? extends RepositoryObject>
clazz, WorkingState state) {
int result = 0;
- for (RepositorySet set : m_repositorySets) {
- result += set.getNumberWithWorkingState(clazz, state);
+ synchronized (m_lock) {
+ for (RepositorySet set : m_repositorySets) {
+ result += set.getNumberWithWorkingState(clazz, state);
+ }
}
return result;
}
public WorkingState getWorkingState(RepositoryObject object) {
- for (RepositorySet set : m_repositorySets) {
- WorkingState result = set.getWorkingState(object);
- if (result != null) {
- return result;
+ WorkingState result = null;
+ synchronized (m_lock) {
+ for (RepositorySet set : m_repositorySets) {
+ result = set.getWorkingState(object);
+ if (result != null) {
+ break;
+ }
}
}
- return WorkingState.Unchanged;
+ return (result == null) ? WorkingState.Unchanged : result;
}
public void addArtifactHelper(ServiceReference ref, ArtifactHelper helper)
{
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminLoginContextImpl.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminLoginContextImpl.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminLoginContextImpl.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryAdminLoginContextImpl.java
Fri Apr 13 09:15:10 2012
@@ -35,10 +35,10 @@ import org.apache.ace.client.repository.
import org.osgi.service.useradmin.User;
class RepositoryAdminLoginContextImpl implements RepositoryAdminLoginContext {
+ private final String m_sessionid;
private final User m_user;
private final List<RepositorySetDescriptor> m_descriptors = new
ArrayList<RepositorySetDescriptor>();
private URL m_obrBase;
- private final String m_sessionid;
RepositoryAdminLoginContextImpl(User user, String sessionid) {
m_user = user;
@@ -80,6 +80,10 @@ class RepositoryAdminLoginContextImpl im
DeploymentVersionRepository.class);
}
+ public List<RepositorySetDescriptor> getDescriptors() {
+ return m_descriptors;
+ }
+
public RepositoryAdminLoginContext setObrBase(URL base) {
m_obrBase = base;
return this;
@@ -92,9 +96,9 @@ class RepositoryAdminLoginContextImpl im
User getUser() {
return m_user;
}
-
- public List<RepositorySetDescriptor> getDescriptors() {
- return m_descriptors;
+
+ String getSessionId() {
+ return m_sessionid;
}
/**
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositoryObjectImpl.java
Fri Apr 13 09:15:10 2012
@@ -33,10 +33,9 @@ public class RepositoryObjectImpl<T exte
private final Map<String, String> m_tags = new HashMap<String, String>();
@SuppressWarnings("unchecked")
private final Map<Class, List<Association>> m_associations = new
HashMap<Class, List<Association>>();
-
private final ChangeNotifier m_notifier;
-
private final String m_xmlNode;
+
private volatile boolean m_deleted = false;
private volatile boolean m_busy = false;
@@ -78,7 +77,6 @@ public class RepositoryObjectImpl<T exte
/**
* Returns an enumeration of the values in this object's dictionary.
*/
-
@Override
public Enumeration<Object> elements() {
synchronized (m_attributes) {
@@ -90,7 +88,6 @@ public class RepositoryObjectImpl<T exte
* Gets the object associated with this key. Will return null when the key
is not used; if the key is available for both the
* tags and the object's basic information, an array of two Strings will
be returned.
*/
-
@Override
public Object get(Object key) {
synchronized (m_attributes) {
@@ -112,7 +109,6 @@ public class RepositoryObjectImpl<T exte
/**
* Return whether the dictionary is empty.
*/
-
@Override
public boolean isEmpty() {
synchronized (m_attributes) {
@@ -123,7 +119,6 @@ public class RepositoryObjectImpl<T exte
/**
* Returns an enumeration of the keys in this object.
*/
-
@Override
public Enumeration<String> keys() {
synchronized (m_attributes) {
@@ -135,30 +130,28 @@ public class RepositoryObjectImpl<T exte
}
/**
- * @throws UnsupportedOperationException
+ * Unsupported operation.
+ *
+ * @throws UnsupportedOperationException always
*/
-
@Override
- public Object put(@SuppressWarnings("unused")
- String key, @SuppressWarnings("unused")
- Object value) {
+ public Object put(String key, Object value) {
throw new UnsupportedOperationException();
}
/**
- * @throws UnsupportedOperationException
+ * Unsupported operation.
+ *
+ * @throws UnsupportedOperationException always
*/
-
@Override
- public Object remove(@SuppressWarnings("unused")
- Object key) {
+ public Object remove(Object key) {
throw new UnsupportedOperationException();
}
/**
* Returns the number of keys in both this object's tags, and its 'member'
keys.
*/
-
@Override
public int size() {
synchronized (m_attributes) {
@@ -169,47 +162,6 @@ public class RepositoryObjectImpl<T exte
}
}
- /**
- * Helper class that implements an enumeration for use in
<code>keys()</code>.
- */
- private class KeysEnumeration implements Enumeration<String> {
- private final Iterator<String> m_iter;
-
- public KeysEnumeration(Iterator<String> iter) {
- m_iter = iter;
- }
-
-
- public boolean hasMoreElements() {
- return m_iter.hasNext();
- }
-
-
- public String nextElement() {
- return m_iter.next();
- }
-
- }
-
- /**
- * Helper class that implements an enumeration for use in
<code>elements()</code>.
- */
- private class ValuesEnumeration implements Enumeration<Object> {
- private final Enumeration<String> m_iter = keys();
-
-
- public boolean hasMoreElements() {
- return m_iter.hasMoreElements();
- }
-
-
- public Object nextElement() {
- return get(m_iter.nextElement());
- }
-
- }
-
-
public String addAttribute(String key, String value) {
for (String s : getDefiningKeys()) {
if (s.equals(key)) {
@@ -223,7 +175,6 @@ public class RepositoryObjectImpl<T exte
}
}
-
public String addTag(String key, String value) {
synchronized (m_attributes) {
ensureCurrent();
@@ -232,33 +183,28 @@ public class RepositoryObjectImpl<T exte
}
}
-
public String getAttribute(String key) {
synchronized (m_attributes) {
return m_attributes.get(key);
}
}
-
public String getTag(String key) {
synchronized (m_attributes) {
return m_tags.get(key);
}
}
-
public Enumeration<String> getAttributeKeys() {
synchronized (m_attributes) {
return new KeysEnumeration(new
HashSet<String>(m_attributes.keySet()).iterator());
}
}
-
public Dictionary<String, Object> getDictionary() {
return this;
}
-
public Enumeration<String> getTagKeys() {
synchronized (m_attributes) {
return new KeysEnumeration(new
HashSet<String>(m_tags.keySet()).iterator());
@@ -606,4 +552,37 @@ public class RepositoryObjectImpl<T exte
return null;
}
+ /**
+ * Helper class that implements an enumeration for use in
<code>keys()</code>.
+ */
+ private static class KeysEnumeration implements Enumeration<String> {
+ private final Iterator<String> m_iter;
+
+ public KeysEnumeration(Iterator<String> iter) {
+ m_iter = iter;
+ }
+
+ public boolean hasMoreElements() {
+ return m_iter.hasNext();
+ }
+
+ public String nextElement() {
+ return m_iter.next();
+ }
+ }
+
+ /**
+ * Helper class that implements an enumeration for use in
<code>elements()</code>.
+ */
+ private class ValuesEnumeration implements Enumeration<Object> {
+ private final Enumeration<String> m_iter = keys();
+
+ public boolean hasMoreElements() {
+ return m_iter.hasMoreElements();
+ }
+
+ public Object nextElement() {
+ return get(m_iter.nextElement());
+ }
+ }
}
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySerializer.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySerializer.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySerializer.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySerializer.java
Fri Apr 13 09:15:10 2012
@@ -86,9 +86,14 @@ class RepositorySerializer implements Co
for (ObjectRepositoryImpl repo : m_set.getRepos()) {
repo.setBusy(true);
}
- m_stream.toXML(this, out);
- for (ObjectRepositoryImpl repo : m_set.getRepos()) {
- repo.setBusy(false);
+ try {
+ m_stream.toXML(this, out);
+ }
+ finally {
+ // Ensure all busy flags are reset at all times...
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.setBusy(false);
+ }
}
}
@@ -119,9 +124,10 @@ class RepositorySerializer implements Co
}
finally {
Thread.currentThread().setContextClassLoader(cl);
- }
- for (ObjectRepositoryImpl repo : m_set.getRepos()) {
- repo.setBusy(false);
+ // Ensure all busy flags are reset at all times...
+ for (ObjectRepositoryImpl repo : m_set.getRepos()) {
+ repo.setBusy(false);
+ }
}
}
}
Modified:
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySet.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySet.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySet.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/main/java/org/apache/ace/client/repository/impl/RepositorySet.java
Fri Apr 13 09:15:10 2012
@@ -18,6 +18,7 @@
*/
package org.apache.ace.client.repository.impl;
+import java.io.Closeable;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
@@ -27,12 +28,14 @@ import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Properties;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import org.apache.ace.client.repository.ObjectRepository;
import org.apache.ace.client.repository.RepositoryAdmin;
import org.apache.ace.client.repository.RepositoryObject;
-import org.apache.ace.client.repository.SessionFactory;
import org.apache.ace.client.repository.RepositoryObject.WorkingState;
+import org.apache.ace.client.repository.SessionFactory;
import org.apache.ace.repository.ext.CachedRepository;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceRegistration;
@@ -60,11 +63,11 @@ class RepositorySet {
private final CachedRepository m_repository;
private final String m_name;
private final boolean m_writeAccess;
-
- private final Map<RepositoryObject, WorkingState> m_workingState = new
HashMap<RepositoryObject, WorkingState>();
- private ServiceRegistration m_modifiedHandler;
+ private final ConcurrentMap<RepositoryObject, WorkingState> m_workingState;
private final ChangeNotifier m_notifier;
private final LogService m_log;
+
+ private volatile ServiceRegistration m_modifiedHandler;
/* ********
* Basics
@@ -80,6 +83,7 @@ class RepositorySet {
* </ul>
*/
RepositorySet(ChangeNotifier notifier, LogService log, User user,
Preferences prefs, ObjectRepositoryImpl[] repos, CachedRepository repository,
String name, boolean writeAccess) {
+ m_workingState = new ConcurrentHashMap<RepositoryObject,
WorkingState>();
m_notifier = notifier;
m_log = log;
m_user = user;
@@ -90,12 +94,22 @@ class RepositorySet {
m_writeAccess = writeAccess;
}
+ void unregisterHandler() {
+ m_modifiedHandler.unregister();
+ m_modifiedHandler = null;
+ }
+
+ boolean writeAccess() {
+ return m_writeAccess;
+ }
+
boolean isModified() {
- boolean modified = false;
- for (Map.Entry<RepositoryObject, WorkingState> entry :
m_workingState.entrySet()) {
- modified |= !(entry.getValue().equals(WorkingState.Unchanged));
+ for (WorkingState workingState : m_workingState.values()) {
+ if (!WorkingState.Unchanged.equals(workingState)) {
+ return true;
+ }
}
- return modified;
+ return false;
}
User getUser() {
@@ -126,6 +140,7 @@ class RepositorySet {
m_log.log(LogService.LOG_WARNING, "Could not store all preferences
for " + workingNode.absolutePath());
e.printStackTrace();
}
+
for (Map.Entry<RepositoryObject, WorkingState> entry :
m_workingState.entrySet()) {
workingNode.node(entry.getKey().getDefinition()).put(PREFS_LOCAL_WORKING_STATE_VALUE,
entry.getValue().toString());
}
@@ -141,13 +156,16 @@ class RepositorySet {
Map<String, WorkingState> entries = new HashMap<String,
WorkingState>();
// First, get all nodes and their workingstate.
try {
+ String defaultWorkingState = WorkingState.Unchanged.toString();
+
for (String node : workingNode.childrenNames()) {
- String state =
workingNode.node(node).get(PREFS_LOCAL_WORKING_STATE_VALUE,
WorkingState.Unchanged.toString());
+ String state =
workingNode.node(node).get(PREFS_LOCAL_WORKING_STATE_VALUE,
defaultWorkingState);
entries.put(node, WorkingState.valueOf(state));
}
}
catch (BackingStoreException e) {
// Something went wrong reading from the store, just work with
whatever we have in the map.
+ m_log.log(LogService.LOG_WARNING, "Could not load all preferences
for " + workingNode.absolutePath());
e.printStackTrace();
}
// Then, go through all objects and check whether they match a
definition we know.
@@ -167,35 +185,24 @@ class RepositorySet {
* ********/
boolean readLocal() throws IOException {
- InputStream input = m_repository.getLocal(false);
+ InputStream input = m_repository.getLocal(false /* fail */);
if (input.available() > 0) {
read(input);
return true;
}
else {
- try {
- input.close();
- }
- catch (IOException e) {
- // This does not matter now.
- }
+ closeSafely(input);
return false;
}
}
void read(InputStream input) {
new RepositorySerializer(this).fromXML(input);
- try {
- input.close();
- }
- catch (IOException e) {
- // Not much we can do...
- e.printStackTrace();
- }
+ closeSafely(input);
}
void writeLocal() throws IOException {
- PipedInputStream input = new PipedInputStream();
+ final PipedInputStream input = new PipedInputStream();
final PipedOutputStream output = new PipedOutputStream(input);
new Thread(new Runnable() {
public void run() {
@@ -245,11 +252,17 @@ class RepositorySet {
for (ObjectRepositoryImpl repo : getRepos()) {
repo.setBusy(true);
}
- for (ObjectRepositoryImpl repo : getRepos()) {
- repo.removeAll();
+
+ try {
+ for (ObjectRepositoryImpl repo : getRepos()) {
+ repo.removeAll();
+ }
}
- for (ObjectRepositoryImpl repo : getRepos()) {
- repo.setBusy(false);
+ finally {
+ // Ensure all busy flags are reset at all times...
+ for (ObjectRepositoryImpl repo : getRepos()) {
+ repo.setBusy(false);
+ }
}
}
@@ -267,23 +280,15 @@ class RepositorySet {
m_modifiedHandler =
context.registerService(EventHandler.class.getName(), new ModifiedHandler(),
topic);
}
- public void unregisterHandler() {
- m_modifiedHandler.unregister();
- m_modifiedHandler = null;
- }
-
WorkingState getWorkingState(RepositoryObject object) {
- if (m_workingState.containsKey(object)) {
- return m_workingState.get(object);
- }
- return null;
+ return m_workingState.get(object);
}
int getNumberWithWorkingState(Class<? extends RepositoryObject> clazz,
WorkingState state) {
int result = 0;
for (Map.Entry<RepositoryObject, WorkingState> entry :
m_workingState.entrySet()) {
if (clazz.isInstance(entry.getKey()) &&
state.equals(entry.getValue())) {
- result ++;
+ result++;
}
}
return result;
@@ -300,44 +305,55 @@ class RepositorySet {
}
m_notifier.notifyChanged(RepositoryAdmin.TOPIC_STATUSCHANGED_SUFFIX,
null);
}
-
- class ModifiedHandler implements EventHandler {
-
+
+ private void closeSafely(Closeable resource) {
+ if (resource != null) {
+ try {
+ resource.close();
+ }
+ catch (IOException e) {
+ // Ignored; not much we can do about this...
+ m_log.log(LogService.LOG_DEBUG, "Closing resource failed!", e);
+ }
+ }
+ }
+
+ final class ModifiedHandler implements EventHandler {
+
public void handleEvent(Event event) {
/*
* NOTE: if recalculating the state for every event turns out to be
* too expensive, we can cache the 'modified' state and not
recalculate
* it every time.
*/
-
+
boolean wasModified = isModified();
+
RepositoryObject object = (RepositoryObject)
event.getProperty(RepositoryObject.EVENT_ENTITY);
-
+ String topic = event.getTopic();
+
WorkingState newState = WorkingState.Unchanged;
- if (event.getTopic().endsWith("/ADDED")) {
+ if (topic.endsWith("/ADDED")) {
newState = WorkingState.New;
}
- else if (event.getTopic().endsWith("/CHANGED")) {
+ else if (topic.endsWith("/CHANGED")) {
newState = WorkingState.Changed;
}
- else if (event.getTopic().endsWith("/REMOVED")) {
+ else if (topic.endsWith("/REMOVED")) {
newState = WorkingState.Removed;
}
-
+
if (!newState.equals(m_workingState.get(object))) {
m_workingState.put(object, newState);
+
Properties props = new Properties();
props.put(RepositoryObject.EVENT_ENTITY, object);
m_notifier.notifyChanged(RepositoryAdmin.TOPIC_STATUSCHANGED_SUFFIX, props);
}
-
+
if (!wasModified) {
m_notifier.notifyChanged(RepositoryAdmin.TOPIC_STATUSCHANGED_SUFFIX, null);
}
}
}
-
- public boolean writeAccess() {
- return m_writeAccess;
- }
}
Modified:
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ArtifactTest.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ArtifactTest.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ArtifactTest.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ArtifactTest.java
Fri Apr 13 09:15:10 2012
@@ -91,7 +91,7 @@ public class ArtifactTest {
m_artifactRepository.addHelper("myMime", new MockHelper());
m_artifactRepository.addHelper(BundleHelper.MIMETYPE, new
BundleHelperImpl());
- ArtifactObject normalBundle = createArtifact(BundleHelper.MIMETYPE,
"normalBundle", "normalBundle", null);
+ createArtifact(BundleHelper.MIMETYPE, "normalBundle", "normalBundle",
null);
ArtifactObject resourceProcessor1 =
createArtifact(BundleHelper.MIMETYPE, "resourceProcessor1",
"resourceProcessor1", "somePID");
ArtifactObject resourceProcessor2 =
createArtifact(BundleHelper.MIMETYPE, "resourceProcessor2",
"resourceProcessor2", "someOtherPID");
Modified:
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ModelTest.java
URL:
http://svn.apache.org/viewvc/ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ModelTest.java?rev=1325679&r1=1325678&r2=1325679&view=diff
==============================================================================
---
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ModelTest.java
(original)
+++
ace/trunk/ace-client-repository-impl/src/test/java/org/apache/ace/client/repository/impl/ModelTest.java
Fri Apr 13 09:15:10 2012
@@ -607,15 +607,15 @@ public class ModelTest {
@Test( groups = { TestUtils.UNIT } )
public void testAssociationsWithCardinality() {
- ArtifactObject b1 = createBasicArtifactObject("b1");
- FeatureObject g1 = createBasicFeatureObject("g1");
- FeatureObject g2 = createBasicFeatureObject("g2");
- FeatureObject g3 = createBasicFeatureObject("g3");
+ ArtifactObject a1 = createBasicArtifactObject("a1");
+ FeatureObject f1 = createBasicFeatureObject("f1");
+ FeatureObject f2 = createBasicFeatureObject("f2");
+ FeatureObject f3 = createBasicFeatureObject("f3");
Map<String, String> props = new HashMap<String, String>();
- props.put(Association.LEFT_ENDPOINT, "(" +
BundleHelper.KEY_SYMBOLICNAME + "=b1)");
+ props.put(Association.LEFT_ENDPOINT, "(" +
BundleHelper.KEY_SYMBOLICNAME + "=a1)");
props.put(Association.LEFT_CARDINALITY, "1");
- props.put(Association.RIGHT_ENDPOINT, "(" + FeatureObject.KEY_NAME +
"=g*)");
+ props.put(Association.RIGHT_ENDPOINT, "(" + FeatureObject.KEY_NAME +
"=f*)");
props.put(Association.RIGHT_CARDINALITY, "2");
Map<String, String> tags = new HashMap<String, String>();
@@ -630,10 +630,12 @@ public class ModelTest {
props.put(Association.RIGHT_CARDINALITY, "3");
Artifact2FeatureAssociation bg =
m_artifact2FeatureRepository.create(props, tags);
- assert b1.getFeatures().size() == 3 : "The artifact should be
associated to three features.";
- assert (g1.getArtifacts().size() == 1) &&
g1.getArtifacts().contains(b1) : "g1 should be associated to only b1.";
- assert (g2.getArtifacts().size() == 1) &&
g2.getArtifacts().contains(b1) : "g1 should be associated to only b1.";
- assert (g3.getArtifacts().size() == 1) &&
g3.getArtifacts().contains(b1) : "g1 should be associated to only b1.";
+ assert bg != null : "Assocating artifact to feature failed?!";
+
+ assert a1.getFeatures().size() == 3 : "The artifact should be
associated to three features.";
+ assert (f1.getArtifacts().size() == 1) &&
f1.getArtifacts().contains(a1) : "g1 should be associated to only b1.";
+ assert (f2.getArtifacts().size() == 1) &&
f2.getArtifacts().contains(a1) : "g1 should be associated to only b1.";
+ assert (f3.getArtifacts().size() == 1) &&
f3.getArtifacts().contains(a1) : "g1 should be associated to only b1.";
}
private Filter createLocalFilter(String filter) throws
InvalidSyntaxException {