Started a basic storage manager.
authorFredrik Tolf <fredrik@dolda2000.com>
Thu, 15 Oct 2009 05:26:54 +0000 (07:26 +0200)
committerFredrik Tolf <fredrik@dolda2000.com>
Thu, 15 Oct 2009 05:26:54 +0000 (07:26 +0200)
src/dolda/jsvc/store/Store.java [new file with mode: 0644]

diff --git a/src/dolda/jsvc/store/Store.java b/src/dolda/jsvc/store/Store.java
new file mode 100644 (file)
index 0000000..8e050a3
--- /dev/null
@@ -0,0 +1,85 @@
+package dolda.jsvc.store;
+
+import dolda.jsvc.*;
+import dolda.jsvc.util.Misc;
+import java.io.*;
+import java.security.*;
+import java.security.cert.Certificate;
+import java.util.*;
+
+public class Store {
+    private static Map<Package, Store> interned = new WeakHashMap<Package, Store>();
+    private final Package pkg;
+    private final File base;
+    
+    private Store(Package pkg, CodeSource src, File root) {
+       this.pkg = pkg;
+       String nm = pkg.getName();
+       File base = root;
+       if(src != null) {
+           try {
+               MessageDigest fdig = MessageDigest.getInstance("MD5");
+               for(Certificate cert : src.getCertificates()) {
+                   MessageDigest cdig = MessageDigest.getInstance("MD5");
+                   cdig.update(cert.getEncoded());
+                   fdig.update(cdig.digest());
+               }
+               byte[] fp = fdig.digest();
+               StringBuilder buf = new StringBuilder();
+               for(byte b : fp) {
+                   buf.append(Misc.int2hex((b & 0xf0) >> 4, true));
+                   buf.append(Misc.int2hex(b & 0x0f, true));
+               }
+               base = new File(base, buf.toString());
+           } catch(NoSuchAlgorithmException e) {
+               throw(new Error(e));
+           } catch(java.security.cert.CertificateEncodingException e) {
+               throw(new Error(e));
+           }
+       }
+       int p = 0;
+       int p2;
+       while((p2 = nm.indexOf('.', p)) >= 0) {
+           base = new File(base, nm.substring(p, p2));
+           p = p2 + 1;
+       }
+       this.base = new File(base, nm.substring(p));
+    }
+    
+    private static File getstoreroot() {
+       ThreadContext ctx = ThreadContext.current();
+       if(ctx == null)
+           throw(new RuntimeException("Not running in jsvc context"));
+       String bn = ctx.server().config("jsvc.storage");
+       if(bn == null)
+           throw(new RuntimeException("No storage root has been configured"));
+       return(new File(bn));
+    }
+
+    public static Store forclass(final Class<?> cl) {
+       Package pkg = cl.getPackage();
+       File root = getstoreroot();
+       Store s;
+       synchronized(interned) {
+           s = interned.get(pkg);
+           if(s == null) {
+               ProtectionDomain dom;
+               dom = AccessController.doPrivileged(new PrivilegedAction<ProtectionDomain>() {
+                       public ProtectionDomain run() {
+                           try {
+                               return(cl.getProtectionDomain());
+                           } catch(SecurityException e) {
+                               return(null);
+                           }
+                       }
+                   });
+               if(dom != null)
+                   s = new Store(pkg, dom.getCodeSource(), root);
+               else
+                   s = new Store(pkg, null, root);
+               interned.put(pkg, s);
+           }
+       }
+       return(s);
+    }
+}