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.io.File;
025    import java.net.URL;
026    import java.util.ArrayList;
027    import java.util.Collection;
028    import java.util.Collections;
029    import java.util.Dictionary;
030    import java.util.Enumeration;
031    import java.util.List;
032    import java.util.Map;
033    
034    import org.osgi.framework.Bundle;
035    import org.osgi.framework.BundleContext;
036    import org.osgi.framework.BundleException;
037    import org.osgi.framework.ServiceReference;
038    import org.osgi.framework.Version;
039    
040    /**
041     * Bundle that delegates ClassLoader operations to a collection of {@link Bundle} objects. 
042     * 
043     * @version $Rev: 937957 $ $Date: 2010-04-26 10:00:08 +0200 (lun. 26 avril 2010) $
044     */
045    public class DelegatingBundle implements Bundle {
046    
047        private Collection<Bundle> bundles;
048        private Bundle bundle;
049        private BundleContext bundleContext;
050    
051        public DelegatingBundle(Collection<Bundle> bundles) {
052            this.bundles = bundles;
053            if (bundles.isEmpty()) {
054                throw new IllegalArgumentException("At least one bundle is required");
055            }
056            // assume first Bundle is the main bundle
057            this.bundle = bundles.iterator().next();
058            this.bundleContext = new DelegatingBundleContext(this, bundle.getBundleContext());
059        }
060           
061        public Bundle getMainBundle() {
062            return bundle;
063        }
064        
065        public Class<?> loadClass(String name) throws ClassNotFoundException {
066            for (Bundle bundle : bundles) {
067                try {
068                    return bundle.loadClass(name);
069                } catch (ClassNotFoundException ex) {
070                    // ignore
071                }
072            }
073            throw new ClassNotFoundException(name);
074        }
075    
076        public URL getResource(String name) {
077            URL resource = null;
078            for (Bundle bundle : bundles) {
079                resource = bundle.getResource(name);
080                if (resource != null) {
081                    return resource;
082                }
083            }
084            return null;
085        }
086    
087        public Enumeration<URL> getResources(String name) throws IOException {
088            ArrayList<URL> allResources = new ArrayList<URL>();
089            for (Bundle bundle : bundles) {
090                Enumeration<URL> e = (Enumeration<URL>) bundle.getResources(name);
091                addToList(allResources, e);
092            }
093            return Collections.enumeration(allResources); 
094        }    
095        
096        private static void addToList(List<URL> list, Enumeration<URL> enumeration) {
097            if (enumeration != null) {
098                while (enumeration.hasMoreElements()) {
099                    list.add(enumeration.nextElement());
100                }
101            }
102        }
103    
104        public BundleContext getBundleContext() {
105            return bundleContext;
106        }
107        
108        public Enumeration findEntries(String arg0, String arg1, boolean arg2) {
109            return bundle.findEntries(arg0, arg1, arg2);
110        }
111    
112        public long getBundleId() {
113            return bundle.getBundleId();
114        }
115    
116        public URL getEntry(String arg0) {
117            return bundle.getEntry(arg0);
118        }
119    
120        public Enumeration getEntryPaths(String arg0) {
121            return bundle.getEntryPaths(arg0);
122        }
123    
124        public Dictionary getHeaders() {
125            return bundle.getHeaders();
126        }
127    
128        public Dictionary getHeaders(String arg0) {
129            return bundle.getHeaders(arg0);
130        }
131    
132        public long getLastModified() {
133            return bundle.getLastModified();
134        }
135    
136        public String getLocation() {
137            return bundle.getLocation();
138        }
139    
140        public ServiceReference[] getRegisteredServices() {
141            return bundle.getRegisteredServices();
142        }
143    
144        public ServiceReference[] getServicesInUse() {
145            return bundle.getServicesInUse();
146        }
147    
148        public Map getSignerCertificates(int arg0) {
149            return bundle.getSignerCertificates(arg0);
150        }
151    
152        public int getState() {
153            return bundle.getState();
154        }
155    
156        public String getSymbolicName() {
157            return bundle.getSymbolicName();
158        }
159    
160        public Version getVersion() {
161            return bundle.getVersion();
162        }
163    
164        public boolean hasPermission(Object arg0) {
165            return bundle.hasPermission(arg0);
166        }
167    
168        public void start() throws BundleException {
169            bundle.start();
170        }
171    
172        public void start(int arg0) throws BundleException {
173            bundle.start(arg0);
174        }
175    
176        public void stop() throws BundleException {
177            bundle.stop();
178        }
179    
180        public void stop(int arg0) throws BundleException {
181            bundle.stop(arg0);
182        }
183    
184        public void uninstall() throws BundleException {
185            bundle.uninstall();
186        }
187    
188        public void update() throws BundleException {
189            bundle.update();
190        }
191    
192        public void update(InputStream arg0) throws BundleException {
193            bundle.update(arg0);
194        }
195    
196        public String toString() {
197            return "[DelegatingBundle: " + bundles + "]";
198        }
199        
200        // OSGI 4.3
201        public File getDataFile(String filename) {
202            return bundle.getDataFile(filename);
203        }
204        
205        // OSGI 4.3
206        public <A> A adapt(Class<A> type) {
207            return bundle.<A>adapt(type);
208        }
209    
210        // OSGI 4.3
211        public int compareTo(Bundle bundle) {
212            return bundle.compareTo(bundle);
213        }
214    }