KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2003, 2007 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.util.*;
14
15 import org.eclipse.osgi.framework.debug.Debug;
16 import org.eclipse.osgi.framework.debug.FrameworkDebugOptions;
17 import org.eclipse.osgi.framework.internal.core.Constants;
18 import org.eclipse.osgi.framework.internal.core.FilterImpl;
19 import org.eclipse.osgi.framework.util.*;
20 import org.eclipse.osgi.internal.baseadaptor.StateManager;
21 import org.eclipse.osgi.service.resolver.*;
22 import org.eclipse.osgi.util.ManifestElement;
23 import org.osgi.framework.*;
24
25 public abstract class StateImpl implements State {
26     public static final String JavaDoc[] PROPS = {"osgi.os", "osgi.ws", "osgi.nl", "osgi.arch", Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES, Constants.OSGI_RESOLVER_MODE, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, "osgi.resolveOptional", "osgi.genericAliases"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
27
transient private Resolver resolver;
28     transient private StateDeltaImpl changes;
29     transient private boolean resolving = false;
30     transient private HashSet removalPendings = new HashSet();
31     private boolean resolved = true;
32     private long timeStamp = System.currentTimeMillis();
33     private KeyedHashSet bundleDescriptions = new KeyedHashSet(false);
34     private HashMap resolverErrors = new HashMap();
35     private StateObjectFactory factory;
36     private KeyedHashSet resolvedBundles = new KeyedHashSet();
37     boolean fullyLoaded = false;
38     private boolean dynamicCacheChanged = false;
39     // only used for lazy loading of BundleDescriptions
40
private StateReader reader;
41     private Dictionary[] platformProperties = {new Hashtable(PROPS.length)}; // Dictionary here because of Filter API
42
private long highestBundleId = -1;
43     private HashSet platformPropertyKeys = new HashSet(PROPS.length);
44
45     private static long cumulativeTime;
46
47     // to prevent extra-package instantiation
48
protected StateImpl() {
49         // always add the default platform property keys.
50
addPlatformPropertyKeys(PROPS);
51     }
52
53     public boolean addBundle(BundleDescription description) {
54         if (!basicAddBundle(description))
55             return false;
56         String JavaDoc platformFilter = description.getPlatformFilter();
57         if (platformFilter != null) {
58             try {
59                 // add any new platform filter propery keys this bundle is using
60
FilterImpl filter = (FilterImpl) FrameworkUtil.createFilter(platformFilter);
61                 addPlatformPropertyKeys(filter.getAttributes());
62             } catch (InvalidSyntaxException e) {
63                 // ignore this is handled in another place
64
}
65         }
66         resolved = false;
67         getDelta().recordBundleAdded((BundleDescriptionImpl) description);
68         if (Constants.getInternalSymbolicName().equals(description.getSymbolicName()))
69             resetSystemExports();
70         if (resolver != null)
71             resolver.bundleAdded(description);
72         updateTimeStamp();
73         return true;
74     }
75
76     public boolean updateBundle(BundleDescription newDescription) {
77         BundleDescriptionImpl existing = (BundleDescriptionImpl) bundleDescriptions.get((BundleDescriptionImpl) newDescription);
78         if (existing == null)
79             return false;
80         if (!bundleDescriptions.remove(existing))
81             return false;
82         resolvedBundles.remove(existing);
83         existing.setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, true);
84         if (!basicAddBundle(newDescription))
85             return false;
86         resolved = false;
87         getDelta().recordBundleUpdated((BundleDescriptionImpl) newDescription);
88         if (Constants.getInternalSymbolicName().equals(newDescription.getSymbolicName()))
89             resetSystemExports();
90         if (resolver != null) {
91             boolean pending = existing.getDependents().length > 0;
92             resolver.bundleUpdated(newDescription, existing, pending);
93             if (pending) {
94                 getDelta().recordBundleRemovalPending(existing);
95                 removalPendings.add(existing);
96             } else {
97                 // an existing bundle has been updated with no dependents it can safely be unresolved now
98
synchronized (this) {
99                     try {
100                         resolving = true;
101                         resolverErrors.remove(existing);
102                         resolveBundle(existing, false, null, null, null, null);
103                     } finally {
104                         resolving = false;
105                     }
106                 }
107             }
108         }
109         updateTimeStamp();
110         return true;
111     }
112
113     public BundleDescription removeBundle(long bundleId) {
114         BundleDescription toRemove = getBundle(bundleId);
115         if (toRemove == null || !removeBundle(toRemove))
116             return null;
117         return toRemove;
118     }
119
120     public boolean removeBundle(BundleDescription toRemove) {
121         if (!bundleDescriptions.remove((KeyedElement) toRemove))
122             return false;
123         resolvedBundles.remove((KeyedElement) toRemove);
124         resolved = false;
125         getDelta().recordBundleRemoved((BundleDescriptionImpl) toRemove);
126         ((BundleDescriptionImpl) toRemove).setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, true);
127         if (resolver != null) {
128             boolean pending = toRemove.getDependents().length > 0;
129             resolver.bundleRemoved(toRemove, pending);
130             if (pending) {
131                 getDelta().recordBundleRemovalPending((BundleDescriptionImpl) toRemove);
132                 removalPendings.add(toRemove);
133             } else {
134                 // a bundle has been removed with no dependents it can safely be unresolved now
135
synchronized (this) {
136                     try {
137                         resolving = true;
138                         resolverErrors.remove(toRemove);
139                         resolveBundle(toRemove, false, null, null, null, null);
140                     } finally {
141                         resolving = false;
142                     }
143                 }
144             }
145         }
146         updateTimeStamp();
147         return true;
148     }
149
150     public StateDelta getChanges() {
151         return getDelta();
152     }
153
154     private StateDeltaImpl getDelta() {
155         if (changes == null)
156             changes = new StateDeltaImpl(this);
157         return changes;
158     }
159
160     public BundleDescription[] getBundles(String JavaDoc symbolicName) {
161         if (Constants.OSGI_SYSTEM_BUNDLE.equals(symbolicName))
162             symbolicName = Constants.getInternalSymbolicName();
163         final List bundles = new ArrayList();
164         for (Iterator iter = bundleDescriptions.iterator(); iter.hasNext();) {
165             BundleDescription bundle = (BundleDescription) iter.next();
166             if (symbolicName.equals(bundle.getSymbolicName()))
167                 bundles.add(bundle);
168         }
169         return (BundleDescription[]) bundles.toArray(new BundleDescription[bundles.size()]);
170     }
171
172     public BundleDescription[] getBundles() {
173         return (BundleDescription[]) bundleDescriptions.elements(new BundleDescription[bundleDescriptions.size()]);
174     }
175
176     public BundleDescription getBundle(long id) {
177         BundleDescription result = (BundleDescription) bundleDescriptions.getByKey(new Long JavaDoc(id));
178         if (result != null)
179             return result;
180         // need to look in removal pending bundles;
181
for (Iterator iter = removalPendings.iterator(); iter.hasNext();) {
182             BundleDescription removedBundle = (BundleDescription) iter.next();
183             if (removedBundle.getBundleId() == id) // just return the first matching id
184
return removedBundle;
185         }
186         return null;
187     }
188
189     public BundleDescription getBundle(String JavaDoc name, Version version) {
190         BundleDescription[] allBundles = getBundles(name);
191         if (allBundles.length == 1)
192             return version == null || allBundles[0].getVersion().equals(version) ? allBundles[0] : null;
193
194         if (allBundles.length == 0)
195             return null;
196
197         BundleDescription unresolvedFound = null;
198         BundleDescription resolvedFound = null;
199         for (int i = 0; i < allBundles.length; i++) {
200             BundleDescription current = allBundles[i];
201             BundleDescription base;
202
203             if (current.isResolved())
204                 base = resolvedFound;
205             else
206                 base = unresolvedFound;
207
208             if (version == null || current.getVersion().equals(version)) {
209                 if (base != null && (base.getVersion().compareTo(current.getVersion()) <= 0 || base.getBundleId() > current.getBundleId())) {
210                     if (base == resolvedFound)
211                         resolvedFound = current;
212                     else
213                         unresolvedFound = current;
214                 } else {
215                     if (current.isResolved())
216                         resolvedFound = current;
217                     else
218                         unresolvedFound = current;
219                 }
220
221             }
222         }
223         if (resolvedFound != null)
224             return resolvedFound;
225
226         return unresolvedFound;
227     }
228
229     public long getTimeStamp() {
230         return timeStamp;
231     }
232
233     public boolean isResolved() {
234         return resolved || isEmpty();
235     }
236
237     public void resolveConstraint(VersionConstraint constraint, BaseDescription supplier) {
238         ((VersionConstraintImpl) constraint).setSupplier(supplier);
239     }
240
241     public synchronized void resolveBundle(BundleDescription bundle, boolean status, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) {
242         if (!resolving)
243             throw new IllegalStateException JavaDoc(); // TODO need error message here!
244
BundleDescriptionImpl modifiable = (BundleDescriptionImpl) bundle;
245         // must record the change before setting the resolve state to
246
// accurately record if a change has happened.
247
getDelta().recordBundleResolved(modifiable, status);
248         // force the new resolution data to stay in memory; we will not read this from disk anymore
249
modifiable.setLazyLoaded(false);
250         modifiable.setStateBit(BundleDescriptionImpl.RESOLVED, status);
251         if (status) {
252             resolverErrors.remove(modifiable);
253             resolvedBundles.add(modifiable);
254         } else {
255             // remove the bundle from the resolved pool
256
resolvedBundles.remove(modifiable);
257             modifiable.removeDependencies();
258         }
259         // to support develoment mode we will resolveConstraints even if the resolve status == false
260
// we only do this if the resolved constraints are not null
261
if (selectedExports == null || resolvedRequires == null || resolvedImports == null)
262             unresolveConstraints(modifiable);
263         else
264             resolveConstraints(modifiable, hosts, selectedExports, resolvedRequires, resolvedImports);
265     }
266
267     public synchronized void removeBundleComplete(BundleDescription bundle) {
268         if (!resolving)
269             throw new IllegalStateException JavaDoc(); // TODO need error message here!
270
getDelta().recordBundleRemovalComplete((BundleDescriptionImpl) bundle);
271         removalPendings.remove(bundle);
272     }
273
274     private void resolveConstraints(BundleDescriptionImpl bundle, BundleDescription[] hosts, ExportPackageDescription[] selectedExports, BundleDescription[] resolvedRequires, ExportPackageDescription[] resolvedImports) {
275         HostSpecificationImpl hostSpec = (HostSpecificationImpl) bundle.getHost();
276         if (hostSpec != null) {
277             if (hosts != null) {
278                 hostSpec.setHosts(hosts);
279                 for (int i = 0; i < hosts.length; i++)
280                     ((BundleDescriptionImpl) hosts[i]).addDependency(bundle, true);
281             }
282         }
283
284         bundle.setSelectedExports(selectedExports);
285         bundle.setResolvedRequires(resolvedRequires);
286         bundle.setResolvedImports(resolvedImports);
287
288         bundle.addDependencies(hosts, true);
289         bundle.addDependencies(resolvedRequires, true);
290         bundle.addDependencies(resolvedImports, true);
291         // add dependecies for generics
292
GenericSpecification[] genericRequires = bundle.getGenericRequires();
293         if (genericRequires.length > 0) {
294             ArrayList genericSuppliers = new ArrayList(genericRequires.length);
295             for (int i = 0; i < genericRequires.length; i++) {
296                 GenericDescription[] suppliers = genericRequires[i].getSuppliers();
297                 if (suppliers != null)
298                     for (int j = 0; j < suppliers.length; j++)
299                         genericSuppliers.add(suppliers[j]);
300             }
301             bundle.addDependencies((BaseDescription[]) genericSuppliers.toArray(new BaseDescription[genericSuppliers.size()]), true);
302         }
303     }
304
305     private void unresolveConstraints(BundleDescriptionImpl bundle) {
306         HostSpecificationImpl host = (HostSpecificationImpl) bundle.getHost();
307         if (host != null)
308             host.setHosts(null);
309
310         bundle.setSelectedExports(null);
311         bundle.setResolvedImports(null);
312         bundle.setResolvedRequires(null);
313
314         // remove suppliers for generics
315
GenericSpecification[] genericRequires = bundle.getGenericRequires();
316         if (genericRequires.length > 0)
317             for (int i = 0; i < genericRequires.length; i++)
318                 ((GenericSpecificationImpl) genericRequires[i]).setSupplers(null);
319         bundle.removeDependencies();
320     }
321
322     private synchronized StateDelta resolve(boolean incremental, BundleDescription[] reResolve) {
323         try {
324             resolving = true;
325             if (resolver == null)
326                 throw new IllegalStateException JavaDoc("no resolver set"); //$NON-NLS-1$
327
fullyLoad();
328             long start = 0;
329             if (StateManager.DEBUG_PLATFORM_ADMIN_RESOLVER)
330                 start = System.currentTimeMillis();
331             if (!incremental) {
332                 resolved = false;
333                 reResolve = getBundles();
334                 // need to get any removal pendings before flushing
335
if (removalPendings.size() > 0) {
336                     BundleDescription[] removed = getRemovalPendings();
337                     reResolve = mergeBundles(reResolve, removed);
338                 }
339                 flush(reResolve);
340             }
341             if (resolved && reResolve == null)
342                 return new StateDeltaImpl(this);
343             if (removalPendings.size() > 0) {
344                 BundleDescription[] removed = getRemovalPendings();
345                 reResolve = mergeBundles(reResolve, removed);
346             }
347             // use the Headers class to handle ignoring case while matching keys (bug 180817)
348
Headers[] tmpPlatformProperties = new Headers[platformProperties.length];
349             for (int i = 0; i < platformProperties.length; i++) {
350                 tmpPlatformProperties[i] = new Headers(platformProperties[i].size());
351                 for (Enumeration keys = platformProperties[i].keys(); keys.hasMoreElements();) {
352                     Object JavaDoc key = keys.nextElement();
353                     tmpPlatformProperties[i].put(key, platformProperties[i].get(key));
354                 }
355             }
356             resolver.resolve(reResolve, tmpPlatformProperties);
357             resolved = removalPendings.size() == 0;
358
359             StateDelta savedChanges = changes == null ? new StateDeltaImpl(this) : changes;
360             changes = new StateDeltaImpl(this);
361
362             if (StateManager.DEBUG_PLATFORM_ADMIN_RESOLVER) {
363                 long time = System.currentTimeMillis() - start;
364                 Debug.println("Time spent resolving: " + time); //$NON-NLS-1$
365
cumulativeTime = cumulativeTime + time;
366                 FrameworkDebugOptions.getDefault().setOption("org.eclipse.core.runtime.adaptor/resolver/timing/value", Long.toString(cumulativeTime)); //$NON-NLS-1$
367
}
368             if (savedChanges.getChanges().length > 0)
369                 updateTimeStamp();
370             return savedChanges;
371         } finally {
372             resolving = false;
373         }
374     }
375
376     private BundleDescription[] mergeBundles(BundleDescription[] reResolve, BundleDescription[] removed) {
377         if (reResolve == null)
378             return removed; // just return all the removed bundles
379
if (reResolve.length == 0)
380             return reResolve; // if reResolve length==0 then we want to prevent pending removal
381
// merge in all removal pending bundles that are not already in the list
382
ArrayList result = new ArrayList(reResolve.length + removed.length);
383         for (int i = 0; i < reResolve.length; i++)
384             result.add(reResolve[i]);
385         for (int i = 0; i < removed.length; i++) {
386             boolean found = false;
387             for (int j = 0; j < reResolve.length; j++) {
388                 if (removed[i] == reResolve[j]) {
389                     found = true;
390                     break;
391                 }
392             }
393             if (!found)
394                 result.add(removed[i]);
395         }
396         return (BundleDescription[]) result.toArray(new BundleDescription[result.size()]);
397     }
398
399     private void flush(BundleDescription[] bundles) {
400         resolver.flush();
401         resolved = false;
402         resolverErrors.clear();
403         if (resolvedBundles.isEmpty())
404             return;
405         for (int i = 0; i < bundles.length; i++) {
406             resolveBundle(bundles[i], false, null, null, null, null);
407         }
408         resolvedBundles.clear();
409     }
410
411     public StateDelta resolve() {
412         return resolve(true, null);
413     }
414
415     public StateDelta resolve(boolean incremental) {
416         return resolve(incremental, null);
417     }
418
419     public StateDelta resolve(BundleDescription[] reResolve) {
420         return resolve(true, reResolve);
421     }
422
423     public void setOverrides(Object JavaDoc value) {
424         throw new UnsupportedOperationException JavaDoc();
425     }
426
427     public BundleDescription[] getResolvedBundles() {
428         return (BundleDescription[]) resolvedBundles.elements(new BundleDescription[resolvedBundles.size()]);
429     }
430
431     public boolean isEmpty() {
432         return bundleDescriptions.isEmpty();
433     }
434
435     void setResolved(boolean resolved) {
436         this.resolved = resolved;
437     }
438
439     boolean basicAddBundle(BundleDescription description) {
440         ((BundleDescriptionImpl) description).setContainingState(this);
441         ((BundleDescriptionImpl) description).setStateBit(BundleDescriptionImpl.REMOVAL_PENDING, false);
442         if (bundleDescriptions.add((BundleDescriptionImpl) description)) {
443             if (description.getBundleId() > getHighestBundleId())
444                 highestBundleId = description.getBundleId();
445             return true;
446         }
447         return false;
448     }
449
450     void addResolvedBundle(BundleDescriptionImpl resolvedBundle) {
451         resolvedBundles.add(resolvedBundle);
452     }
453
454     public ExportPackageDescription[] getExportedPackages() {
455         fullyLoad();
456         final List allExportedPackages = new ArrayList();
457         for (Iterator iter = resolvedBundles.iterator(); iter.hasNext();) {
458             BundleDescription bundle = (BundleDescription) iter.next();
459             ExportPackageDescription[] bundlePackages = bundle.getSelectedExports();
460             if (bundlePackages == null)
461                 continue;
462             for (int i = 0; i < bundlePackages.length; i++)
463                 allExportedPackages.add(bundlePackages[i]);
464         }
465         for (Iterator iter = removalPendings.iterator(); iter.hasNext();) {
466             BundleDescription bundle = (BundleDescription) iter.next();
467             ExportPackageDescription[] bundlePackages = bundle.getSelectedExports();
468             if (bundlePackages == null)
469                 continue;
470             for (int i = 0; i < bundlePackages.length; i++)
471                 allExportedPackages.add(bundlePackages[i]);
472         }
473         return (ExportPackageDescription[]) allExportedPackages.toArray(new ExportPackageDescription[allExportedPackages.size()]);
474     }
475
476     BundleDescription[] getFragments(final BundleDescription host) {
477         final List fragments = new ArrayList();
478         for (Iterator iter = bundleDescriptions.iterator(); iter.hasNext();) {
479             BundleDescription bundle = (BundleDescription) iter.next();
480             HostSpecification hostSpec = bundle.getHost();
481
482             if (hostSpec != null) {
483                 BundleDescription[] hosts = hostSpec.getHosts();
484                 if (hosts != null)
485                     for (int i = 0; i < hosts.length; i++)
486                         if (hosts[i] == host) {
487                             fragments.add(bundle);
488                             break;
489                         }
490             }
491         }
492         return (BundleDescription[]) fragments.toArray(new BundleDescription[fragments.size()]);
493     }
494
495     public void setTimeStamp(long newTimeStamp) {
496         timeStamp = newTimeStamp;
497     }
498
499     private void updateTimeStamp() {
500         if (getTimeStamp() == Long.MAX_VALUE)
501             setTimeStamp(0);
502         setTimeStamp(getTimeStamp() + 1);
503     }
504
505     public StateObjectFactory getFactory() {
506         return factory;
507     }
508
509     void setFactory(StateObjectFactory factory) {
510         this.factory = factory;
511     }
512
513     public BundleDescription getBundleByLocation(String JavaDoc location) {
514         for (Iterator i = bundleDescriptions.iterator(); i.hasNext();) {
515             BundleDescription current = (BundleDescription) i.next();
516             if (location.equals(current.getLocation()))
517                 return current;
518         }
519         return null;
520     }
521
522     public Resolver getResolver() {
523         return resolver;
524     }
525
526     public void setResolver(Resolver newResolver) {
527         if (resolver == newResolver)
528             return;
529         if (resolver != null) {
530             Resolver oldResolver = resolver;
531             resolver = null;
532             oldResolver.setState(null);
533         }
534         resolver = newResolver;
535         if (resolver == null)
536             return;
537         resolver.setState(this);
538     }
539
540     public boolean setPlatformProperties(Dictionary platformProperties) {
541         return setPlatformProperties(new Dictionary[] {platformProperties});
542     }
543
544     public boolean setPlatformProperties(Dictionary[] platformProperties) {
545         return setPlatformProperties(platformProperties, true);
546     }
547
548     synchronized boolean setPlatformProperties(Dictionary[] platformProperties, boolean resetSystemExports) {
549         if (platformProperties.length == 0)
550             throw new IllegalArgumentException JavaDoc();
551         // copy the properties for our use internally
552
Dictionary[] newPlatformProperties = new Dictionary[platformProperties.length];
553         for (int i = 0; i < platformProperties.length; i++) {
554             newPlatformProperties[i] = new Hashtable(platformProperties[i].size());
555             synchronized (platformProperties[i]) {
556                 for (Enumeration keys = platformProperties[i].keys(); keys.hasMoreElements();) {
557                     Object JavaDoc key = keys.nextElement();
558                     newPlatformProperties[i].put(key, platformProperties[i].get(key));
559                 }
560             }
561         }
562         boolean result = false;
563         if (this.platformProperties.length != newPlatformProperties.length) {
564             result = true;
565         } else {
566             // we need to see if any of the existing filter prop keys have changed
567
String JavaDoc[] keys = getPlatformPropertyKeys();
568             for (int i = 0; i < newPlatformProperties.length && !result; i++)
569                 result |= changedProps(this.platformProperties[i], newPlatformProperties[i], keys);
570         }
571         // always do a complete replacement of the properties in case new bundles are added that uses new filter props
572
this.platformProperties = newPlatformProperties;
573         if (resetSystemExports && result)
574             resetSystemExports();
575         return result;
576     }
577
578     private void resetSystemExports() {
579         BundleDescription[] systemBundles = getBundles(Constants.getInternalSymbolicName());
580         if (systemBundles.length > 0) {
581             BundleDescriptionImpl systemBundle = (BundleDescriptionImpl) systemBundles[0];
582             ExportPackageDescription[] exports = systemBundle.getExportPackages();
583             ArrayList newExports = new ArrayList(exports.length);
584             for (int i = 0; i < exports.length; i++)
585                 if (((Integer JavaDoc) exports[i].getDirective(ExportPackageDescriptionImpl.EQUINOX_EE)).intValue() < 0)
586                     newExports.add(exports[i]);
587             addSystemExports(newExports);
588             systemBundle.setExportPackages((ExportPackageDescription[]) newExports.toArray(new ExportPackageDescription[newExports.size()]));
589         }
590     }
591
592     private void addSystemExports(ArrayList exports) {
593         for (int i = 0; i < platformProperties.length; i++)
594             try {
595                 ManifestElement[] elements = ManifestElement.parseHeader(Constants.EXPORT_PACKAGE, (String JavaDoc) platformProperties[i].get(Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES));
596                 if (elements == null)
597                     continue;
598                 // we can pass false for strict mode here because we never want to mark the system exports as internal.
599
ExportPackageDescription[] systemExports = StateBuilder.createExportPackages(elements, null, null, null, 2, false);
600                 Integer JavaDoc profInx = new Integer JavaDoc(i);
601                 for (int j = 0; j < systemExports.length; j++) {
602                     ((ExportPackageDescriptionImpl) systemExports[j]).setDirective(ExportPackageDescriptionImpl.EQUINOX_EE, profInx);
603                     exports.add(systemExports[j]);
604                 }
605             } catch (BundleException e) {
606                 // TODO consider throwing this...
607
}
608     }
609
610     public Dictionary[] getPlatformProperties() {
611         return platformProperties;
612     }
613
614     private boolean checkProp(Object JavaDoc origObj, Object JavaDoc newObj) {
615         if ((origObj == null && newObj != null) || (origObj != null && newObj == null))
616             return true;
617         if (origObj == null)
618             return false;
619         if (origObj.getClass() != newObj.getClass())
620             return true;
621         if (origObj instanceof String JavaDoc)
622             return !origObj.equals(newObj);
623         String JavaDoc[] origProps = (String JavaDoc[]) origObj;
624         String JavaDoc[] newProps = (String JavaDoc[]) newObj;
625         if (origProps.length != newProps.length)
626             return true;
627         for (int i = 0; i < origProps.length; i++) {
628             if (!origProps[i].equals(newProps[i]))
629                 return true;
630         }
631         return false;
632     }
633
634     private boolean changedProps(Dictionary origProps, Dictionary newProps, String JavaDoc[] keys) {
635         for (int i = 0; i < keys.length; i++) {
636             Object JavaDoc origProp = origProps.get(keys[i]);
637             Object JavaDoc newProp = newProps.get(keys[i]);
638             if (checkProp(origProp, newProp))
639                 return true;
640         }
641         return false;
642     }
643
644     public BundleDescription[] getRemovalPendings() {
645         return (BundleDescription[]) removalPendings.toArray(new BundleDescription[removalPendings.size()]);
646     }
647
648     public synchronized ExportPackageDescription linkDynamicImport(BundleDescription importingBundle, String JavaDoc requestedPackage) {
649         if (resolver == null)
650             throw new IllegalStateException JavaDoc("no resolver set"); //$NON-NLS-1$
651
BundleDescriptionImpl importer = (BundleDescriptionImpl) importingBundle;
652         if (importer.getDynamicStamp(requestedPackage) == getTimeStamp())
653             return null;
654         try {
655             resolving = true;
656             fullyLoad();
657             // ask the resolver to resolve our dynamic import
658
ExportPackageDescriptionImpl result = (ExportPackageDescriptionImpl) resolver.resolveDynamicImport(importingBundle, requestedPackage);
659             if (result == null)
660                 importer.setDynamicStamp(requestedPackage, new Long JavaDoc(getTimeStamp()));
661             else {
662                 importer.setDynamicStamp(requestedPackage, null); // remove any cached timestamp
663
// need to add the result to the list of resolved imports
664
importer.addDynamicResolvedImport(result);
665             }
666             setDynamicCacheChanged(true);
667             return result;
668         } finally {
669             resolving = false;
670         }
671     }
672
673     void setReader(StateReader reader) {
674         this.reader = reader;
675     }
676
677     StateReader getReader() {
678         return reader;
679     }
680
681     public void fullyLoad() {
682         if (reader == null)
683             return;
684         synchronized (reader) {
685             if (fullyLoaded == true)
686                 return;
687             if (reader.isLazyLoaded())
688                 reader.fullyLoad();
689             fullyLoaded = true;
690         }
691     }
692
693     public void unloadLazyData(long expireTime) {
694         // make sure no other thread is trying to unload or load
695
synchronized (reader) {
696             if (reader.getAccessedFlag()) {
697                 reader.setAccessedFlag(false); // reset accessed flag
698
return;
699             }
700             fullyLoaded = false;
701             BundleDescription[] bundles = getBundles();
702             for (int i = 0; i < bundles.length; i++)
703                 ((BundleDescriptionImpl) bundles[i]).unload();
704         }
705     }
706
707     public ExportPackageDescription[] getSystemPackages() {
708         ArrayList result = new ArrayList();
709         BundleDescription[] systemBundles = getBundles(Constants.getInternalSymbolicName());
710         if (systemBundles.length > 0) {
711             BundleDescriptionImpl systemBundle = (BundleDescriptionImpl) systemBundles[0];
712             ExportPackageDescription[] exports = systemBundle.getExportPackages();
713             for (int i = 0; i < exports.length; i++)
714                 if (((Integer JavaDoc) exports[i].getDirective(ExportPackageDescriptionImpl.EQUINOX_EE)).intValue() >= 0)
715                     result.add(exports[i]);
716         }
717         return (ExportPackageDescription[]) result.toArray(new ExportPackageDescription[result.size()]);
718     }
719
720     boolean inStrictMode() {
721         return Constants.STRICT_MODE.equals(getPlatformProperties()[0].get(Constants.OSGI_RESOLVER_MODE));
722     }
723
724     public synchronized ResolverError[] getResolverErrors(BundleDescription bundle) {
725         if (bundle.isResolved())
726             return new ResolverError[0];
727         ArrayList result = (ArrayList) resolverErrors.get(bundle);
728         return result == null ? new ResolverError[0] : (ResolverError[]) result.toArray(new ResolverError[result.size()]);
729     }
730
731     public synchronized void addResolverError(BundleDescription bundle, int type, String JavaDoc data, VersionConstraint unsatisfied) {
732         if (!resolving)
733             throw new IllegalStateException JavaDoc(); // TODO need error message here!
734
ArrayList errors = (ArrayList) resolverErrors.get(bundle);
735         if (errors == null) {
736             errors = new ArrayList(1);
737             resolverErrors.put(bundle, errors);
738         }
739         errors.add(new ResolverErrorImpl((BundleDescriptionImpl) bundle, type, data, unsatisfied));
740     }
741
742     public synchronized void removeResolverErrors(BundleDescription bundle) {
743         if (!resolving)
744             throw new IllegalStateException JavaDoc(); // TODO need error message here!
745
resolverErrors.remove(bundle);
746     }
747
748     public boolean dynamicCacheChanged() {
749         return dynamicCacheChanged;
750     }
751
752     void setDynamicCacheChanged(boolean dynamicCacheChanged) {
753         this.dynamicCacheChanged = dynamicCacheChanged;
754     }
755
756     public StateHelper getStateHelper() {
757         return StateHelperImpl.getInstance();
758     }
759
760     void addPlatformPropertyKeys(String JavaDoc[] keys) {
761         synchronized (platformPropertyKeys) {
762             for (int i = 0; i < keys.length; i++)
763                 if (!platformPropertyKeys.contains(keys[i]))
764                     platformPropertyKeys.add(keys[i]);
765         }
766     }
767
768     String JavaDoc[] getPlatformPropertyKeys() {
769         synchronized (platformPropertyKeys) {
770             return (String JavaDoc[]) platformPropertyKeys.toArray(new String JavaDoc[platformPropertyKeys.size()]);
771         }
772     }
773
774     public long getHighestBundleId() {
775         return highestBundleId;
776     }
777
778 }
779
Popular Tags