001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one
003     * or more contributor license agreements.  See the NOTICE file
004     * distributed with this work for additional information
005     * regarding copyright ownership.  The ASF licenses this file
006     * to you under the Apache License, Version 2.0 (the
007     * "License"); you may not use this file except in compliance
008     * with the License.  You may obtain a copy of the License at
009     *
010     *  http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing,
013     * software distributed under the License is distributed on an
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015     * KIND, either express or implied.  See the License for the
016     * specific language governing permissions and limitations
017     * under the License.
018     */
019    
020    package org.apache.xbean.osgi.bundle.util;
021    
022    import java.io.IOException;
023    import java.io.InputStream;
024    import java.net.URL;
025    import java.util.ArrayList;
026    import java.util.Collection;
027    import java.util.Collections;
028    import java.util.Dictionary;
029    import java.util.Enumeration;
030    import java.util.List;
031    import java.util.Map;
032    
033    import org.osgi.framework.Bundle;
034    import org.osgi.framework.BundleContext;
035    import org.osgi.framework.BundleException;
036    import org.osgi.framework.ServiceReference;
037    import org.osgi.framework.Version;
038    
039    /**
040     * Bundle that delegates ClassLoader operations to a collection of {@link Bundle} objects. 
041     * 
042     * @version $Rev: 937957 $ $Date: 2010-04-26 10:00:08 +0200 (Mon, 26 Apr 2010) $
043     */
044    public class DelegatingBundle implements Bundle {
045    
046        private Collection<Bundle> bundles;
047        private Bundle bundle;
048        private BundleContext bundleContext;
049    
050        public DelegatingBundle(Collection<Bundle> bundles) {
051            this.bundles = bundles;
052            if (bundles.isEmpty()) {
053                throw new IllegalArgumentException("At least one bundle is required");
054            }
055            // assume first Bundle is the main bundle
056            this.bundle = bundles.iterator().next();
057            this.bundleContext = new DelegatingBundleContext(this, bundle.getBundleContext());
058        }
059           
060        public Bundle getMainBundle() {
061            return bundle;
062        }
063        
064        public Class<?> loadClass(String name) throws ClassNotFoundException {
065            for (Bundle bundle : bundles) {
066                try {
067                    return bundle.loadClass(name);
068                } catch (ClassNotFoundException ex) {
069                    // ignore
070                }
071            }
072            throw new ClassNotFoundException(name);
073        }
074    
075        public URL getResource(String name) {
076            URL resource = null;
077            for (Bundle bundle : bundles) {
078                resource = bundle.getResource(name);
079                if (resource != null) {
080                    return resource;
081                }
082            }
083            return null;
084        }
085    
086        public Enumeration<URL> getResources(String name) throws IOException {
087            ArrayList<URL> allResources = new ArrayList<URL>();
088            for (Bundle bundle : bundles) {
089                Enumeration<URL> e = (Enumeration<URL>) bundle.getResources(name);
090                addToList(allResources, e);
091            }
092            return Collections.enumeration(allResources); 
093        }    
094        
095        private static void addToList(List<URL> list, Enumeration<URL> enumeration) {
096            if (enumeration != null) {
097                while (enumeration.hasMoreElements()) {
098                    list.add(enumeration.nextElement());
099                }
100            }
101        }
102    
103        public BundleContext getBundleContext() {
104            return bundleContext;
105        }
106        
107        public Enumeration findEntries(String arg0, String arg1, boolean arg2) {
108            return bundle.findEntries(arg0, arg1, arg2);
109        }
110    
111        public long getBundleId() {
112            return bundle.getBundleId();
113        }
114    
115        public URL getEntry(String arg0) {
116            return bundle.getEntry(arg0);
117        }
118    
119        public Enumeration getEntryPaths(String arg0) {
120            return bundle.getEntryPaths(arg0);
121        }
122    
123        public Dictionary getHeaders() {
124            return bundle.getHeaders();
125        }
126    
127        public Dictionary getHeaders(String arg0) {
128            return bundle.getHeaders(arg0);
129        }
130    
131        public long getLastModified() {
132            return bundle.getLastModified();
133        }
134    
135        public String getLocation() {
136            return bundle.getLocation();
137        }
138    
139        public ServiceReference[] getRegisteredServices() {
140            return bundle.getRegisteredServices();
141        }
142    
143        public ServiceReference[] getServicesInUse() {
144            return bundle.getServicesInUse();
145        }
146    
147        public Map getSignerCertificates(int arg0) {
148            return bundle.getSignerCertificates(arg0);
149        }
150    
151        public int getState() {
152            return bundle.getState();
153        }
154    
155        public String getSymbolicName() {
156            return bundle.getSymbolicName();
157        }
158    
159        public Version getVersion() {
160            return bundle.getVersion();
161        }
162    
163        public boolean hasPermission(Object arg0) {
164            return bundle.hasPermission(arg0);
165        }
166    
167        public void start() throws BundleException {
168            bundle.start();
169        }
170    
171        public void start(int arg0) throws BundleException {
172            bundle.start(arg0);
173        }
174    
175        public void stop() throws BundleException {
176            bundle.stop();
177        }
178    
179        public void stop(int arg0) throws BundleException {
180            bundle.stop(arg0);
181        }
182    
183        public void uninstall() throws BundleException {
184            bundle.uninstall();
185        }
186    
187        public void update() throws BundleException {
188            bundle.update();
189        }
190    
191        public void update(InputStream arg0) throws BundleException {
192            bundle.update(arg0);
193        }
194    
195        public String toString() {
196            return "[DelegatingBundle: " + bundles + "]";
197        }
198               
199    }