ace-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r1325679 - in /ace/trunk/ace-client-repository-impl/src: main/java/org/apache/ace/client/repository/impl/ test/java/org/apache/ace/client/repository/impl/
Date Fri, 13 Apr 2012 09:15:12 GMT
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 {



Mime
View raw message