KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > osgi > internal > resolver > BundleDescriptionImpl


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.internal.resolver;
12
13 import java.io.IOException JavaDoc;
14 import java.util.*;
15 import org.eclipse.osgi.framework.internal.core.Constants;
16 import org.eclipse.osgi.framework.util.KeyedElement;
17 import org.eclipse.osgi.service.resolver.*;
18
19 public class BundleDescriptionImpl extends BaseDescriptionImpl implements BundleDescription, KeyedElement {
20     static final String JavaDoc[] EMPTY_STRING = new String JavaDoc[0];
21     static final ImportPackageSpecification[] EMPTY_IMPORTS = new ImportPackageSpecification[0];
22     static final BundleSpecification[] EMPTY_BUNDLESPECS = new BundleSpecification[0];
23     static final ExportPackageDescription[] EMPTY_EXPORTS = new ExportPackageDescription[0];
24     static final BundleDescription[] EMPTY_BUNDLEDESCS = new BundleDescription[0];
25     static final GenericSpecification[] EMPTY_GENERICSPECS = new GenericSpecification[0];
26     static final GenericDescription[] EMPTY_GENERICDESCS = new GenericDescription[0];
27
28     static final int RESOLVED = 0x01;
29     static final int SINGLETON = 0x02;
30     static final int REMOVAL_PENDING = 0x04;
31     static final int FULLY_LOADED = 0x08;
32     static final int LAZY_LOADED = 0x10;
33     static final int HAS_DYNAMICIMPORT = 0x20;
34     static final int ATTACH_FRAGMENTS = 0x40;
35     static final int DYNAMIC_FRAGMENTS = 0x80;
36
37     // set to fully loaded and allow dynamic fragments by default
38
private int stateBits = FULLY_LOADED | ATTACH_FRAGMENTS | DYNAMIC_FRAGMENTS;
39
40     private long bundleId = -1;
41     private HostSpecification host; //null if the bundle is not a fragment
42
private StateImpl containingState;
43
44     private Object JavaDoc userObject;
45     private int lazyDataOffset = -1;
46     private int lazyDataSize = -1;
47
48     //TODO These could be arrays
49
private ArrayList dependencies;
50     private ArrayList dependents;
51
52     private LazyData lazyData;
53     private int equinox_ee = -1;
54
55     public BundleDescriptionImpl() {
56         //
57
}
58
59     public long getBundleId() {
60         return bundleId;
61     }
62
63     public String JavaDoc getSymbolicName() {
64         return getName();
65     }
66
67     public BundleDescription getSupplier() {
68         return this;
69     }
70
71     public String JavaDoc getLocation() {
72         fullyLoad();
73         return lazyData.location;
74     }
75
76     public String JavaDoc getPlatformFilter() {
77         fullyLoad();
78         return lazyData.platformFilter;
79     }
80
81     public String JavaDoc[] getExecutionEnvironments() {
82         fullyLoad();
83         if (lazyData.executionEnvironments == null)
84             return EMPTY_STRING;
85         return lazyData.executionEnvironments;
86     }
87
88     public ImportPackageSpecification[] getImportPackages() {
89         fullyLoad();
90         if (lazyData.importPackages == null)
91             return EMPTY_IMPORTS;
92         return lazyData.importPackages;
93     }
94
95     public BundleSpecification[] getRequiredBundles() {
96         fullyLoad();
97         if (lazyData.requiredBundles == null)
98             return EMPTY_BUNDLESPECS;
99         return lazyData.requiredBundles;
100     }
101
102     public GenericSpecification[] getGenericRequires() {
103         fullyLoad();
104         if (lazyData.genericRequires == null)
105             return EMPTY_GENERICSPECS;
106         return lazyData.genericRequires;
107     }
108
109     public GenericDescription[] getGenericCapabilities() {
110         fullyLoad();
111         if (lazyData.genericCapabilities == null)
112             return EMPTY_GENERICDESCS;
113         return lazyData.genericCapabilities;
114     }
115
116     public ExportPackageDescription[] getExportPackages() {
117         fullyLoad();
118         return lazyData.exportPackages == null ? EMPTY_EXPORTS : lazyData.exportPackages;
119     }
120
121     public boolean isResolved() {
122         return (stateBits & RESOLVED) != 0;
123     }
124
125     public State getContainingState() {
126         return containingState;
127     }
128
129     public BundleDescription[] getFragments() {
130         if (host != null)
131             return EMPTY_BUNDLEDESCS;
132         return containingState.getFragments(this);
133     }
134
135     public HostSpecification getHost() {
136         return host;
137     }
138
139     public boolean isSingleton() {
140         return (stateBits & SINGLETON) != 0;
141     }
142
143     public boolean isRemovalPending() {
144         return (stateBits & REMOVAL_PENDING) != 0;
145     }
146
147     public boolean hasDynamicImports() {
148         return (stateBits & HAS_DYNAMICIMPORT) != 0;
149     }
150
151     public boolean attachFragments() {
152         return (stateBits & ATTACH_FRAGMENTS) != 0;
153     }
154
155     public boolean dynamicFragments() {
156         return (stateBits & DYNAMIC_FRAGMENTS) != 0;
157     }
158
159     public ExportPackageDescription[] getSelectedExports() {
160         fullyLoad();
161         if (lazyData.selectedExports == null)
162             return EMPTY_EXPORTS;
163         return lazyData.selectedExports;
164     }
165
166     public BundleDescription[] getResolvedRequires() {
167         fullyLoad();
168         if (lazyData.resolvedRequires == null)
169             return EMPTY_BUNDLEDESCS;
170         return lazyData.resolvedRequires;
171     }
172
173     public ExportPackageDescription[] getResolvedImports() {
174         fullyLoad();
175         if (lazyData.resolvedImports == null)
176             return EMPTY_EXPORTS;
177         return lazyData.resolvedImports;
178     }
179
180     protected void setBundleId(long bundleId) {
181         this.bundleId = bundleId;
182     }
183
184     protected void setSymbolicName(String JavaDoc symbolicName) {
185         setName(symbolicName);
186     }
187
188     protected void setLocation(String JavaDoc location) {
189         checkLazyData();
190         lazyData.location = location;
191     }
192
193     protected void setPlatformFilter(String JavaDoc platformFilter) {
194         checkLazyData();
195         lazyData.platformFilter = platformFilter;
196     }
197
198     protected void setExecutionEnvironments(String JavaDoc[] executionEnvironments) {
199         checkLazyData();
200         lazyData.executionEnvironments = executionEnvironments;
201     }
202
203     protected void setExportPackages(ExportPackageDescription[] exportPackages) {
204         checkLazyData();
205         lazyData.exportPackages = exportPackages;
206         if (exportPackages != null) {
207             for (int i = 0; i < exportPackages.length; i++) {
208                 ((ExportPackageDescriptionImpl) exportPackages[i]).setExporter(this);
209             }
210         }
211     }
212
213     protected void setImportPackages(ImportPackageSpecification[] importPackages) {
214         checkLazyData();
215         lazyData.importPackages = importPackages;
216         if (importPackages != null) {
217             for (int i = 0; i < importPackages.length; i++) {
218                 if (Constants.OSGI_SYSTEM_BUNDLE.equals(importPackages[i].getBundleSymbolicName()))
219                     ((ImportPackageSpecificationImpl) importPackages[i]).setBundleSymbolicName(Constants.getInternalSymbolicName());
220                 ((ImportPackageSpecificationImpl) importPackages[i]).setBundle(this);
221                 if (ImportPackageSpecification.RESOLUTION_DYNAMIC.equals(importPackages[i].getDirective(Constants.RESOLUTION_DIRECTIVE)))
222                     stateBits |= HAS_DYNAMICIMPORT;
223             }
224         }
225     }
226
227     protected void setRequiredBundles(BundleSpecification[] requiredBundles) {
228         checkLazyData();
229         lazyData.requiredBundles = requiredBundles;
230         if (requiredBundles != null)
231             for (int i = 0; i < requiredBundles.length; i++) {
232                 if (Constants.OSGI_SYSTEM_BUNDLE.equals(requiredBundles[i].getName()))
233                     ((VersionConstraintImpl) requiredBundles[i]).setName(Constants.getInternalSymbolicName());
234                 ((VersionConstraintImpl) requiredBundles[i]).setBundle(this);
235             }
236     }
237
238     protected void setGenericCapabilities(GenericDescription[] genericCapabilities) {
239         checkLazyData();
240         lazyData.genericCapabilities = genericCapabilities;
241         if (genericCapabilities != null)
242             for (int i = 0; i < genericCapabilities.length; i++)
243                 ((GenericDescriptionImpl) genericCapabilities[i]).setSupplier(this);
244     }
245
246     protected void setGenericRequires(GenericSpecification[] genericRequires) {
247         checkLazyData();
248         lazyData.genericRequires = genericRequires;
249         if (genericRequires != null)
250             for (int i = 0; i < genericRequires.length; i++)
251                 ((VersionConstraintImpl) genericRequires[i]).setBundle(this);
252     }
253
254     protected int getStateBits() {
255         return stateBits;
256     }
257
258     protected void setStateBit(int stateBit, boolean on) {
259         if (on)
260             stateBits |= stateBit;
261         else
262             stateBits &= ~stateBit;
263     }
264
265     protected void setContainingState(State value) {
266         containingState = (StateImpl) value;
267         if (containingState != null && containingState.getReader() != null) {
268             if (containingState.getReader().isLazyLoaded())
269                 stateBits |= LAZY_LOADED;
270             else
271                 stateBits &= ~LAZY_LOADED;
272         } else {
273             stateBits &= ~LAZY_LOADED;
274         }
275     }
276
277     protected void setHost(HostSpecification host) {
278         this.host = host;
279         if (host != null) {
280             if (Constants.OSGI_SYSTEM_BUNDLE.equals(host.getName()))
281                 ((VersionConstraintImpl) host).setName(Constants.getInternalSymbolicName());
282             ((VersionConstraintImpl) host).setBundle(this);
283         }
284     }
285
286     protected void setLazyLoaded(boolean lazyLoad) {
287         fullyLoad();
288         if (lazyLoad)
289             stateBits |= LAZY_LOADED;
290         else
291             stateBits &= ~LAZY_LOADED;
292     }
293
294     protected void setSelectedExports(ExportPackageDescription[] selectedExports) {
295         checkLazyData();
296         lazyData.selectedExports = selectedExports;
297         if (selectedExports != null) {
298             for (int i = 0; i < selectedExports.length; i++) {
299                 ((ExportPackageDescriptionImpl) selectedExports[i]).setExporter(this);
300             }
301         }
302     }
303
304     protected void setResolvedImports(ExportPackageDescription[] resolvedImports) {
305         checkLazyData();
306         lazyData.resolvedImports = resolvedImports;
307     }
308
309     protected void setResolvedRequires(BundleDescription[] resolvedRequires) {
310         checkLazyData();
311         lazyData.resolvedRequires = resolvedRequires;
312     }
313
314     public String JavaDoc toString() {
315         if (getSymbolicName() == null)
316             return "[" + getBundleId() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
317
return getSymbolicName() + "_" + getVersion(); //$NON-NLS-1$
318
}
319
320     public Object JavaDoc getKey() {
321         return new Long JavaDoc(bundleId);
322     }
323
324     public boolean compare(KeyedElement other) {
325         if (!(other instanceof BundleDescriptionImpl))
326             return false;
327         BundleDescriptionImpl otherBundleDescription = (BundleDescriptionImpl) other;
328         return bundleId == otherBundleDescription.bundleId;
329     }
330
331     public int getKeyHashCode() {
332         return (int) (bundleId % Integer.MAX_VALUE);
333     }
334
335     /* TODO Determine if we need more than just Object ID type of hashcode.
336      public int hashCode() {
337      if (getSymbolicName() == null)
338      return (int) (bundleId % Integer.MAX_VALUE);
339      return (int) ((bundleId * (getSymbolicName().hashCode())) % Integer.MAX_VALUE);
340      }
341      */

342
343     protected synchronized void removeDependencies() {
344         if (dependencies == null)
345             return;
346         Iterator iter = dependencies.iterator();
347         while (iter.hasNext()) {
348             ((BundleDescriptionImpl) iter.next()).removeDependent(this);
349         }
350         dependencies = null;
351     }
352
353     protected void addDependencies(BaseDescription[] newDependencies, boolean checkDups) {
354         if (newDependencies == null)
355             return;
356         if (!checkDups && dependencies == null)
357             dependencies = new ArrayList(newDependencies.length);
358         for (int i = 0; i < newDependencies.length; i++) {
359             addDependency((BaseDescriptionImpl) newDependencies[i], checkDups);
360         }
361     }
362
363     protected synchronized void addDependency(BaseDescriptionImpl dependency, boolean checkDups) {
364         BundleDescriptionImpl bundle = (BundleDescriptionImpl) dependency.getSupplier();
365         if (bundle == this)
366             return;
367         if (dependencies == null)
368             dependencies = new ArrayList(10);
369         if (!checkDups || !dependencies.contains(bundle)) {
370             bundle.addDependent(this);
371             dependencies.add(bundle);
372         }
373     }
374
375     /*
376      * Gets all the bundle dependencies as a result of import-package or require-bundle.
377      * Self and fragment bundles are removed.
378      */

379     synchronized List getBundleDependencies() {
380         if (dependencies == null)
381             return new ArrayList(0);
382         ArrayList required = new ArrayList(dependencies.size());
383         for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
384             Object JavaDoc dep = iter.next();
385             if (dep != this && dep instanceof BundleDescription && ((BundleDescription) dep).getHost() == null)
386                 required.add(dep);
387         }
388         return required;
389     }
390
391     public Object JavaDoc getUserObject() {
392         return userObject;
393     }
394
395     public void setUserObject(Object JavaDoc userObject) {
396         this.userObject = userObject;
397     }
398
399     protected synchronized void addDependent(BundleDescription dependent) {
400         if (dependents == null)
401             dependents = new ArrayList(10);
402         // no need to check for duplicates here; this is only called in addDepenency which already checks for dups.
403
dependents.add(dependent);
404     }
405
406     protected synchronized void removeDependent(BundleDescription dependent) {
407         if (dependents == null)
408             return;
409         dependents.remove(dependent);
410     }
411
412     public synchronized BundleDescription[] getDependents() {
413         if (dependents == null)
414             return EMPTY_BUNDLEDESCS;
415         return (BundleDescription[]) dependents.toArray(new BundleDescription[dependents.size()]);
416     }
417
418     void setFullyLoaded(boolean fullyLoaded) {
419         if (fullyLoaded) {
420             stateBits |= FULLY_LOADED;
421         } else {
422             stateBits &= ~FULLY_LOADED;
423         }
424     }
425
426     boolean isFullyLoaded() {
427         return (stateBits & FULLY_LOADED) != 0;
428     }
429
430     void setLazyDataOffset(int lazyDataOffset) {
431         this.lazyDataOffset = lazyDataOffset;
432     }
433
434     int getLazyDataOffset() {
435         return this.lazyDataOffset;
436     }
437
438     void setLazyDataSize(int lazyDataSize) {
439         this.lazyDataSize = lazyDataSize;
440     }
441
442     int getLazyDataSize() {
443         return this.lazyDataSize;
444     }
445
446     private void fullyLoad() {
447         if ((stateBits & LAZY_LOADED) == 0)
448             return;
449         StateReader reader = containingState.getReader();
450         synchronized (reader) {
451             if (isFullyLoaded()) {
452                 reader.setAccessedFlag(true); // set reader accessed flag
453
return;
454             }
455             try {
456                 reader.fullyLoad(this);
457             } catch (IOException JavaDoc e) {
458                 throw new RuntimeException JavaDoc(e.getMessage()); // TODO not sure what to do here!!
459
}
460         }
461     }
462
463     synchronized void addDynamicResolvedImport(ExportPackageDescriptionImpl result) {
464         // mark the dependency
465
addDependency(result, true);
466         // add the export to the list of the resolvedImports
467
checkLazyData();
468         if (lazyData.resolvedImports == null) {
469             lazyData.resolvedImports = new ExportPackageDescription[] {result};
470             return;
471         }
472         ExportPackageDescription[] newImports = new ExportPackageDescription[lazyData.resolvedImports.length + 1];
473         System.arraycopy(lazyData.resolvedImports, 0, newImports, 0, lazyData.resolvedImports.length);
474         newImports[newImports.length - 1] = result;
475         lazyData.resolvedImports = newImports;
476         setLazyLoaded(false);
477     }
478
479     /*
480      * This method must be called while the state reader for the containing state is locked.
481      */

482     void unload() {
483         if ((stateBits & LAZY_LOADED) == 0)
484             return;
485         if (!isFullyLoaded())
486             return;
487         setFullyLoaded(false);
488         LazyData tempData = lazyData;
489         lazyData = null;
490         if (tempData == null || tempData.selectedExports == null)
491             return;
492         for (int i = 0; i < tempData.selectedExports.length; i++)
493             containingState.getReader().objectTable.remove(new Integer JavaDoc(((ExportPackageDescriptionImpl) tempData.selectedExports[i]).getTableIndex()));
494     }
495
496     void setDynamicStamps(HashMap dynamicStamps) {
497         lazyData.dynamicStamps = dynamicStamps;
498     }
499
500     void setDynamicStamp(String JavaDoc requestedPackage, Long JavaDoc timestamp) {
501         checkLazyData();
502         if (lazyData.dynamicStamps == null) {
503             if (timestamp == null)
504                 return;
505             lazyData.dynamicStamps = new HashMap();
506         }
507         if (timestamp == null)
508             lazyData.dynamicStamps.remove(requestedPackage);
509         else
510             lazyData.dynamicStamps.put(requestedPackage, timestamp);
511     }
512
513     long getDynamicStamp(String JavaDoc requestedPackage) {
514         fullyLoad();
515         Long JavaDoc stamp = lazyData.dynamicStamps == null ? null : (Long JavaDoc) lazyData.dynamicStamps.get(requestedPackage);
516         return stamp == null ? 0 : stamp.longValue();
517     }
518
519     HashMap getDynamicStamps() {
520         fullyLoad();
521         return lazyData.dynamicStamps;
522     }
523
524     public void setEquinoxEE(int equinox_ee) {
525         this.equinox_ee = equinox_ee;
526     }
527
528     public int getEquinoxEE() {
529         return equinox_ee;
530     }
531
532     private void checkLazyData() {
533         if (lazyData == null)
534             lazyData = new LazyData();
535     }
536
537     private final class LazyData {
538         String JavaDoc location;
539         String JavaDoc platformFilter;
540
541         BundleSpecification[] requiredBundles;
542         ExportPackageDescription[] exportPackages;
543         ImportPackageSpecification[] importPackages;
544         GenericDescription[] genericCapabilities;
545         GenericSpecification[] genericRequires;
546
547         ExportPackageDescription[] selectedExports;
548         BundleDescription[] resolvedRequires;
549         ExportPackageDescription[] resolvedImports;
550
551         String JavaDoc[] executionEnvironments;
552
553         HashMap dynamicStamps;
554     }
555 }
556
Popular Tags