You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@aries.apache.org by li...@apache.org on 2010/10/13 19:38:49 UTC

svn commit: r1022207 - in /incubator/aries/trunk/subsystem/subsystem-scope-impl: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/aries/ src/main/java/org/apache/aries/subsystem/ src/main/java/org/a...

Author: linsun
Date: Wed Oct 13 17:38:45 2010
New Revision: 1022207

URL: http://svn.apache.org/viewvc?rev=1022207&view=rev
Log:
ARIES-456 Provide scope API & Impl & itests to evaluate the new RFC 138 (Framework hooks) for subsystem

Added:
    incubator/aries/trunk/subsystem/subsystem-scope-impl/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml   (with props)
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java   (with props)
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java   (with props)
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java   (with props)
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java   (with props)
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java   (with props)
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/
    incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java   (with props)

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml Wed Oct 13 17:38:45 2010
@@ -0,0 +1,102 @@
+
+    <!--
+        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.
+    -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.aries.subsystem</groupId>
+        <artifactId>subsystem</artifactId>
+        <version>0.3-incubating-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>org.apache.aries.subsystem.scope.impl</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Aries Subsystem Scope Impl</name>
+    <description>
+      Subsystems Scope Impl.
+    </description>
+
+    <properties>
+        <aries.osgi.activator>
+            org.apache.aries.subsystem.scope.internal.Activator
+        </aries.osgi.activator>
+        <aries.osgi.private.pkg>
+            org.apache.aries.subsystem.scope.internal,
+            org.apache.aries.subsystem.scope.impl
+        </aries.osgi.private.pkg>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.aries.subsystem</groupId>
+            <artifactId>org.apache.aries.subsystem.api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.subsystem</groupId>
+            <artifactId>org.apache.aries.subsystem.scope.api</artifactId>
+            <version>${version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.application</groupId>
+            <artifactId>org.apache.aries.application.utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.testsupport</groupId>
+            <artifactId>org.apache.aries.testsupport.unit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.eclipse</groupId>
+            <artifactId>osgi</artifactId>
+            <version>3.7.0.v20100910</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.bundlerepository</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+</project>

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/pom.xml
------------------------------------------------------------------------------
    svn:mime-type = text/xml

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java Wed Oct 13 17:38:45 2010
@@ -0,0 +1,52 @@
+/*
+ * 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.aries.subsystem.scope.impl;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+public class DictionaryBuilder<K,V> {
+
+    public static <K,V> Dictionary<K,V> build(K k, V v) {
+        return new DictionaryBuilder<K,V>().p(k, v).get();
+    }
+
+    public static <K,V> Dictionary<K,V> build(K k1, V v1, K k2, V v2) {
+        return new DictionaryBuilder<K,V>().p(k1, v1).p(k2, v2).get();
+    }
+
+    public static <K,V> Dictionary<K,V> build(K k1, V v1, K k2, V v2, K k3, V v3) {
+        return new DictionaryBuilder<K,V>().p(k1, v1).p(k2, v2).p(k3, v3).get();
+    }
+
+    private Dictionary<K,V> dict;
+
+    public DictionaryBuilder() {
+        dict = new Hashtable<K,V>();
+    }
+
+    DictionaryBuilder<K,V> p(K k, V v) {
+        dict.put(k, v);
+        return this;
+    }
+
+    Dictionary<K,V> get() {
+        return dict;
+    }
+}
\ No newline at end of file

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/DictionaryBuilder.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java Wed Oct 13 17:38:45 2010
@@ -0,0 +1,48 @@
+/*
+ * 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.aries.subsystem.scope.impl;
+
+import org.apache.aries.subsystem.scope.Scope;
+import org.apache.aries.subsystem.scope.ScopeAdmin;
+import org.apache.aries.subsystem.scope.ScopeUpdate;
+import org.apache.aries.subsystem.scope.internal.Activator;
+
+public class ScopeAdminImpl implements ScopeAdmin {
+
+    private ScopeImpl parentScope;
+    private ScopeImpl scope;
+    
+    public ScopeAdminImpl(ScopeImpl parentScope, ScopeImpl scope) {
+        this.parentScope = parentScope;
+        this.scope = scope;
+    }
+    
+    public Scope getParentScope() {
+        return this.parentScope;
+    }
+
+    public Scope getScope() {
+        return this.scope;
+    }
+ 
+    public ScopeUpdate newScopeUpdate() {
+        return new ScopeUpdateImpl(this.scope, Activator.getBundleContext());
+    }
+
+}

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java Wed Oct 13 17:38:45 2010
@@ -0,0 +1,550 @@
+/*
+ * 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.aries.subsystem.scope.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.aries.subsystem.scope.Scope;
+import org.apache.aries.subsystem.scope.ScopeAdmin;
+import org.apache.aries.subsystem.scope.ScopeUpdate;
+import org.apache.aries.subsystem.scope.SharePolicy;
+import org.apache.aries.subsystem.scope.internal.Activator;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.framework.Version;
+import org.osgi.framework.hooks.bundle.EventHook;
+import org.osgi.framework.hooks.bundle.FindHook;
+import org.osgi.framework.hooks.resolver.ResolverHook;
+import org.osgi.framework.wiring.BundleRevision;
+import org.osgi.framework.wiring.Capability;
+import org.osgi.util.tracker.ServiceTracker;
+import org.osgi.util.tracker.ServiceTrackerCustomizer;
+
+// the idea is one scopeAdmin per scope. for bundles in the same scope, same
+// ScopeAdmin would be returned
+public class ScopeAdminServiceFactory implements ServiceFactory {
+
+    // mapping of scope and ScopeAdminImpl
+    private final List<ScopeAdmin> admins = new ArrayList<ScopeAdmin>();
+    private final Map<ScopeAdmin, Long> references = new HashMap<ScopeAdmin, Long>();
+    protected static ScopeAdminImpl defaultScopeAdmin;
+    private static BundleContext context;
+    private ServiceTracker serviceTracker;
+    private List<ServiceRegistration> srs = new ArrayList<ServiceRegistration>();
+    public static final String SERVICE_CAPABILITY = "osgi.service";
+    
+    public void init() throws InvalidSyntaxException {
+        context = Activator.getBundleContext();
+        Filter filter = FrameworkUtil.createFilter("(&("
+                + Constants.OBJECTCLASS + "=" + ScopeAdmin.class.getName() + "))");
+        serviceTracker = new ServiceTracker(context, filter,
+                new ServiceTrackerCustomizer() {
+
+                    public Object addingService(ServiceReference reference) {
+                        // adding new service, update admins map
+                        ScopeAdmin sa = (ScopeAdmin) context
+                                .getService(reference);
+                        admins.add(sa);
+
+                        return sa;
+                    }
+
+                    public void modifiedService(ServiceReference reference,
+                            Object service) {
+                        // TODO Auto-generated method stub
+
+                    }
+
+                    public void removedService(ServiceReference reference,
+                            Object service) {
+                        ScopeAdmin sa = (ScopeAdmin) service;
+                        admins.remove(sa);
+                    }
+
+                });
+        defaultScopeAdmin = new ScopeAdminImpl(null, new ScopeImpl("root",
+                context));
+        admins.add(defaultScopeAdmin);
+        references.put(defaultScopeAdmin, new Long(0));
+        serviceTracker.open();
+        
+        ScopeAdminBundleHooks bundleHooks = new ScopeAdminBundleHooks();
+        srs.add(context.registerService(new String[]{FindHook.class.getName(), EventHook.class.getName(), ResolverHook.class.getName()}, bundleHooks, null));
+        ScopeAdminEventHooks eventHooks = new ScopeAdminEventHooks();
+        srs.add(context.registerService(new String[]{org.osgi.framework.hooks.service.FindHook.class.getName(), org.osgi.framework.hooks.service.EventHook.class.getName()}, eventHooks, null));
+
+        
+    }
+
+    public void destroy() {
+        if (serviceTracker != null) {
+            serviceTracker.close();
+        }
+        
+        for (ServiceRegistration sr : srs) {
+            sr.unregister();
+        }
+    }
+
+    public synchronized Object getService(Bundle bundle, ServiceRegistration registration) {
+        // determine bundle in which scope first, then determine the
+        // scopeadmin to return
+        ScopeAdmin sa = getScopeAdmin(bundle);
+        long ref = 0;
+
+        // unable to find scope admin in our admins map
+        if (sa == null) {
+            // unable to find scope admin, assuming it is in the root scope.
+            sa = defaultScopeAdmin;
+            
+        } else {
+            ref = references.get(sa);
+        }
+
+        references.put(sa, ref + 1);
+        return sa;
+    }
+
+    public synchronized void ungetService(Bundle bundle,
+            ServiceRegistration registration, Object service) {
+        ScopeAdminImpl admin = (ScopeAdminImpl) service;
+        long ref = references.get(admin) - 1;
+        if (ref == 0) {
+            // admin.dispose();
+            admins.remove(admin);
+            references.remove(admin);
+        } else {
+            references.put(admin, ref);
+        }
+    }
+    
+    // assume one bundle only belongs to one subsystem at most
+    private ScopeAdmin getScopeAdmin(Bundle bundle) {
+        
+        // add pax-exam-probe to default scope for now before we could figure out bundles in which scope via some sorta of installhook (bug 1747 in OSGi Aliance bug system)
+        if (bundle.getSymbolicName().equals("pax-exam-probe") || bundle.getSymbolicName().indexOf("fileinstall") > -1) {
+            ScopeUpdate scopeUpdate = ScopeAdminServiceFactory.defaultScopeAdmin.newScopeUpdate();
+            scopeUpdate.getBundles().add(bundle);
+        }
+        
+        // add hard coded value below due to bug 1747
+        if (bundle.getSymbolicName().indexOf("helloIsolation") > 0 && bundle.getVersion().equals(new Version("1.0.0"))) {
+            ScopeUpdate scopeUpdate = ScopeAdminServiceFactory.defaultScopeAdmin.newScopeUpdate();
+            scopeUpdate.getBundles().add(bundle);
+        }
+        
+        for (ScopeAdmin admin : admins) {
+            ScopeImpl scope = (ScopeImpl)admin.getScope();
+            
+            // it is possible the scope is in the tobeinstalled bundle location list, and hasn't fully installed yet.
+            Collection<String> bundlesLocations = scope.getToBeInstalledBundleLocation();
+            for (String loc : bundlesLocations) {
+                if (bundle.getLocation().equals(loc)) {
+                    return admin;
+                }
+            }
+            Collection<Bundle> bundles = scope.getBundles();
+            
+            for (Bundle b : bundles) {
+                if (b == bundle) {
+                    return admin;
+                }
+            }
+            
+
+        }
+
+        // it is possible there is no scopeAdmin for the bundle as the bundle has not been added to the scope yet.
+        return null;
+    }
+
+
+    private class ScopeAdminBundleHooks implements FindHook, EventHook, ResolverHook {
+
+        public void find(BundleContext context, Collection<Bundle> bundles) {
+            Bundle b = context.getBundle();
+            // obtain bundle associated subsystem
+            ScopeAdmin scopeAdmin = getScopeAdmin(b);
+            
+            if (scopeAdmin != null) {
+                // able to obtain the correct scope otherwise, we don't need to do anything
+                Collection<Bundle> buns = scopeAdmin.getScope().getBundles();
+                trimBundleCollections(bundles, buns);
+            } else {
+                // should this be an error.  a bundle would have to be in a scope.
+            }
+            
+            // check the scope policy
+            // are we allow any package to be exported out of a scope?   yes  if yes, do we want to have bundle that exports the package visible?
+            // are we allow any service to be exported out of a scope?   yes
+            // go through bundles and remove the bundles that are not part of the scope
+        }
+
+        public void event(BundleEvent event, Collection<BundleContext> contexts) {
+            Bundle bundle = event.getBundle();
+            
+            // obtain bundle associated scopeAdmin
+            ScopeAdmin scopeAdmin = getScopeAdmin(bundle);
+            
+            if (scopeAdmin != null) {
+                // able to obtain the correct scope otherwise, we don't need to do anything
+                Collection<Bundle> buns = scopeAdmin.getScope().getBundles();
+                ScopeImpl scopeImpl = (ScopeImpl)scopeAdmin.getScope();
+                trimBundleContextCollections(contexts, buns, scopeImpl.getToBeInstalledBundleLocation());
+            } 
+            
+            // figure out where contexts reside in which scope and trim them as needed.
+            // should be easy as events should only been seen inside a scope
+            
+        }
+
+        public void begin() {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void end() {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void filterMatches(BundleRevision requirer, Collection<Capability> candidates) {
+            // obtain requirer bundle
+            Bundle bundle = requirer.getBundle();
+            
+            // figure out if the requirer bundle in any scope
+            // obtain bundle associated scopeAdmin
+            ScopeAdmin scopeAdmin = getScopeAdmin(bundle);
+            
+            if (scopeAdmin != null) {
+                // able to obtain the correct scope otherwise, we don't need to do anything
+                Collection<Bundle> buns = scopeAdmin.getScope().getBundles();
+                
+                Collection<Scope> childrenScopes = scopeAdmin.getScope().getChildren();
+                List<SharePolicy> exportPackagePolicies = new ArrayList<SharePolicy>();
+                for (Scope childScope : childrenScopes) {
+                    Map<String, List<SharePolicy>> exportPolicies = childScope.getSharePolicies(SharePolicy.TYPE_EXPORT);
+                    if (exportPolicies.get(Capability.PACKAGE_CAPABILITY) != null) {
+                        exportPackagePolicies.addAll(exportPolicies.get(Capability.PACKAGE_CAPABILITY));
+                    }
+                }
+                
+                List<SharePolicy> importPackagePolicies = new ArrayList<SharePolicy>();
+                Map<String, List<SharePolicy>> importPolicies = scopeAdmin.getScope().getSharePolicies(SharePolicy.TYPE_IMPORT);
+                if (importPolicies.get(Capability.PACKAGE_CAPABILITY) != null) {
+                    importPackagePolicies.addAll(importPolicies.get(Capability.PACKAGE_CAPABILITY));
+                }
+
+                trimCapabilityCollections(candidates, buns, exportPackagePolicies, importPackagePolicies);
+            }
+            // simple filter candidates
+          
+        }
+
+        public void filterResolvable(Collection candidates) {
+            // TODO Auto-generated method stub
+            
+        }
+
+        public void filterSingletonCollisions(Capability singleton, Collection collisionCandidates) {
+            // TODO Auto-generated method stub
+            
+        }
+        
+    }
+    
+    // based on event hooks
+    private class ScopeAdminEventHooks implements org.osgi.framework.hooks.service.FindHook, org.osgi.framework.hooks.service.EventHook {
+
+        // modifies getServiceReference
+        public void find(BundleContext context, String name, String filter,
+                boolean allServices, Collection references) {
+            Bundle bundle = context.getBundle();
+            
+            // figure out if the bundle in any scope
+            // obtain bundle associated scopeAdmin
+            ScopeAdmin scopeAdmin = getScopeAdmin(bundle);
+            
+            if (scopeAdmin != null) {
+                // able to obtain the correct scope otherwise, we don't need to do anything
+                Collection<Bundle> buns = scopeAdmin.getScope().getBundles();
+                
+                Collection<Scope> childrenScopes = scopeAdmin.getScope().getChildren();
+                List<SharePolicy> exportServicePolicies = new ArrayList<SharePolicy>();
+                for (Scope childScope : childrenScopes) {
+                    Map<String, List<SharePolicy>> exportPolicies = childScope.getSharePolicies(SharePolicy.TYPE_EXPORT);
+                    if (exportPolicies.get(SERVICE_CAPABILITY) != null) {
+                        exportServicePolicies.addAll(exportPolicies.get(SERVICE_CAPABILITY));
+                    }
+                }
+                
+                List<SharePolicy> importServicePolicies = new ArrayList<SharePolicy>();
+                Map<String, List<SharePolicy>> importPolicies = scopeAdmin.getScope().getSharePolicies(SharePolicy.TYPE_IMPORT);
+                if (importPolicies.get(SERVICE_CAPABILITY) != null) {
+                    importServicePolicies.addAll(importPolicies.get(SERVICE_CAPABILITY));
+                }
+                trimServiceReferenceCollections(references, buns, exportServicePolicies, importServicePolicies);       
+            }
+            
+            
+        }
+
+        // modifies service events - assume events are only seen in the scope.
+        public void event(ServiceEvent event, Collection contexts) {
+            Bundle bundle = event.getServiceReference().getBundle();
+            
+            // obtain bundle associated scopeAdmin
+            ScopeAdmin scopeAdmin = getScopeAdmin(bundle);
+            
+            if (scopeAdmin != null) {
+                // able to obtain the correct scope otherwise, we don't need to do anything
+                Collection<Bundle> buns = scopeAdmin.getScope().getBundles();
+                trimBundleContextCollections(contexts, buns, null);
+            }
+            
+        }
+
+        
+    }
+    
+    // trim the references candidate to only the ones in scopeBundles
+    private synchronized void trimServiceReferenceCollections(
+            Collection<ServiceReference> references,
+            Collection<Bundle> scopeBundles, 
+            List<SharePolicy> exportServicePolicies, 
+            List<SharePolicy> importServicePolicies) {
+        Collection<ServiceReference> toBeRemoved = new ArrayList<ServiceReference>();
+        for (ServiceReference reference : references) {
+            Bundle b = reference.getBundle();
+            boolean exist = false;
+
+            for (Bundle bundle : scopeBundles) {
+                if (b == bundle) {
+                    exist = true;
+                    break;
+                }
+            }
+
+            if (!exist) {
+                // double check toBeRemoved.  If it exists in toBeRemoved but are part of exportServicePolicies of the child scope
+                // then we still allow the services to be used
+                // if it exists in toBeRemoved but are part of importServicePolicies of the scope the bundle is in, we still allow
+                // the services to be used.
+                boolean matchPolicy = false;
+                // go through export package policies
+                for (SharePolicy sp : exportServicePolicies) {         
+                    if (sp.getFilter().match(reference)) {
+                        matchPolicy = true;
+                        continue;
+                    }
+                    
+                }
+                
+                if (!matchPolicy) {
+                    // go through import package policies
+                    for (SharePolicy sp : importServicePolicies) {
+                        if (sp.getFilter().match(reference)) {
+                            matchPolicy = true;
+                            continue;
+                        }
+                        
+                    }
+                    if (!matchPolicy) {
+                        toBeRemoved.add(reference);
+                    }
+                }
+            }
+        }
+
+        if (!toBeRemoved.isEmpty()) {
+            references.removeAll(toBeRemoved);
+        }
+    }
+    
+    // trim the bundles candidate to only the ones in subsystemBundles
+    private synchronized void trimBundleCollections(Collection<Bundle> bundles, Collection<Bundle> scopeBundles) {
+        Collection<Bundle> toBeRemoved = new ArrayList<Bundle>();
+        for (Bundle b : bundles) {
+            boolean exist = false;
+            
+            for (Bundle bundle : scopeBundles) {
+                if (b == bundle) {
+                    exist = true;
+                    break;
+                }
+            }
+            
+            if (!exist) {
+                toBeRemoved.add(b);
+            }
+        }
+
+        if (!toBeRemoved.isEmpty()) {
+            bundles.removeAll(toBeRemoved);
+        }
+    }
+    
+    // trim the bundles candidate to only the ones in scopeBundles
+    private synchronized void trimBundleContextCollections(Collection<BundleContext> bundleContexts, 
+            Collection<Bundle> scopeBundles, Collection<String> toBeInstalledBundleLocations) {
+        Collection<BundleContext> toBeRemoved = new ArrayList<BundleContext>();
+
+        for (BundleContext bc : bundleContexts) {
+            boolean exist = false;
+            
+            for (Bundle bundle : scopeBundles) {
+                if (bc.getBundle() == bundle || existsInList(bc.getBundle().getLocation(), toBeInstalledBundleLocations)) {
+                    exist = true;
+                    break;
+                }
+            }
+            
+            if (!exist) {
+                toBeRemoved.add(bc);
+            } 
+            
+        }
+        
+        if (!toBeRemoved.isEmpty()) {
+            bundleContexts.removeAll(toBeRemoved);
+        }
+
+    }
+
+    private boolean existsInList(String bundleLoc, Collection<String> toBeInstalledBundleLocations) {
+        if (toBeInstalledBundleLocations == null) {
+            return false;
+        }
+        
+        for (String loc : toBeInstalledBundleLocations) {
+            if (bundleLoc.equals(loc)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    // trim the bundles candidate to only the ones in subsystemBundles
+    private synchronized void trimCapabilityCollections(Collection<Capability> capabilities, 
+            Collection<Bundle> scopeBundles, 
+            List<SharePolicy> exportPackagePolicies, 
+            List<SharePolicy> importPackagePolicies) {
+        Collection<Capability> toBeRemoved = new ArrayList<Capability>();
+
+        for (Capability cap : capabilities) {
+            Bundle b = cap.getProviderRevision().getBundle();
+
+            if (b.getBundleId() == 0) {
+                continue;
+            }
+            boolean exist = false;
+            
+            for (Bundle bundle : scopeBundles) {
+                if (b == bundle) {
+                    exist = true;
+                    break;
+                }
+            }
+            
+            if (!exist) {
+                // double check toBeRemoved.  If it exists in toBeRemoved but are part of exportPackagePolicies of the child scope
+                // then we still allow the capabilities to be used
+                // if it exists in toBeRemoved but are part of importPackagePolicies of the scope the bundle is in, we still allow
+                // the capabilities to be used.
+                boolean matchPolicy = false;
+                // go through export package policies
+                for (SharePolicy sp : exportPackagePolicies) {
+                    if (sp.getFilter().match(new UnmodifiableDictionary(cap.getAttributes()))) {
+                        matchPolicy = true;
+                        break;
+                    }
+                    
+                }
+                
+                if (!matchPolicy) {
+                    // go through import package policies
+                    for (SharePolicy sp : importPackagePolicies) {
+                        // append the scope to the capability to do scope affinity
+                        Map<String, Object> capabilityAttributes = new HashMap<String, Object>();
+                        capabilityAttributes.putAll(cap.getAttributes());
+                        Scope scope = getScopeAdmin(b).getScope();
+                        capabilityAttributes.put("scopeName", scope.getName());
+                        
+                        if (sp.getFilter().match(new UnmodifiableDictionary(capabilityAttributes))) {
+                            matchPolicy = true;
+                            break;
+                        }
+                        
+                    }
+                    if (!matchPolicy) {
+                        toBeRemoved.add(cap);
+                    }
+                }
+            }
+        }
+         
+        if (!toBeRemoved.isEmpty()) {
+            capabilities.removeAll(toBeRemoved);
+        }
+    }
+    
+    static class UnmodifiableDictionary extends Dictionary {
+        private final Map   wrapped;
+        UnmodifiableDictionary(Map wrapped) {
+            this.wrapped = wrapped;
+        }
+        public Enumeration elements() {
+            return Collections.enumeration(wrapped.values());
+        }
+        public Object get(Object key) {
+            return wrapped.get(key);
+        }
+        public boolean isEmpty() {
+            return wrapped.isEmpty();
+        }
+        public Enumeration keys() {
+            return Collections.enumeration(wrapped.keySet());
+        }
+        public Object put(Object key, Object value) {
+            throw new UnsupportedOperationException();
+        }
+        public Object remove(Object key) {
+            throw new UnsupportedOperationException();
+        }
+        public int size() {
+            return wrapped.size();
+        }
+    }
+}
+

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeAdminServiceFactory.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java Wed Oct 13 17:38:45 2010
@@ -0,0 +1,185 @@
+/*
+ * 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.aries.subsystem.scope.impl;
+
+import java.lang.IllegalArgumentException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.aries.subsystem.scope.Scope;
+import org.apache.aries.subsystem.scope.SharePolicy;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleEvent;
+import org.osgi.util.tracker.BundleTracker;
+import org.osgi.util.tracker.BundleTrackerCustomizer;
+
+public class ScopeImpl implements Scope {
+
+    private String name;
+    private String location;
+    private BundleContext context;
+    private List<Scope> children = new ArrayList<Scope>();
+    private List<Bundle> bundles = new ArrayList<Bundle>();
+    private Map<String, List<SharePolicy>> importPolicies = new HashMap<String, List<SharePolicy>>();
+    private Map<String, List<SharePolicy>> exportPolicies = new HashMap<String, List<SharePolicy>>();
+    private BundleTracker bt;
+    private long id;
+    private List<String> bundleLocations = new ArrayList<String>();
+    
+    public ScopeImpl(String name) {
+        this.name = name;
+        this.id = getId();
+    }
+    
+    public ScopeImpl(String name, String location) {
+        this.name = name;
+        this.location = location;
+        this.id = getId();
+    }
+    // assume this constructor would be used to construct the root scope
+    public ScopeImpl(String name, BundleContext context) {
+        this(name);
+
+        this.context = context;
+        if (name.equals("root")) {
+            bundles.addAll(Arrays.asList(context.getBundles()));
+        }
+
+     
+        // let's use a bundle tracker to dynamically update the bundle list - need to wait on the resolution of the new rfc 138 bug
+        // we cannot really use bundle tracker because the hooks may not work here
+        //bt = new BundleTracker(context, Bundle.INSTALLED | Bundle.UNINSTALLED, new ScopeBundleTrackerCustomizer());
+        //bt.open();
+    }
+    
+    public void destroy() {
+        /*if (bt != null) {
+            bt.close();
+        }*/
+    }
+    
+    public Collection<Bundle> getBundles() {
+        return Collections.unmodifiableCollection(bundles);
+    }
+    
+    protected Collection<String> getToBeInstalledBundleLocation() {
+        return bundleLocations;
+    }
+    
+    protected void clearBundleLocations() {
+        bundleLocations = new ArrayList<String>();
+    }
+    
+    protected Collection<Bundle> getModifiableBundles() {
+        return this.bundles;
+    }
+
+    public Collection<Scope> getChildren() {
+        return Collections.unmodifiableList(children);
+    }
+    
+    protected Collection<Scope> getModifiableChildren() {
+        return this.children;
+    }
+
+    public String getName() {
+        return this.name;
+    }
+
+    public Map<String, List<SharePolicy>> getSharePolicies(String type) {
+        if (type.equals(SharePolicy.TYPE_IMPORT)) {
+            return Collections.unmodifiableMap(this.importPolicies);
+        } else if (type.equals(SharePolicy.TYPE_EXPORT)) {
+            return Collections.unmodifiableMap(this.exportPolicies);
+        }
+        throw new IllegalArgumentException("Valid Types are : " + SharePolicy.TYPE_EXPORT + " & " + 
+                SharePolicy.TYPE_IMPORT + " Invalid type: " + type);
+        
+    }
+    
+    protected Map<String, List<SharePolicy>> getModifiableSharePolicies(String type) {
+        if (type.equals(SharePolicy.TYPE_IMPORT)) {
+            return this.importPolicies;
+        } else if (type.equals(SharePolicy.TYPE_EXPORT)) {
+            return this.exportPolicies;
+        }
+        throw new IllegalArgumentException("Valid Types are : " + SharePolicy.TYPE_EXPORT + " & " + 
+                SharePolicy.TYPE_IMPORT + " Invalid type: " + type);
+    }
+
+    private class ScopeBundleTrackerCustomizer implements BundleTrackerCustomizer {
+
+        public Object addingBundle(Bundle bundle, BundleEvent event) {
+            if (event.getType() == BundleEvent.INSTALLED) {
+                bundles.add(bundle);
+            } else if (event.getType() == BundleEvent.UNINSTALLED) {
+                bundles.remove(bundle);
+            }
+            
+            return bundle;
+        }
+
+        public void modifiedBundle(Bundle bundle, BundleEvent event,
+                Object object) {
+            if (event.getType() == BundleEvent.INSTALLED) {
+                bundles.add(bundle);
+            } else if (event.getType() == BundleEvent.UNINSTALLED) {
+                bundles.remove(bundle);
+            }
+            
+        }
+
+        public void removedBundle(Bundle bundle, BundleEvent event,
+                Object object) {
+            if (event.getType() == BundleEvent.INSTALLED) {
+                bundles.add(bundle);
+            } else if (event.getType() == BundleEvent.UNINSTALLED) {
+                bundles.remove(bundle);
+            }          
+        }
+        
+    }
+
+    public long getId() {
+        if (id == 0) {
+            id = IdGenerator.next();
+        } 
+        
+        return id;
+    }
+    
+    private static class IdGenerator {
+        static long newId;       
+        
+        protected static synchronized long next() {
+            newId++;
+            return newId;
+        }
+    }
+
+    public String getLocation() {
+        return this.location;
+    }
+}

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java Wed Oct 13 17:38:45 2010
@@ -0,0 +1,242 @@
+/*
+ * 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.aries.subsystem.scope.impl;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.apache.aries.subsystem.scope.InstallInfo;
+import org.apache.aries.subsystem.scope.Scope;
+import org.apache.aries.subsystem.scope.ScopeAdmin;
+import org.apache.aries.subsystem.scope.ScopeUpdate;
+import org.apache.aries.subsystem.scope.SharePolicy;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.ServiceRegistration;
+
+public class ScopeUpdateImpl implements ScopeUpdate {
+
+    private ScopeImpl scope;
+    private List<InstallInfo> installInfo = new ArrayList<InstallInfo>();
+    private List<ScopeUpdate> children = new ArrayList<ScopeUpdate>();
+    private List<Scope> tbrChildren = new ArrayList<Scope>();
+    private BundleContext bc;
+    private static ConcurrentHashMap<Long, ServiceRegistration> srs = new ConcurrentHashMap<Long, ServiceRegistration>();
+    
+    public ScopeUpdateImpl(ScopeImpl scope, BundleContext bc) {
+        this.scope = scope;
+        this.bc = bc;
+    }
+    
+    public ScopeUpdateImpl(ScopeImpl scope, List<InstallInfo> installInfo) {
+        this.scope = scope;
+        this.installInfo = installInfo;
+    }
+    
+    
+    public ScopeUpdateImpl(ScopeImpl scope, List<InstallInfo> installInfo, List<ScopeUpdate> children) {
+        this.scope = scope;
+        this.installInfo = installInfo;
+        this.children = children;
+    }
+    
+    public ScopeImpl getScope() {
+        return this.scope;
+    }
+    
+    public boolean commit() throws BundleException {
+        // process installedBundle
+        boolean success = false;
+        List<Bundle> installedBundle = new ArrayList<Bundle>();
+        for (InstallInfo info : this.installInfo) {
+            URL url = info.getContent();
+            String loc = info.getLocation();
+            Bundle b;
+            Bundle oldB = alreadyInstalled(info);
+            
+            // in case of modify, uninstall the previous bundle first.
+            if (oldB != null) {
+                oldB.uninstall();
+                getBundles().remove(oldB);
+            }
+            
+            try {
+                scope.getToBeInstalledBundleLocation().add(loc);
+                b = bc.installBundle(loc, url.openStream());
+                installedBundle.add(b);
+            } catch (IOException e) {
+                // clear bundle location off the list.
+                scope.getToBeInstalledBundleLocation().remove(loc);
+                throw new BundleException("problem when opening url " + e.getCause());
+            }
+            scope.getToBeInstalledBundleLocation().remove(loc);
+        }
+        
+        // clear bundle location list since all install is finished.
+        scope.clearBundleLocations();
+        
+        // update bundle list for the scope
+        getBundles().addAll(installedBundle);
+
+        
+        // process child scopes
+        Collection<ScopeUpdate> children = getChildren();
+        for (ScopeUpdate child : children) {
+            
+            ScopeUpdateImpl scopeUpdateImpl = (ScopeUpdateImpl)child;
+            ServiceRegistration sr = null;
+            try {
+                // also create a new scopeAdmin as scopeadmin and scope is 1-1 relationship
+                ScopeAdminImpl newScopeAdmin = new ScopeAdminImpl(this.scope, scopeUpdateImpl.getScope());
+                
+                
+                sr = this.bc.registerService(ScopeAdmin.class.getName(), 
+                        newScopeAdmin, 
+                        DictionaryBuilder.build("ScopeName", child.getName(), "ScopeId", scopeUpdateImpl.getScope().getId()));
+                srs.put(scopeUpdateImpl.getScope().getId(), sr);
+                child.commit();
+            } catch (BundleException e) {
+                if (sr != null) {
+                    sr.unregister();
+                    srs.remove(scopeUpdateImpl.getScope().getId());
+                }
+                throw new BundleException("problem when commiting child scope: " + child.getName() + " " + e.getCause());
+            }
+            
+
+            // update current scope to specify the children.
+            getExistingChildren().add(scopeUpdateImpl.getScope());
+            
+
+        }
+        // remove any scopes in to be removed children list
+        for (Scope scope : tbrChildren) {
+            removeChildScope(scope); 
+        }
+        
+        
+        return true;
+    }
+    
+    // check if the install info is already installed in the scope
+    private Bundle alreadyInstalled(InstallInfo info) {
+        String loc = info.getLocation();
+        
+        Collection<Bundle> bundles = scope.getBundles();
+        
+        for (Bundle b : bundles) {
+            if (b.getLocation().equals(loc)) {
+                return b;
+            }
+        }
+        
+        return null;
+    }
+
+    public Collection<Bundle> getBundles() {
+        return scope.getModifiableBundles();
+    }
+
+    public List<InstallInfo> getBundlesToInstall() {
+        return this.installInfo;
+    }
+    
+    /*public List<InstallInfo> getBundlesToDelete() {
+        return this.installInfo;
+    }
+    
+    public List<InstallInfo> getBundlesToModify() {
+        return this.installInfo;
+    }*/
+
+    public Collection<ScopeUpdate> getChildren() {
+        return this.children;
+    }
+    
+    public Collection<Scope> getExistingChildren() {
+        return scope.getModifiableChildren();
+    }
+
+    public Collection<Scope> getToBeRemovedChildren() {
+        return this.tbrChildren;
+    }
+    
+    // this would remove the child off the scope and uninstall the scope.
+    private void removeChildScope(Scope sc) {
+        removeChildScope(sc.getId());
+    }
+    // this would remove the child off the scope and uninstall the scope.
+    private void removeChildScope(long id) {
+        Collection<Scope> scopes =  scope.getModifiableChildren();
+        for (Scope scope : scopes) {
+            if (scope.getId() == id) {
+                for (Bundle b : scope.getBundles()) {
+                    try {
+                        b.uninstall();
+                    } catch (BundleException e) {
+                        // TODO Auto-generated catch block
+                        e.printStackTrace();
+                    }
+                }
+                scopes.remove(scope);
+                // unregister the associated ScopeAdmin in service registry
+                ServiceRegistration sr = srs.get(id);
+                if (sr != null) {
+                    sr.unregister();
+                    srs.remove(id);
+                } else {
+                    throw new NullPointerException ("Unable to find the ScopeAdmin service Registration in the map");
+                }
+                return;
+            }
+        }
+    }
+    
+    public String getName() {
+        return scope.getName();
+    }
+
+    public Map<String, List<SharePolicy>> getSharePolicies(String type) {
+        return scope.getModifiableSharePolicies(type);
+    }
+
+    public ScopeUpdate newChild(String name) {
+        ScopeImpl newScope = new ScopeImpl(name);
+
+        // create scope update
+        ScopeUpdate scopeUpdate = new ScopeUpdateImpl(newScope, this.bc);
+        this.children.add(scopeUpdate);
+        return scopeUpdate;
+    }
+
+    public ScopeUpdate newChild(String name, String location) {
+        ScopeImpl newScope = new ScopeImpl(name, location);
+
+        // create scope update
+        ScopeUpdate scopeUpdate = new ScopeUpdateImpl(newScope, this.bc);
+        this.children.add(scopeUpdate);
+        return scopeUpdate;
+    }
+}

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/impl/ScopeUpdateImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java
URL: http://svn.apache.org/viewvc/incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java?rev=1022207&view=auto
==============================================================================
--- incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java (added)
+++ incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java Wed Oct 13 17:38:45 2010
@@ -0,0 +1,91 @@
+/*
+ * 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.aries.subsystem.scope.internal;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+
+import org.apache.aries.subsystem.scope.ScopeAdmin;
+import org.apache.aries.subsystem.scope.impl.ScopeAdminServiceFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+public class Activator implements BundleActivator {
+
+    private static BundleContext context;
+    private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
+    ScopeAdminServiceFactory scopeAdminFactory;
+
+    static BundleContext getContext() {
+        return context;
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext
+     * )
+     */
+    public void start(BundleContext bundleContext) throws Exception {
+        Activator.context = bundleContext;
+        scopeAdminFactory = new ScopeAdminServiceFactory();
+        scopeAdminFactory.init();
+        register(ScopeAdmin.class, scopeAdminFactory, null);
+
+    }
+
+    protected <T> void register(Class<T> clazz, T service, Dictionary props) {
+        registrations.add(context.registerService(clazz.getName(), service,
+                props));
+    }
+
+    protected <T> void register(Class<T> clazz, ServiceFactory factory,
+            Dictionary props) {
+        registrations.add(context.registerService(clazz.getName(), factory,
+                props));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+     */
+    public void stop(BundleContext bundleContext) throws Exception {
+        Activator.context = null;
+        for (ServiceRegistration r : registrations) {
+            try {
+                r.unregister();
+            } catch (Exception e) {
+                // LOGGER.warn("Scope Activator shut down", e);
+            }
+        }
+
+        scopeAdminFactory.destroy();
+    }
+
+    public static BundleContext getBundleContext() {
+        return context;
+    }
+
+}

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: incubator/aries/trunk/subsystem/subsystem-scope-impl/src/main/java/org/apache/aries/subsystem/scope/internal/Activator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain