FELIX-5112 ClassCastException when deploying an OBR Resource already present in the runtime

Fixed exception issue
Committed on behalf of @skahmann with many thanks. Contributed via https://github.com/apache/felix/pull/44


git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1718668 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalResource.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalResource.java
new file mode 100644
index 0000000..c4718d4
--- /dev/null
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/LocalResource.java
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.felix.bundlerepository;
+
+import org.osgi.framework.BundleReference;
+
+public interface LocalResource extends BundleReference, Resource {
+}
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LazyLocalResourceImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LazyLocalResourceImpl.java
index 6837fc7..a39f761 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LazyLocalResourceImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LazyLocalResourceImpl.java
@@ -25,6 +25,7 @@
 import java.util.StringTokenizer;
 
 import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.LocalResource;
 import org.apache.felix.bundlerepository.Requirement;
 import org.apache.felix.bundlerepository.Resource;
 import org.apache.felix.utils.log.Logger;
@@ -35,7 +36,7 @@
 import org.osgi.framework.Version;
 import org.osgi.framework.wiring.BundleRevision;
 
-public class LazyLocalResourceImpl implements Resource
+public class LazyLocalResourceImpl implements LocalResource
 {
     private final Bundle m_bundle;
     private final Logger m_logger;
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LocalResourceImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LocalResourceImpl.java
index e3d4c27..b0bbb21 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LocalResourceImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/LocalResourceImpl.java
@@ -25,6 +25,7 @@
 import java.util.StringTokenizer;
 
 import org.apache.felix.bundlerepository.Capability;
+import org.apache.felix.bundlerepository.LocalResource;
 import org.apache.felix.bundlerepository.Resource;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.Constants;
@@ -32,7 +33,7 @@
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.wiring.BundleRevision;
 
-public class LocalResourceImpl extends ResourceImpl
+public class LocalResourceImpl extends ResourceImpl implements LocalResource
 {
     private Bundle m_bundle = null;
 
diff --git a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java
index 3245b09..90d8295 100644
--- a/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java
+++ b/bundlerepository/src/main/java/org/apache/felix/bundlerepository/impl/ResolverImpl.java
@@ -19,21 +19,9 @@
 package org.apache.felix.bundlerepository.impl;
 
 import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
-import org.apache.felix.bundlerepository.Capability;
-import org.apache.felix.bundlerepository.Reason;
-import org.apache.felix.bundlerepository.Repository;
-import org.apache.felix.bundlerepository.Requirement;
-import org.apache.felix.bundlerepository.Resolver;
-import org.apache.felix.bundlerepository.Resource;
+import org.apache.felix.bundlerepository.*;
 import org.apache.felix.utils.log.Logger;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
@@ -136,9 +124,35 @@
         throw new IllegalStateException("The resources have not been resolved.");
     }
 
-    private Resource[] getResources(boolean local)
+    private LocalResource[] getLocalResources()
     {
-        List resources = new ArrayList();
+        List<LocalResource> resources = new ArrayList<LocalResource>();
+        for (Resource resource : getResources())
+        {
+            if (resource != null && resource.isLocal())
+            {
+                resources.add((LocalResource) resource);
+            }
+        }
+        return resources.toArray(new LocalResource[resources.size()]);
+    }
+
+    private Resource[] getRemoteResources()
+    {
+        List<Resource> resources = new ArrayList<Resource>();
+        for (Resource resource : getResources())
+        {
+            if (resource != null && !resource.isLocal())
+            {
+                resources.add(resource);
+            }
+        }
+        return resources.toArray(new Resource[resources.size()]);
+    }
+
+    private Resource[] getResources()
+    {
+        List<Resource> resources = new ArrayList<Resource>();
         for (int repoIdx = 0; (m_repositories != null) && (repoIdx < m_repositories.length); repoIdx++)
         {
             boolean isLocal = m_repositories[repoIdx] instanceof LocalRepositoryImpl;
@@ -149,16 +163,9 @@
             if (isSystem && (m_resolutionFlags & NO_SYSTEM_BUNDLE) != 0) {
                 continue;
             }
-            Resource[] res = m_repositories[repoIdx].getResources();
-            for (int resIdx = 0; (res != null) && (resIdx < res.length); resIdx++)
-            {
-                if (res[resIdx].isLocal() == local)
-                {
-                    resources.add(res[resIdx]);
-                }
-            }
+            Collections.addAll(resources, m_repositories[repoIdx].getResources());
         }
-        return (Resource[]) resources.toArray(new Resource[resources.size()]);
+        return resources.toArray(new Resource[resources.size()]);
     }
 
     public synchronized boolean resolve()
@@ -169,8 +176,8 @@
     public synchronized boolean resolve(int flags)
     {
         // Find resources
-        Resource[] locals = getResources(true);
-        Resource[] remotes = getResources(false);
+        Resource[] locals = getLocalResources();
+        Resource[] remotes = getRemoteResources();
 
         // time of the resolution process start
         m_resolveTimeStamp = 0;
@@ -566,8 +573,7 @@
             // For the resource being deployed, see if there is an older
             // version of the resource already installed that can potentially
             // be updated.
-            LocalResourceImpl localResource =
-                findUpdatableLocalResource(deployResources[i]);
+            LocalResource localResource = findUpdatableLocalResource(deployResources[i]);
             // If a potentially updatable older version was found,
             // then verify that updating the local resource will not
             // break any of the requirements of any of the other
@@ -683,11 +689,11 @@
 
     // TODO: OBR - Think about this again and make sure that deployment ordering
     // won't impact it...we need to update the local state too.
-    private LocalResourceImpl findUpdatableLocalResource(Resource resource)
+    private LocalResource findUpdatableLocalResource(Resource resource)
     {
         // Determine if any other versions of the specified resource
         // already installed.
-        Resource[] localResources = findLocalResources(resource.getSymbolicName());
+        LocalResource[] localResources = findLocalResources(resource.getSymbolicName());
         if (localResources != null)
         {
             // Since there are local resources with the same symbolic
@@ -700,7 +706,7 @@
             {
                 if (isResourceUpdatable(localResources[i], resource, localResources))
                 {
-                    return (LocalResourceImpl) localResources[i];
+                    return localResources[i];
                 }
             }
         }
@@ -712,9 +718,9 @@
      * @param symName The symbolic name of the wanted local resources.
      * @return The local resources with the specified symbolic name.
      */
-    private Resource[] findLocalResources(String symName)
+    private LocalResource[] findLocalResources(String symName)
     {
-        Resource[] localResources = getResources(true);
+        LocalResource[] localResources = getLocalResources();
 
         List matchList = new ArrayList();
         for (int i = 0; i < localResources.length; i++)
@@ -725,7 +731,7 @@
                 matchList.add(localResources[i]);
             }
         }
-        return (Resource[]) matchList.toArray(new Resource[matchList.size()]);
+        return (LocalResource[]) matchList.toArray(new LocalResource[matchList.size()]);
     }
 
     private boolean isResourceUpdatable(