KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > framework > internal > core > BundleLoaderProxy


1 /*******************************************************************************
2  * Copyright (c) 2003, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.osgi.framework.internal.core;
12
13 import java.io.IOException JavaDoc;
14 import java.net.URL JavaDoc;
15 import java.util.ArrayList JavaDoc;
16 import java.util.Enumeration JavaDoc;
17 import org.eclipse.osgi.framework.util.KeyedHashSet;
18 import org.eclipse.osgi.service.resolver.*;
19 import org.osgi.framework.*;
20 import org.osgi.service.packageadmin.RequiredBundle;
21
22 /*
23  * The BundleLoaderProxy proxies a BundleLoader object for a Bundle. This
24  * allows for a Bundle's depedencies to be linked without forcing the
25  * creating of the BundleLoader or BundleClassLoader objects. This class
26  * keeps track of the depedencies between the bundles installed in the
27  * Framework.
28  */

29 public class BundleLoaderProxy implements RequiredBundle {
30     // The BundleLoader that this BundleLoaderProxy is managing
31
private BundleLoader loader;
32     // The Bundle that this BundleLoaderProxy is for
33
final private BundleHost bundle;
34     // the BundleDescription for the Bundle
35
final private BundleDescription description;
36     // Indicates if this BundleLoaderProxy is stale;
37
// this is true when the bundle is updated or uninstalled.
38
private boolean stale = false;
39     // cached of package sources for the bundle
40
final private KeyedHashSet pkgSources;
41
42     public BundleLoaderProxy(BundleHost bundle, BundleDescription description) {
43         this.bundle = bundle;
44         this.description = description;
45         this.pkgSources = new KeyedHashSet(false);
46     }
47
48     synchronized BundleLoader getBundleLoader() {
49         if (loader != null)
50             return loader;
51         if (bundle.isResolved()) {
52             try {
53                 if (bundle.getBundleId() == 0) // this is the system bundle
54
loader = new SystemBundleLoader(bundle, this);
55                 else
56                     loader = new BundleLoader(bundle, this);
57             } catch (BundleException e) {
58                 bundle.framework.publishFrameworkEvent(FrameworkEvent.ERROR, bundle, e);
59                 return null;
60             }
61         }
62         return loader;
63     }
64
65     BundleLoader getBasicBundleLoader() {
66         return loader;
67     }
68
69     AbstractBundle getBundleHost() {
70         return bundle;
71     }
72
73     void setStale() {
74         stale = true;
75     }
76
77     boolean isStale() {
78         return stale;
79     }
80
81     public String JavaDoc toString() {
82         String JavaDoc symbolicName = bundle.getSymbolicName();
83         StringBuffer JavaDoc sb = new StringBuffer JavaDoc(symbolicName == null ? bundle.getBundleData().getLocation() : symbolicName);
84         sb.append("; ").append(Constants.BUNDLE_VERSION_ATTRIBUTE); //$NON-NLS-1$
85
sb.append("=\"").append(description.getVersion().toString()).append("\""); //$NON-NLS-1$//$NON-NLS-2$
86
return sb.toString();
87     }
88
89     public org.osgi.framework.Bundle getBundle() {
90         if (isStale())
91             return null;
92
93         return bundle;
94     }
95
96     public org.osgi.framework.Bundle[] getRequiringBundles() {
97         if (isStale())
98             return null;
99         // This is VERY slow; but never gets called in regular execution.
100
BundleDescription[] dependents = description.getDependents();
101         if (dependents == null || dependents.length == 0)
102             return null;
103         ArrayList JavaDoc result = new ArrayList JavaDoc(dependents.length);
104         for (int i = 0; i < dependents.length; i++)
105             addRequirers(dependents[i], result);
106         return result.size() == 0 ? null : (Bundle[]) result.toArray(new org.osgi.framework.Bundle[result.size()]);
107     }
108
109     void addRequirers(BundleDescription dependent, ArrayList JavaDoc result) {
110         if (dependent.getHost() != null) // don't look in fragments.
111
return;
112         BundleLoaderProxy dependentProxy = getBundleLoader().getLoaderProxy(dependent);
113         if (dependentProxy == null)
114             return; // bundle must have been uninstalled
115
if (result.contains(dependentProxy.bundle))
116             return; // prevent endless recusion
117
BundleLoader dependentLoader = dependentProxy.getBundleLoader();
118         BundleLoaderProxy[] requiredBundles = dependentLoader.requiredBundles;
119         int[] reexportTable = dependentLoader.reexportTable;
120         if (requiredBundles == null)
121             return;
122         int size = reexportTable == null ? 0 : reexportTable.length;
123         int reexportIndex = 0;
124         for (int i = 0; i < requiredBundles.length; i++) {
125             if (requiredBundles[i] == this) {
126                 result.add(dependentProxy.bundle);
127                 if (reexportIndex < size && reexportTable[reexportIndex] == i) {
128                     reexportIndex++;
129                     BundleDescription[] dependents = dependent.getDependents();
130                     if (dependents == null)
131                         return;
132                     for (int j = 0; j < dependents.length; j++)
133                         dependentProxy.addRequirers(dependents[j], result);
134                 }
135                 return;
136             }
137         }
138         return;
139     }
140
141     public String JavaDoc getSymbolicName() {
142         return description.getSymbolicName();
143     }
144
145     public Version getVersion() {
146         return description.getVersion();
147     }
148
149     public boolean isRemovalPending() {
150         return description.isRemovalPending();
151     }
152
153     BundleDescription getBundleDescription() {
154         return description;
155     }
156
157     PackageSource getPackageSource(String JavaDoc pkgName) {
158         // getByKey is called outside of a synch block because we really do not
159
// care too much of duplicates getting created. Only the first one will
160
// successfully get stored into pkgSources
161
PackageSource pkgSource = (PackageSource) pkgSources.getByKey(pkgName);
162         if (pkgSource == null) {
163             pkgSource = new SingleSourcePackage(pkgName, -1, this);
164             synchronized (pkgSources) {
165                 pkgSources.add(pkgSource);
166             }
167         }
168         return pkgSource;
169     }
170
171     boolean inUse() {
172         return description.getDependents().length > 0;
173     }
174
175     boolean forceSourceCreation(ExportPackageDescription export) {
176         if (!export.isRoot())
177             return true;
178         boolean strict = Constants.STRICT_MODE.equals(bundle.framework.adaptor.getState().getPlatformProperties()[0].get(Constants.OSGI_RESOLVER_MODE));
179         return (export.getDirective(Constants.INCLUDE_DIRECTIVE) != null) || (export.getDirective(Constants.EXCLUDE_DIRECTIVE) != null) || (strict && export.getDirective(Constants.FRIENDS_DIRECTIVE) != null);
180     }
181     // creates a PackageSource from an ExportPackageDescription. This is called when initializing
182
// a BundleLoader to ensure that the proper PackageSource gets created and used for
183
// filtered and reexport packages. The storeSource flag is used by initialize to indicate
184
// that the source for special case package sources (filtered or re-exported should be stored
185
// in the cache. if this flag is set then a normal SinglePackageSource will not be created
186
// (i.e. it will be created lazily)
187
PackageSource createPackageSource(ExportPackageDescription export, boolean storeSource) {
188         PackageSource pkgSource = null;
189         // check to see if it is a reexport
190
if (!export.isRoot()) {
191             pkgSource = new ReexportPackageSource(export.getName());
192         } else {
193             // check to see if it is a filtered export
194
String JavaDoc includes = (String JavaDoc) export.getDirective(Constants.INCLUDE_DIRECTIVE);
195             String JavaDoc excludes = (String JavaDoc) export.getDirective(Constants.EXCLUDE_DIRECTIVE);
196             String JavaDoc[] friends = (String JavaDoc[]) export.getDirective(Constants.FRIENDS_DIRECTIVE);
197             if (friends != null) {
198                 boolean strict = Constants.STRICT_MODE.equals(bundle.framework.adaptor.getState().getPlatformProperties()[0].get(Constants.OSGI_RESOLVER_MODE));
199                 if (!strict)
200                     friends = null; // do not pay attention to friends if not in strict mode
201
}
202             if (includes != null || excludes != null || friends != null) {
203                 ExportPackageDescription[] exports = description.getExportPackages();
204                 int index = -1;
205                 int first = -1;
206                 for (int i = 0; i < exports.length; i++) {
207                     if (first == -1 && exports[i].getName().equals(export.getName()))
208                         first = i;
209                     if (exports[i] == export && first != i) {
210                         index = i;
211                         break;
212                     }
213                 }
214                 pkgSource = new FilteredSourcePackage(export.getName(), index, this, includes, excludes, friends);
215             }
216         }
217
218         if (storeSource) {
219             // if the package source is not null then store the source only if it is not already present;
220
// getByKey is called outside of a synch block because we really do not
221
// care too much of duplicates getting created. Only the first one will
222
// successfully get stored into pkgSources
223
if (pkgSource != null && pkgSources.getByKey(export.getName()) == null)
224                 synchronized (pkgSources) {
225                     pkgSources.add(pkgSource);
226                 }
227         } else {
228             // we are not storing the special case sources, but pkgSource == null this means this
229
// is a normal package source; get it and return it.
230
if (pkgSource == null)
231                 pkgSource = getPackageSource(export.getName());
232         }
233
234         return pkgSource;
235     }
236
237     class ReexportPackageSource extends PackageSource {
238         public ReexportPackageSource(String JavaDoc id) {
239             super(id);
240         }
241
242         public synchronized SingleSourcePackage[] getSuppliers() {
243             PackageSource source = getBundleLoader().getPackageSource(id);
244             if (source == null)
245                 return null;
246             return source.getSuppliers();
247         }
248
249         public Class JavaDoc loadClass(String JavaDoc name) {
250             try {
251                 return getBundleLoader().findClass(name, false);
252             } catch (ClassNotFoundException JavaDoc e) {
253                 return null;
254             }
255         }
256
257         public URL JavaDoc getResource(String JavaDoc name) {
258             return getBundleLoader().findResource(name, false);
259         }
260
261         public Enumeration JavaDoc getResources(String JavaDoc name) throws IOException JavaDoc {
262             return getBundleLoader().findResources(name);
263         }
264     }
265 }
266
Popular Tags