1 4 5 package org.objectweb.fractal.jar; 6 7 import java.io.File ; 8 import java.io.FileInputStream ; 9 import java.io.FileOutputStream ; 10 import java.io.IOException ; 11 import java.io.InputStream ; 12 import java.io.ObjectInputStream ; 13 import java.io.ObjectOutputStream ; 14 import java.io.Serializable ; 15 import java.util.ArrayList ; 16 import java.util.HashMap ; 17 import java.util.HashSet ; 18 import java.util.Iterator ; 19 import java.util.List ; 20 import java.util.Map ; 21 import java.util.Set ; 22 import java.util.zip.ZipEntry ; 23 import java.util.zip.ZipInputStream ; 24 import java.util.zip.ZipOutputStream ; 25 26 public class PackageDatabase implements Serializable { 27 28 private Map packages; 30 private Map files; 32 public PackageDatabase () { 33 this.packages = new HashMap (); 34 this.files = new HashMap (); 35 } 36 37 public List getPackages () throws Exception { 38 return new ArrayList (packages.keySet()); 39 } 40 41 private Package getPackage (String pkg) throws Exception { 42 Package p = (Package )packages.get(pkg); 43 if (p == null) { 44 throw new Exception ("No such package " + pkg); 45 } 46 return p; 47 } 48 49 public List getPackageFiles (String pkg) throws Exception { 50 return new ArrayList (getPackage(pkg).files.values()); 51 } 52 53 public List getPackageDependencies (String pkg) throws Exception { 54 Set s = new HashSet (); 55 getPackageDependencies(getPackage(pkg), s); 56 return new ArrayList (s); 57 } 58 59 private void getPackageDependencies (Package p, Set s) { 60 Iterator i = p.packageDependencies.iterator(); 61 while (i.hasNext()) { 62 Package q = (Package )i.next(); 63 s.add(q); 64 getPackageDependencies(q, s); 65 } 66 } 67 68 public List getDependentPackages (String pkg) throws Exception { 69 Set s = new HashSet (); 70 getDependentPackages(getPackage(pkg), s); 71 return new ArrayList (s); 72 } 73 74 private void getDependentPackages (Package p, Set s) { 75 Iterator i = p.dependentPackages.iterator(); 76 while (i.hasNext()) { 77 Package q = (Package )i.next(); 78 s.add(q); 79 getDependentPackages(q, s); 80 } 81 } 82 83 public void getPackage (String pkg, ZipOutputStream os) throws Exception { 84 Iterator i = getPackage(pkg).files.values().iterator(); 85 while (i.hasNext()) { 86 PackageFile file = (PackageFile)i.next(); 87 os.putNextEntry(new ZipEntry (file.version + '/' + file.name)); 88 os.write(file.content); 89 os.closeEntry(); 90 } 91 } 92 93 public void getJAR (String pkg, ZipOutputStream os) throws Exception { 94 Map m = new HashMap (); 95 getJARFiles(getPackage(pkg), m); 96 97 Iterator i = m.values().iterator(); 98 while (i.hasNext()) { 99 PackageFile file = (PackageFile)i.next(); 100 os.putNextEntry(new ZipEntry (file.name)); 101 os.write(file.content); 102 os.closeEntry(); 103 } 104 } 105 106 private void getJARFiles (Package p, Map m) throws Exception { 107 Iterator i = p.files.values().iterator(); 108 while (i.hasNext()) { 109 PackageFile file = (PackageFile)i.next(); 110 if (file.name.endsWith("MANIFEST.MF")) { 111 continue; 112 } 113 if (m.get(file.name) != null) { 114 PackageFile f = (PackageFile)m.get(file.name); 115 if (!sameContent(file.content, f.content)) { 116 throw new Exception ( 117 "Cannot create a JAR file because several versions of " + f.name + 118 " are needed"); 119 } 120 } else { 121 m.put(file.name, file); 122 } 123 } 124 125 i = p.packageDependencies.iterator(); 126 while (i.hasNext()) { 127 Package q = (Package )i.next(); 128 getJARFiles(q, m); 129 } 130 } 131 132 private boolean sameContent (byte[] c, byte[] d) { 133 if (c.length == d.length) { 134 for (int i = 0; i < c.length; ++i) { 135 if (c[i] != d[i]) { 136 return false; 137 } 138 } 139 return true; 140 } 141 return false; 142 } 143 144 public Package addPackage (String pkg, PackageSource source, Set s) throws Exception { 145 if (packages.get(pkg) != null) { 146 return getPackage(pkg); 147 } 148 149 Package p = new Package (pkg); 150 packages.put(p.name, p); 151 s.add(p); 152 153 InputStream is = source.getPackage(pkg); 154 ZipInputStream zis = new ZipInputStream (is); 155 while (true) { 156 ZipEntry e = zis.getNextEntry(); 157 if (e != null) { 158 String n = e.getName(); 159 int dash = n.indexOf('/'); 160 String name; 161 String version; 162 if (dash == -1) { 163 version = ""; 164 name = n; 165 } else { 166 version = n.substring(0, dash); 167 name = n.substring(dash + 1); 168 } 169 PackageFile file = new PackageFile(name, version); 170 file.content = readFile(zis); 171 p.files.put(n, file); 172 zis.closeEntry(); 173 174 if (!n.endsWith("MANIFEST.MF")) { 175 file = addFile(file); 176 } 177 file.packages.add(p); 178 } else { 179 break; 180 } 181 } 182 183 Iterator i = p.computeDependencies().iterator(); 184 while (i.hasNext()) { 185 Package q = addPackage((String )i.next(), source, s); 186 p.packageDependencies.add(q); 187 q.dependentPackages.add(p); 188 } 189 190 return p; 191 } 192 193 private byte[] readFile (InputStream is) throws IOException { 194 byte[] b = new byte[1000]; 195 int len = 0; 196 while (true) { 197 int n = is.read(b, len, b.length - len); 198 if (n == -1) { 199 if (len < b.length) { 200 byte[] c = new byte[len]; 201 System.arraycopy(b, 0, c, 0, len); 202 b = c; 203 } 204 return b; 205 } else { 206 len += n; 207 if (len == b.length) { 208 byte[] c = new byte[b.length + 1000]; 209 System.arraycopy(b, 0, c, 0, len); 210 b = c; 211 } 212 } 213 } 214 } 215 216 private PackageFile addFile (PackageFile file) throws Exception { 217 String key = file.version + '/' + file.name; 218 if (files.get(key) == null) { 219 files.put(key, file); 220 return file; 221 } else { 222 PackageFile f = (PackageFile)files.get(key); 223 if (!sameContent(file.content, f.content)) { 224 throw new Exception ( 225 "Cannot add package: the " + file.name + '-' + file.version + 226 " file content is not the same in the package and in the database"); 227 } 228 return f; 229 } 230 } 231 232 public void removePackage (String pkg) throws Exception { 233 removePackage(getPackage(pkg)); 234 } 235 236 public void removePackage (Package pkg) { 237 Iterator i = pkg.files.values().iterator(); 239 while (i.hasNext()) { 240 PackageFile file = (PackageFile)i.next(); 241 file.packages.remove(pkg); 242 if (file.packages.size() == 0) { 243 files.remove(file.version + '/' + file.name); 244 } 245 } 246 247 i = pkg.packageDependencies.iterator(); 249 while (i.hasNext()) { 250 Package q = (Package )i.next(); 251 q.dependentPackages.remove(pkg); 252 } 253 254 i = new ArrayList (pkg.dependentPackages).iterator(); 256 while (i.hasNext()) { 257 removePackage((Package )i.next()); 258 } 259 260 packages.remove(pkg.name); 261 } 262 263 265 public static void main (String [] args) throws Exception { 266 if (args.length < 3) { 267 printUsage(); 268 } 269 String database = args[0]; 270 String source = args[1]; 271 String op = args[2]; 272 273 PackageDatabase db; 274 if (new File (database).exists()) { 275 ObjectInputStream is = new ObjectInputStream (new FileInputStream (database)); 276 db = (PackageDatabase)is.readObject(); 277 is.close(); 278 } else { 279 System.out.println("Database does not exist, a new one will be created"); 280 db = new PackageDatabase(); 281 } 282 283 if (op.equals("-l")) { 284 if (args.length > 3) { 285 printUsage(); 286 } 287 List l = db.getPackages(); 288 System.out.println("Available packages:"); 289 for (int i = 0; i < l.size(); ++i) { 290 System.out.println(" " + l.get(i)); 291 } 292 } else { 293 if (args.length != 4) { 294 printUsage(); 295 } 296 String pkg = args[3]; 297 if (op.equals("-i")) { 298 List l = db.getPackageFiles(pkg); 299 System.out.println("Package files:"); 300 for (int i = 0; i < l.size(); ++i) { 301 System.out.println(" " + l.get(i)); 302 } 303 l = db.getPackageDependencies(pkg); 304 System.out.println("Package dependencies:"); 305 for (int i = 0; i < l.size(); ++i) { 306 System.out.println(" " + l.get(i)); 307 } 308 l = db.getDependentPackages(pkg); 309 System.out.println("Dependent packages:"); 310 for (int i = 0; i < l.size(); ++i) { 311 System.out.println(" " + l.get(i)); 312 } 313 } else if (op.equals("-x")) { 314 FileOutputStream fos = new FileOutputStream (pkg + ".far"); 315 ZipOutputStream zos = new ZipOutputStream (fos); 316 db.getPackage(pkg, zos); 317 zos.close(); 318 } else if (op.equals("-j")) { 319 FileOutputStream fos = new FileOutputStream (pkg + ".jar"); 320 ZipOutputStream zos = new ZipOutputStream (fos); 321 db.getJAR(pkg, zos); 322 zos.close(); 323 } else if (op.equals("-a")) { 324 Set s = new HashSet (); 325 db.addPackage(pkg, new LocalPackageSource(source), s); 326 System.out.println("The following packages need to be added:"); 327 Iterator i = s.iterator(); 328 while (i.hasNext()) { 329 System.out.println(" " + i.next()); 330 } 331 ObjectOutputStream os = new ObjectOutputStream (new FileOutputStream (database)); 333 os.writeObject(db); 334 os.close(); 335 } else if (op.equals("-r")) { 336 List l = db.getDependentPackages(pkg); 337 l.add(db.getPackage(pkg)); 338 System.out.println("The following packages need to be removed:"); 339 for (int i = 0; i < l.size(); ++i) { 340 System.out.println(" " + l.get(i)); 341 } 342 db.removePackage(pkg); 344 ObjectOutputStream os = new ObjectOutputStream (new FileOutputStream (database)); 345 os.writeObject(db); 346 os.close(); 347 } else { 348 printUsage(); 349 } 350 } 351 } 352 353 private static void printUsage () { 354 System.err.println("Usage: <database> <package source> -l|-i|-x|-j|-a|-r [<pkg>]"); 355 System.exit(0); 356 } 357 } 358 | Popular Tags |