1 11 package org.eclipse.osgi.framework.internal.core; 12 13 import java.io.IOException ; 14 import java.io.InputStream ; 15 import java.net.URL ; 16 import java.net.URLConnection ; 17 import java.security.*; 18 import java.util.*; 19 import org.eclipse.osgi.framework.adaptor.*; 20 import org.eclipse.osgi.framework.debug.Debug; 21 import org.eclipse.osgi.framework.util.KeyedElement; 22 import org.eclipse.osgi.service.resolver.*; 23 import org.eclipse.osgi.util.NLS; 24 import org.osgi.framework.*; 25 26 31 public abstract class AbstractBundle implements Bundle, Comparable , KeyedElement { 32 33 protected Framework framework; 34 35 protected volatile int state; 36 37 protected volatile Thread stateChanging; 38 39 protected BundleData bundledata; 40 41 protected Object statechangeLock = new Object (); 42 43 protected BundleProtectionDomain domain; 44 45 protected ManifestLocalization manifestLocalization = null; 46 47 56 protected static AbstractBundle createBundle(BundleData bundledata, Framework framework) throws BundleException { 57 if ((bundledata.getType() & BundleData.TYPE_FRAGMENT) > 0) 58 return new BundleFragment(bundledata, framework); 59 return new BundleHost(bundledata, framework); 60 } 61 62 71 protected AbstractBundle(BundleData bundledata, Framework framework) { 72 state = INSTALLED; 73 stateChanging = null; 74 this.bundledata = bundledata; 75 this.framework = framework; 76 bundledata.setBundle(this); 77 } 78 79 82 protected abstract void load(); 83 84 93 protected abstract boolean reload(AbstractBundle newBundle); 94 95 101 protected abstract void refresh(); 102 103 110 protected abstract boolean unload(); 111 112 116 protected void close() { 117 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 118 if ((state & (INSTALLED)) == 0) { 119 Debug.println("Bundle.close called when state != INSTALLED: " + this); Debug.printStackTrace(new Exception ("Stack trace")); } 122 } 123 state = UNINSTALLED; 124 } 125 126 129 protected BundleActivator loadBundleActivator() throws BundleException { 130 131 String activatorClassName = bundledata.getActivator(); 132 if (activatorClassName != null) { 133 try { 134 Class activatorClass = loadClass(activatorClassName, false); 135 136 return (BundleActivator) (activatorClass.newInstance()); 137 } catch (Throwable t) { 138 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 139 Debug.printStackTrace(t); 140 } 141 throw new BundleException(NLS.bind(Msg.BUNDLE_INVALID_ACTIVATOR_EXCEPTION, activatorClassName, bundledata.getSymbolicName()), t); 142 } 143 } 144 return (null); 145 } 146 147 158 protected abstract Class loadClass(String name, boolean checkPermission) throws ClassNotFoundException ; 159 160 167 public int getState() { 168 return (state); 169 } 170 171 175 protected boolean isActive() { 176 return ((state & (ACTIVE | STARTING)) != 0); 177 } 178 179 183 protected boolean isResolved() { 184 return (state & (INSTALLED | UNINSTALLED)) == 0; 185 } 186 187 251 public void start() throws BundleException { 252 start(0); 253 } 254 255 public void start(int options) throws BundleException { 256 framework.checkAdminPermission(this, AdminPermission.EXECUTE); 257 checkValid(); 258 beginStateChange(); 259 try { 260 startWorker(options); 261 } finally { 262 completeStateChange(); 263 } 264 } 265 266 271 protected abstract void startWorker(int options) throws BundleException; 272 273 286 protected boolean readyToResume() { 287 return false; 288 } 289 290 343 protected void resume() throws BundleException { 344 if (state == UNINSTALLED) { 345 return; 346 } 347 beginStateChange(); 348 try { 349 if (readyToResume()) 350 startWorker(START_TRANSIENT); 351 } finally { 352 completeStateChange(); 353 } 354 } 355 356 416 public void stop() throws BundleException { 417 stop(0); 418 } 419 420 public void stop(int options) throws BundleException { 421 framework.checkAdminPermission(this, AdminPermission.EXECUTE); 422 checkValid(); 423 beginStateChange(); 424 try { 425 stopWorker(options); 426 } finally { 427 completeStateChange(); 428 } 429 } 430 431 436 protected abstract void stopWorker(int options) throws BundleException; 437 438 446 protected void setStatus(final int mask, final boolean state) { 447 try { 448 AccessController.doPrivileged(new PrivilegedExceptionAction() { 449 public Object run() throws BundleException, IOException { 450 int status = bundledata.getStatus(); 451 boolean test = ((status & mask) != 0); 452 if (test != state) { 453 bundledata.setStatus(state ? (status | mask) : (status & ~mask)); 454 bundledata.save(); 455 } 456 return null; 457 } 458 }); 459 } catch (PrivilegedActionException pae) { 460 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, pae.getException()); 461 } 462 } 463 464 520 protected void suspend(boolean lock) throws BundleException { 521 if (state == UNINSTALLED) { 522 return; 523 } 524 beginStateChange(); 525 try { 526 stopWorker(STOP_TRANSIENT); 527 } finally { 528 if (!lock) { 529 completeStateChange(); 530 } 531 } 532 } 533 534 595 public void update() throws BundleException { 596 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 597 Debug.println("update location " + bundledata.getLocation()); } 599 framework.checkAdminPermission(this, AdminPermission.LIFECYCLE); 600 if ((bundledata.getType() & (BundleData.TYPE_BOOTCLASSPATH_EXTENSION | BundleData.TYPE_FRAMEWORK_EXTENSION)) != 0) 601 framework.checkAdminPermission(this, AdminPermission.EXTENSIONLIFECYCLE); 603 checkValid(); 604 beginStateChange(); 605 try { 606 final AccessControlContext callerContext = AccessController.getContext(); 607 updateWorker(new PrivilegedExceptionAction() { 609 public Object run() throws BundleException { 610 611 String updateLocation = bundledata.getLocation(); 612 if (bundledata.getManifest().get(Constants.BUNDLE_UPDATELOCATION) != null) { 613 updateLocation = (String ) bundledata.getManifest().get(Constants.BUNDLE_UPDATELOCATION); 614 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 615 Debug.println(" from location: " + updateLocation); } 617 } 618 619 URLConnection source = framework.adaptor.mapLocationToURLConnection(updateLocation); 620 621 updateWorkerPrivileged(source, callerContext); 622 return null; 623 } 624 }); 625 } finally { 626 completeStateChange(); 627 } 628 } 629 630 642 public void update(final InputStream in) throws BundleException { 643 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 644 Debug.println("update location " + bundledata.getLocation()); Debug.println(" from: " + in); } 647 framework.checkAdminPermission(this, AdminPermission.LIFECYCLE); 648 if ((bundledata.getType() & (BundleData.TYPE_BOOTCLASSPATH_EXTENSION | BundleData.TYPE_FRAMEWORK_EXTENSION)) != 0) 649 framework.checkAdminPermission(this, AdminPermission.EXTENSIONLIFECYCLE); 651 checkValid(); 652 beginStateChange(); 653 try { 654 final AccessControlContext callerContext = AccessController.getContext(); 655 updateWorker(new PrivilegedExceptionAction() { 657 public Object run() throws BundleException { 658 659 URLConnection source = new BundleSource(in); 660 661 updateWorkerPrivileged(source, callerContext); 662 return null; 663 } 664 }); 665 } finally { 666 completeStateChange(); 667 } 668 } 669 670 673 protected void updateWorker(PrivilegedExceptionAction action) throws BundleException { 674 boolean bundleActive = false; 675 if (!isFragment()) 676 bundleActive = (state & (ACTIVE | STARTING)) != 0; 677 if (bundleActive) { 678 try { 679 stopWorker(STOP_TRANSIENT); 680 } catch (BundleException e) { 681 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, e); 682 if ((state & (ACTIVE | STARTING)) != 0) { 683 throw e; 684 } 685 } 686 } 687 try { 688 AccessController.doPrivileged(action); 689 framework.publishBundleEvent(BundleEvent.UPDATED, this); 690 } catch (PrivilegedActionException pae) { 691 if (pae.getException() instanceof RuntimeException ) 692 throw (RuntimeException ) pae.getException(); 693 throw (BundleException) pae.getException(); 694 } finally { 695 if (bundleActive) { 696 try { 697 startWorker(START_TRANSIENT); 698 } catch (BundleException e) { 699 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, e); 700 } 701 } 702 } 703 } 704 705 708 protected void updateWorkerPrivileged(URLConnection source, AccessControlContext callerContext) throws BundleException { 709 AbstractBundle oldBundle = AbstractBundle.createBundle(bundledata, framework); 710 boolean reloaded = false; 711 BundleOperation storage = framework.adaptor.updateBundle(this.bundledata, source); 712 BundleRepository bundles = framework.getBundles(); 713 try { 714 BundleData newBundleData = storage.begin(); 715 final AbstractBundle newBundle = framework.createAndVerifyBundle(newBundleData); 717 String [] nativepaths = framework.selectNativeCode(newBundle); 718 if (nativepaths != null) { 719 newBundleData.installNativeCode(nativepaths); 720 } 721 boolean exporting; 722 int st = getState(); 723 synchronized (bundles) { 724 exporting = reload(newBundle); 725 manifestLocalization = null; 726 } 727 reloaded = true; 729 if (System.getSecurityManager() != null) { 730 final boolean extension = (bundledata.getType() & (BundleData.TYPE_BOOTCLASSPATH_EXTENSION | BundleData.TYPE_FRAMEWORK_EXTENSION)) != 0; 731 if (extension && !hasPermission(new AllPermission())) 733 throw new BundleException(Msg.BUNDLE_EXTENSION_PERMISSION, new SecurityException (Msg.BUNDLE_EXTENSION_PERMISSION)); 734 try { 735 AccessController.doPrivileged(new PrivilegedExceptionAction() { 736 public Object run() throws Exception { 737 framework.checkAdminPermission(newBundle, AdminPermission.LIFECYCLE); 738 if (extension) framework.checkAdminPermission(newBundle, AdminPermission.EXTENSIONLIFECYCLE); 740 return null; 741 } 742 }, callerContext); 743 } catch (PrivilegedActionException e) { 744 throw e.getException(); 745 } 746 } 747 if (st == RESOLVED) 749 framework.publishBundleEvent(BundleEvent.UNRESOLVED, this); 750 storage.commit(exporting); 751 } catch (Throwable t) { 752 try { 753 storage.undo(); 754 if (reloaded) { 758 synchronized (bundles) { 759 reload(oldBundle); 760 } 761 } 762 } catch (BundleException ee) { 763 764 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, ee); 765 } 766 if (t instanceof SecurityException ) 767 throw (SecurityException ) t; 768 if (t instanceof BundleException) 769 throw (BundleException) t; 770 throw new BundleException(t.getMessage(), t); 771 } 772 } 773 774 822 public void uninstall() throws BundleException { 823 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 824 Debug.println("uninstall location: " + bundledata.getLocation()); } 826 framework.checkAdminPermission(this, AdminPermission.LIFECYCLE); 827 if ((bundledata.getType() & (BundleData.TYPE_BOOTCLASSPATH_EXTENSION | BundleData.TYPE_FRAMEWORK_EXTENSION)) != 0) 828 framework.checkAdminPermission(this, AdminPermission.EXTENSIONLIFECYCLE); 830 checkValid(); 831 beginStateChange(); 832 try { 833 uninstallWorker(new PrivilegedExceptionAction() { 834 public Object run() throws BundleException { 835 uninstallWorkerPrivileged(); 836 return null; 837 } 838 }); 839 } finally { 840 completeStateChange(); 841 } 842 } 843 844 847 protected void uninstallWorker(PrivilegedExceptionAction action) throws BundleException { 848 boolean bundleActive = false; 849 if (!isFragment()) 850 bundleActive = (state & (ACTIVE | STARTING)) != 0; 851 if (bundleActive) { 852 try { 853 stopWorker(STOP_TRANSIENT); 854 } catch (BundleException e) { 855 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, e); 856 } 857 } 858 try { 859 AccessController.doPrivileged(action); 860 } catch (PrivilegedActionException pae) { 861 if (bundleActive) { 862 try { 863 startWorker(START_TRANSIENT); 864 } catch (BundleException e) { 865 869 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, e); 870 } 871 } 872 throw (BundleException) pae.getException(); 873 } 874 framework.publishBundleEvent(BundleEvent.UNINSTALLED, this); 875 } 876 877 880 protected void uninstallWorkerPrivileged() throws BundleException { 881 if (Debug.DEBUG) { 882 BundleWatcher bundleStats = framework.adaptor.getBundleWatcher(); 883 if (bundleStats != null) 884 bundleStats.watchBundle(this, BundleWatcher.START_UNINSTALLING); 885 } 886 boolean unloaded = false; 887 getHeaders(); 889 BundleOperation storage = framework.adaptor.uninstallBundle(this.bundledata); 890 BundleRepository bundles = framework.getBundles(); 891 try { 892 storage.begin(); 893 boolean exporting; 894 int st = getState(); 895 synchronized (bundles) { 896 bundles.remove(this); 897 exporting = unload(); 898 } 899 if (st == RESOLVED) 901 framework.publishBundleEvent(BundleEvent.UNRESOLVED, this); 902 unloaded = true; 903 storage.commit(exporting); 904 close(); 905 } catch (BundleException e) { 906 try { 907 storage.undo(); 908 if (unloaded) { 909 synchronized (bundles) { 910 load(); 911 bundles.add(this); 912 } 913 } 914 } catch (BundleException ee) { 915 919 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, ee); 920 } 921 throw e; 922 } finally { 923 if (Debug.DEBUG) { 924 BundleWatcher bundleStats = framework.adaptor.getBundleWatcher(); 925 if (bundleStats != null) 926 bundleStats.watchBundle(this, BundleWatcher.END_UNINSTALLING); 927 } 928 } 929 } 930 931 965 public Dictionary getHeaders() { 966 return getHeaders(null); 967 } 968 969 1007 public Dictionary getHeaders(String localeString) { 1008 framework.checkAdminPermission(this, AdminPermission.METADATA); 1009 try { 1010 initializeManifestLocalization(); 1011 } catch (BundleException e) { 1012 framework.publishFrameworkEvent(FrameworkEvent.ERROR, this, e); 1013 return new Hashtable(); 1015 } 1016 if (localeString == null) 1017 localeString = Locale.getDefault().toString(); 1018 return manifestLocalization.getHeaders(localeString); 1019 } 1020 1021 1042 public long getBundleId() { 1043 return (bundledata.getBundleID()); 1044 } 1045 1046 1064 public String getLocation() { 1065 framework.checkAdminPermission(this, AdminPermission.METADATA); 1066 return (bundledata.getLocation()); 1067 } 1068 1069 1087 public boolean hasPermission(Object permission) { 1088 checkValid(); 1089 if (domain != null) { 1090 if (permission instanceof Permission) { 1091 SecurityManager sm = System.getSecurityManager(); 1092 if (sm instanceof FrameworkSecurityManager) { 1093 1098 AccessControlContext acc = new AccessControlContext(new ProtectionDomain[] {domain}); 1099 try { 1100 sm.checkPermission((Permission) permission, acc); 1101 return true; 1102 } catch (Exception e) { 1103 return false; 1104 } 1105 } 1106 return domain.implies((Permission) permission); 1107 } 1108 return false; 1109 } 1110 return true; 1111 } 1112 1113 1132 protected void beginStateChange() throws BundleException { 1133 synchronized (statechangeLock) { 1134 boolean doubleFault = false; 1135 while (true) { 1136 if (stateChanging == null) { 1137 stateChanging = Thread.currentThread(); 1138 return; 1139 } 1140 if (doubleFault || (stateChanging == Thread.currentThread())) { 1141 throw new BundleException(NLS.bind(Msg.BUNDLE_STATE_CHANGE_EXCEPTION, getBundleData().getLocation(), stateChanging.getName()), new BundleStatusException(null, StatusException.CODE_WARNING, stateChanging)); 1142 } 1143 try { 1144 long start = 0; 1145 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1146 Debug.println(" Waiting for state to change in bundle " + this); start = System.currentTimeMillis(); 1148 } 1149 statechangeLock.wait(5000); 1153 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1154 long end = System.currentTimeMillis(); 1155 if (end - start > 0) 1156 System.out.println("Waiting... : " + getSymbolicName() + ' ' + (end - start)); } 1158 } catch (InterruptedException e) { 1159 } 1161 doubleFault = true; 1162 } 1163 } 1164 } 1165 1166 1170 protected void completeStateChange() { 1171 synchronized (statechangeLock) { 1172 if (stateChanging != null) { 1173 stateChanging = null; 1174 statechangeLock.notify(); 1178 } 1179 } 1180 } 1181 1182 1187 public String toString() { 1188 return (bundledata.getLocation() + " [" + getBundleId() + "]"); } 1190 1191 1205 public int compareTo(Object obj) { 1206 int slcomp = getStartLevel() - ((AbstractBundle) obj).getStartLevel(); 1207 if (slcomp != 0) { 1208 return slcomp; 1209 } 1210 long idcomp = getBundleId() - ((AbstractBundle) obj).getBundleId(); 1211 return (idcomp < 0L) ? -1 : ((idcomp > 0L) ? 1 : 0); 1212 } 1213 1214 1221 protected void checkValid() { 1222 if (state == UNINSTALLED) { 1223 throw new IllegalStateException (NLS.bind(Msg.BUNDLE_UNINSTALLED_EXCEPTION, getBundleData().getLocation())); 1224 } 1225 } 1226 1227 1232 protected BundleProtectionDomain getProtectionDomain() { 1233 return domain; 1234 } 1235 1236 1239 protected void unresolvePermissions() { 1240 if (domain != null) { 1241 BundlePermissionCollection collection = (BundlePermissionCollection) domain.getPermissions(); 1242 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1243 Debug.println("Unresolving permissions in bundle " + this); } 1245 collection.unresolvePermissions(); 1246 } 1247 } 1248 1249 protected Bundle[] getFragments() { 1250 checkValid(); 1251 return null; 1252 } 1253 1254 protected boolean isFragment() { 1255 return false; 1256 } 1257 1258 protected BundleLoaderProxy[] getHosts() { 1259 checkValid(); 1260 return null; 1261 } 1262 1263 1268 public Class loadClass(String classname) throws ClassNotFoundException { 1269 return loadClass(classname, true); 1270 } 1271 1272 1277 public Enumeration getEntryPaths(final String path) { 1278 try { 1279 framework.checkAdminPermission(this, AdminPermission.RESOURCE); 1280 } catch (SecurityException e) { 1281 return null; 1282 } 1283 checkValid(); 1284 return (Enumeration) AccessController.doPrivileged(new PrivilegedAction() { 1286 public Object run() { 1287 return bundledata.getEntryPaths(path); 1288 } 1289 }); 1290 } 1291 1292 1297 public URL getEntry(String fileName) { 1298 try { 1299 framework.checkAdminPermission(this, AdminPermission.RESOURCE); 1300 } catch (SecurityException e) { 1301 return null; 1302 } 1303 checkValid(); 1304 if (System.getSecurityManager() == null) 1305 return bundledata.getEntry(fileName); 1306 final String ffileName = fileName; 1307 return (URL ) AccessController.doPrivileged(new PrivilegedAction() { 1309 public Object run() { 1310 return bundledata.getEntry(ffileName); 1311 } 1312 }); 1313 } 1314 1315 public String getSymbolicName() { 1316 return bundledata.getSymbolicName(); 1317 } 1318 1319 public long getLastModified() { 1320 return bundledata.getLastModified(); 1321 } 1322 1323 public BundleData getBundleData() { 1324 return bundledata; 1325 } 1326 1327 public Version getVersion() { 1328 return bundledata.getVersion(); 1329 } 1330 1331 protected BundleDescription getBundleDescription() { 1332 return framework.adaptor.getState().getBundle(getBundleId()); 1333 } 1334 1335 protected int getStartLevel() { 1336 return bundledata.getStartLevel(); 1337 } 1338 1339 protected abstract BundleLoader getBundleLoader(); 1340 1341 1344 protected void resolve() { 1345 if (Debug.DEBUG && Debug.DEBUG_GENERAL) { 1346 if ((state & (INSTALLED)) == 0) { 1347 Debug.println("Bundle.resolve called when state != INSTALLED: " + this); Debug.printStackTrace(new Exception ("Stack trace")); } 1350 } 1351 if (state == INSTALLED) { 1352 state = RESOLVED; 1353 } 1356 } 1357 1358 public BundleContext getBundleContext() { 1359 framework.checkAdminPermission(this, AdminPermission.CONTEXT); 1360 return getContext(); 1361 } 1362 1363 1368 abstract protected BundleContextImpl getContext(); 1369 1370 public String getResolutionFailureMessage() { 1371 BundleDescription bundleDescription = getBundleDescription(); 1372 if (bundleDescription == null) 1373 return Msg.BUNDLE_UNRESOLVED_EXCEPTION; 1374 if (bundleDescription.isResolved()) 1376 throw new IllegalStateException (Msg.BUNDLE_UNRESOLVED_STATE_CONFLICT); 1377 return NLS.bind(Msg.BUNDLE_UNRESOLVED_UNSATISFIED_CONSTRAINT_EXCEPTION, getResolverError(bundleDescription)); 1378 } 1379 1380 private String getResolverError(BundleDescription bundleDesc) { 1381 ResolverError[] errors = framework.adaptor.getState().getResolverErrors(bundleDesc); 1382 if (errors == null || errors.length == 0) 1383 return Msg.BUNDLE_UNRESOLVED_EXCEPTION; 1384 StringBuffer message = new StringBuffer (); 1385 for (int i = 0; i < errors.length; i++) { 1386 message.append(errors[i].toString()); 1387 if (i < errors.length - 1) 1388 message.append(", "); } 1390 return message.toString(); 1391 } 1392 1393 public int getKeyHashCode() { 1394 return (int) getBundleId(); 1395 } 1396 1397 public boolean compare(KeyedElement other) { 1398 return getBundleId() == ((AbstractBundle) other).getBundleId(); 1399 } 1400 1401 public Object getKey() { 1402 return new Long (getBundleId()); 1403 } 1404 1405 1410 public ResourceBundle getResourceBundle(String localeString) { 1411 try { 1412 initializeManifestLocalization(); 1413 } catch (BundleException ex) { 1414 return (null); 1415 } 1416 if (localeString == null) { 1417 localeString = Locale.getDefault().toString(); 1418 } 1419 return manifestLocalization.getResourceBundle(localeString); 1420 } 1421 1422 private void initializeManifestLocalization() throws BundleException { 1423 if (manifestLocalization == null) { 1424 Dictionary rawHeaders; 1425 rawHeaders = bundledata.getManifest(); 1426 manifestLocalization = new ManifestLocalization(this, rawHeaders); 1427 } 1428 } 1429 1430 public boolean testStateChanging(Object thread) { 1431 return stateChanging == thread; 1432 } 1433 1434 public Thread getStateChanging() { 1435 return stateChanging; 1436 } 1437 1438 public Enumeration findEntries(String path, String filePattern, boolean recurse) { 1439 try { 1440 framework.checkAdminPermission(this, AdminPermission.RESOURCE); 1441 } catch (SecurityException e) { 1442 return null; 1443 } 1444 checkValid(); 1445 if (!isResolved()) 1447 framework.packageAdmin.resolveBundles(new Bundle[] {this}); 1448 1449 List pathList = new ArrayList(); 1451 Filter patternFilter = null; 1452 Hashtable patternProps = null; 1453 if (filePattern != null) 1454 try { 1455 patternFilter = new FilterImpl("(filename=" + filePattern + ")"); patternProps = new Hashtable(2); 1459 } catch (InvalidSyntaxException e) { 1460 } 1462 findLocalEntryPaths(path, patternFilter, patternProps, recurse, pathList); 1464 final Bundle[] fragments = getFragments(); 1466 final int numFragments = fragments == null ? -1 : fragments.length; 1467 for (int i = 0; i < numFragments; i++) 1468 ((AbstractBundle) fragments[i]).findLocalEntryPaths(path, patternFilter, patternProps, recurse, pathList); 1469 if (pathList.size() == 0) 1471 return null; 1472 final String [] pathArray = (String []) pathList.toArray(new String [pathList.size()]); 1474 return new Enumeration() { 1475 int curIndex = 0; 1476 int curFragment = -1; 1477 URL nextElement = null; 1478 1479 public boolean hasMoreElements() { 1480 if (nextElement != null) 1481 return true; 1482 getNextElement(); 1483 return nextElement != null; 1484 } 1485 1486 public Object nextElement() { 1487 if (!hasMoreElements()) 1488 throw new NoSuchElementException(); 1489 URL result; 1490 result = nextElement; 1491 getNextElement(); 1493 return result; 1494 } 1495 1496 private void getNextElement() { 1497 nextElement = null; 1498 if (curIndex >= pathArray.length) 1499 return; 1501 String curPath = pathArray[curIndex]; 1502 if (curFragment == -1) { 1503 nextElement = getEntry(curPath); 1505 curFragment++; 1506 } 1507 while (nextElement == null && curFragment < numFragments) 1509 nextElement = fragments[curFragment++].getEntry(curPath); 1510 if (numFragments == -1 || curFragment >= numFragments) { 1512 curIndex++; 1513 curFragment = -1; 1514 } 1515 if (nextElement == null) 1517 getNextElement(); 1518 } 1519 1520 }; 1521 } 1522 1523 protected void findLocalEntryPaths(String path, Filter patternFilter, Hashtable patternProps, boolean recurse, List pathList) { 1524 Enumeration entryPaths = bundledata.getEntryPaths(path); 1525 if (entryPaths == null) 1526 return; 1527 while (entryPaths.hasMoreElements()) { 1528 String entry = (String ) entryPaths.nextElement(); 1529 int lastSlash = entry.lastIndexOf('/'); 1530 if (patternProps != null) { 1531 int secondToLastSlash = entry.lastIndexOf('/', lastSlash - 1); 1532 int fileStart; 1533 int fileEnd = entry.length(); 1534 if (lastSlash < 0) 1535 fileStart = 0; 1536 else if (lastSlash != entry.length() - 1) 1537 fileStart = lastSlash + 1; 1538 else { 1539 fileEnd = lastSlash; if (secondToLastSlash < 0) 1541 fileStart = 0; 1542 else 1543 fileStart = secondToLastSlash + 1; 1544 } 1545 String fileName = entry.substring(fileStart, fileEnd); 1546 patternProps.put("filename", fileName); } 1549 if (!pathList.contains(entry) && (patternFilter == null || patternFilter.matchCase(patternProps))) 1551 pathList.add(entry); 1552 if (recurse && !entry.equals(path) && entry.length() > 0 && lastSlash == (entry.length() - 1)) 1554 findLocalEntryPaths(entry, patternFilter, patternProps, recurse, pathList); 1555 } 1556 return; 1557 } 1558 1559 class BundleStatusException extends Throwable implements StatusException { 1560 private static final long serialVersionUID = 7201911791818929100L; 1561 private int code; 1562 private Object status; 1563 BundleStatusException(String message, int code, Object status) { 1564 super(message); 1565 this.code = code; 1566 this.status = status; 1567 } 1568 public Object getStatus() { 1569 return status; 1570 } 1571 public int getStatusCode() { 1572 return code; 1573 } 1574 1575 } 1576} 1577 | Popular Tags |