00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 package org.knopflerfish.framework.bundlestorage.file;
00036
00037 import org.knopflerfish.framework.*;
00038 import java.io.*;
00039 import java.util.*;
00040
00048 public class BundleStorageImpl implements BundleStorage {
00049
00053 private FileTree bundlesDir;
00054
00058 private long nextFreeId = 1;
00059
00063 private ArrayList archives = new ArrayList();
00064
00070 public BundleStorageImpl() {
00071
00072 bundlesDir = Util.getFileStorage("bs");
00073 if (bundlesDir == null) {
00074 throw new RuntimeException("No bundle storage area available!");
00075 }
00076
00077 String [] list = bundlesDir.list();
00078 for (int i = 0; list != null & i < list.length; i++) {
00079 long id;
00080 try {
00081 id = Long.parseLong(list[i]);
00082 } catch (NumberFormatException e) {
00083 continue;
00084 }
00085 if (id == 0) {
00086 System.err.println("Saved bundle with illegal id 0 is ignored.");
00087 }
00088 int pos = find(id);
00089 if (pos < archives.size() && ((BundleArchive)archives.get(pos)).getBundleId() == id) {
00090 System.err.println("There are two bundle directories with id: " + id);
00091 break;
00092 }
00093 FileTree dir = new FileTree(bundlesDir, list[i]);
00094 if (dir.isDirectory()) {
00095 try {
00096 boolean bUninstalled = BundleArchiveImpl.isUninstalled(dir);
00097 if(bUninstalled) {
00098
00099 dir.delete();
00100 } else {
00101 BundleArchive ba = new BundleArchiveImpl(this, dir, id);
00102 archives.add(pos, ba);
00103 }
00104 if (id >= nextFreeId) {
00105 nextFreeId = id + 1;
00106 }
00107 } catch (Exception e) {
00108 dir.delete();
00109 System.err.println("Removed corrupt bundle dir (" + e.getMessage() + "): " + dir);
00110 }
00111 }
00112 }
00113 }
00114
00122 public BundleArchive insertBundleJar(String location, InputStream is)
00123 throws Exception
00124 {
00125 long id = nextFreeId++;
00126 FileTree dir = new FileTree(bundlesDir, String.valueOf(id));
00127 if (dir.exists()) {
00128
00129 dir.delete();
00130 }
00131 dir.mkdir();
00132 try {
00133 BundleArchive ba = new BundleArchiveImpl(this, dir, is, location, id);
00134 archives.add(ba);
00135 return ba;
00136 } catch (Exception e) {
00137 dir.delete();
00138 throw e;
00139 }
00140 }
00141
00142
00152 public BundleArchive updateBundleArchive(BundleArchive old, InputStream is)
00153 throws Exception
00154 {
00155 return new BundleArchiveImpl((BundleArchiveImpl)old, is);
00156 }
00157
00158
00167 public void replaceBundleArchive(BundleArchive oldBA, BundleArchive newBA)
00168 throws Exception
00169 {
00170 int pos;
00171 long id = oldBA.getBundleId();
00172 synchronized (archives) {
00173 pos = find(id);
00174 if (pos >= archives.size() || archives.get(pos) != oldBA) {
00175 throw new Exception("replaceBundleJar: Old bundle archive not found, pos=" + pos);
00176 }
00177 archives.set(pos, newBA);
00178 }
00179 }
00180
00181
00187 public BundleArchive [] getAllBundleArchives() {
00188 synchronized (archives) {
00189 return (BundleArchive [])archives.toArray(new BundleArchive[archives.size()]);
00190 }
00191 }
00192
00199 public List getStartOnLaunchBundles() {
00200 ArrayList res = new ArrayList();
00201 for (Iterator i = archives.iterator(); i.hasNext(); ) {
00202 BundleArchive ba = (BundleArchive)i.next();
00203 if (ba.getStartOnLaunchFlag()) {
00204 res.add(ba.getBundleLocation());
00205 }
00206 }
00207 return res;
00208 }
00209
00210
00211
00212
00213
00220 boolean removeArchive(BundleArchive ba) {
00221 synchronized (archives) {
00222 int pos = find(ba.getBundleId());
00223 if (archives.get(pos) == ba) {
00224 archives.remove(pos);
00225 return true;
00226 } else {
00227 return false;
00228 }
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00243 private int find(long id) {
00244 int lb = 0;
00245 int ub = archives.size() - 1;
00246 int x = 0;
00247 while (lb < ub) {
00248 x = (lb + ub) / 2;
00249 long xid = ((BundleArchive)archives.get(x)).getBundleId();
00250 if (id <= xid) {
00251 ub = x;
00252 } else {
00253 lb = x+1;
00254 }
00255 }
00256 if (lb < archives.size() && ((BundleArchive)archives.get(lb)).getBundleId() < id) {
00257 return lb + 1;
00258 }
00259 return lb;
00260 }
00261
00262 }