Started a basic storage manager.
[jsvc.git] / src / dolda / jsvc / store / Store.java
CommitLineData
36537ce8
FT
1package dolda.jsvc.store;
2
3import dolda.jsvc.*;
4import dolda.jsvc.util.Misc;
5import java.io.*;
6import java.security.*;
7import java.security.cert.Certificate;
8import java.util.*;
9
10public class Store {
11 private static Map<Package, Store> interned = new WeakHashMap<Package, Store>();
12 private final Package pkg;
13 private final File base;
14
15 private Store(Package pkg, CodeSource src, File root) {
16 this.pkg = pkg;
17 String nm = pkg.getName();
18 File base = root;
19 if(src != null) {
20 try {
21 MessageDigest fdig = MessageDigest.getInstance("MD5");
22 for(Certificate cert : src.getCertificates()) {
23 MessageDigest cdig = MessageDigest.getInstance("MD5");
24 cdig.update(cert.getEncoded());
25 fdig.update(cdig.digest());
26 }
27 byte[] fp = fdig.digest();
28 StringBuilder buf = new StringBuilder();
29 for(byte b : fp) {
30 buf.append(Misc.int2hex((b & 0xf0) >> 4, true));
31 buf.append(Misc.int2hex(b & 0x0f, true));
32 }
33 base = new File(base, buf.toString());
34 } catch(NoSuchAlgorithmException e) {
35 throw(new Error(e));
36 } catch(java.security.cert.CertificateEncodingException e) {
37 throw(new Error(e));
38 }
39 }
40 int p = 0;
41 int p2;
42 while((p2 = nm.indexOf('.', p)) >= 0) {
43 base = new File(base, nm.substring(p, p2));
44 p = p2 + 1;
45 }
46 this.base = new File(base, nm.substring(p));
47 }
48
49 private static File getstoreroot() {
50 ThreadContext ctx = ThreadContext.current();
51 if(ctx == null)
52 throw(new RuntimeException("Not running in jsvc context"));
53 String bn = ctx.server().config("jsvc.storage");
54 if(bn == null)
55 throw(new RuntimeException("No storage root has been configured"));
56 return(new File(bn));
57 }
58
59 public static Store forclass(final Class<?> cl) {
60 Package pkg = cl.getPackage();
61 File root = getstoreroot();
62 Store s;
63 synchronized(interned) {
64 s = interned.get(pkg);
65 if(s == null) {
66 ProtectionDomain dom;
67 dom = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {
68 public ProtectionDomain run() {
69 try {
70 return(cl.getProtectionDomain());
71 } catch(SecurityException e) {
72 return(null);
73 }
74 }
75 });
76 if(dom != null)
77 s = new Store(pkg, dom.getCodeSource(), root);
78 else
79 s = new Store(pkg, null, root);
80 interned.put(pkg, s);
81 }
82 }
83 return(s);
84 }
85}