Author: toad
Date: 2005-10-28 19:24:06 +0000 (Fri, 28 Oct 2005)
New Revision: 7462
Modified:
trunk/freenet/src/freenet/client/ArchiveManager.java
trunk/freenet/src/freenet/client/ClientMetadata.java
trunk/freenet/src/freenet/client/DefaultMIMETypes.java
trunk/freenet/src/freenet/client/Metadata.java
trunk/freenet/src/freenet/keys/FreenetURI.java
Log:
Various.
Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java 2005-10-28
15:12:45 UTC (rev 7461)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java 2005-10-28
19:24:06 UTC (rev 7462)
@@ -5,7 +5,9 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
@@ -216,8 +218,9 @@
* @param ctx The context object.
* @param key The key from which the archive we are unpacking was
fetched.
* @param names Set of names in the archive.
+ * @throws ArchiveFailureException
*/
- private void generateMetadata(ArchiveStoreContext ctx, FreenetURI key,
HashSet names) {
+ private void generateMetadata(ArchiveStoreContext ctx, FreenetURI key,
HashSet names) throws ArchiveFailureException {
/* What we have to do is to:
* - Construct a filesystem tree of the names.
* - Turn each level of the tree into a Metadata object,
including those below it, with
@@ -225,9 +228,50 @@
* - Turn the master Metadata object into binary metadata, with
all its subsidiaries.
* - Create a .metadata entry containing this data.
*/
-
- // TODO implement!
+ // Root directory.
+ // String -> either itself, or another HashMap
+ HashMap dir = new HashMap();
+ Iterator i = names.iterator();
+ while(i.hasNext()) {
+ String name = (String) i.next();
+ addToDirectory(dir, name, "");
+ }
+ Metadata metadata = new Metadata(dir);
+ TempStoreElement element = makeTempStoreBucket(-1);
+ OutputStream os = element.bucket.getOutputStream();
+ metadata.writeTo(os);
+ os.close();
+ addStoreElement(ctx, key, ".metadata", element);
}
+
+ private void addToDirectory(HashMap dir, String name, String prefix)
throws ArchiveFailureException {
+ int x = name.indexOf('/');
+ if(x < 0) {
+ if(dir.containsKey(name)) {
+ throw new ArchiveFailureException("Invalid
archive: contains "+prefix+name+" twice");
+ }
+ dir.put(name, name);
+ } else {
+ String before = name.substring(0, x);
+ String after;
+ if(x == name.length()-1) {
+ // Last char
+ after = "";
+ } else
+ after = name.substring(x+1, name.length());
+ Object o = (Object) dir.get(before);
+ HashMap map;
+ if(o == null) {
+ map = new HashMap();
+ dir.put(before, map);
+ }
+ if(o instanceof String) {
+ throw new ArchiveFailureException("Invalid
archive: contains "+name+" as both file and dir");
+ }
+ map = (HashMap) o;
+ addToDirectory(map, after, prefix + before + "/");
+ }
+ }
private void addErrorElement(ArchiveStoreContext ctx, FreenetURI key,
String name, String error) {
ErrorArchiveStoreItem element = new ErrorArchiveStoreItem(ctx,
key, name, error);
Modified: trunk/freenet/src/freenet/client/ClientMetadata.java
===================================================================
--- trunk/freenet/src/freenet/client/ClientMetadata.java 2005-10-28
15:12:45 UTC (rev 7461)
+++ trunk/freenet/src/freenet/client/ClientMetadata.java 2005-10-28
19:24:06 UTC (rev 7462)
@@ -5,9 +5,6 @@
*/
public class ClientMetadata {
- /** Default MIME type - what to set it to if we don't know any better */
- public static final String DEFAULT_MIME_TYPE =
"application/octet-stream";
-
/** The document MIME type */
private String mimeType;
@@ -22,7 +19,7 @@
public String getMIMEType() {
if(mimeType == null || mimeType.length() == 0)
- return DEFAULT_MIME_TYPE;
+ return DefaultMIMETypes.DEFAULT_MIME_TYPE;
return mimeType;
}
Modified: trunk/freenet/src/freenet/client/DefaultMIMETypes.java
===================================================================
--- trunk/freenet/src/freenet/client/DefaultMIMETypes.java 2005-10-28
15:12:45 UTC (rev 7461)
+++ trunk/freenet/src/freenet/client/DefaultMIMETypes.java 2005-10-28
19:24:06 UTC (rev 7462)
@@ -8,6 +8,9 @@
*/
class DefaultMIMETypes {
+ /** Default MIME type - what to set it to if we don't know any better */
+ public static final String DEFAULT_MIME_TYPE =
"application/octet-stream";
+
private static Vector mimeTypesByNumber = new Vector();
private static HashMap mimeTypesByName = new HashMap();
@@ -26,7 +29,7 @@
Short t = new Short(type);
if(extensions != null)
for(int i=0;i<extensions.length;i++)
- mimeTypesByExtension.put(extensions[i], t);
+
mimeTypesByExtension.put(extensions[i].toLowerCase(), t);
}
protected static synchronized void addMIMEType(short number, String
type, String extensions) {
@@ -665,4 +668,16 @@
addMIMEType((short)611, "x-conference/x-cooltalk", "ice");
addMIMEType((short)612, "x-world/x-vrml", "vrm vrml wrl");
}
+
+ /** Guess a MIME type from a filename */
+ public static String guessMIMEType(String arg) {
+ int x = arg.indexOf('.');
+ if(x == -1 || x == arg.length()-1)
+ return DEFAULT_MIME_TYPE;
+ String ext = arg.substring(x+1).toLowerCase();
+ Short mimeIndexOb = (Short) mimeTypesByExtension.get(ext);
+ if(mimeIndexOb != null) {
+ return (String)
mimeTypesByNumber.get(mimeIndexOb.intValue());
+ } else return DEFAULT_MIME_TYPE;
+ }
}
Modified: trunk/freenet/src/freenet/client/Metadata.java
===================================================================
--- trunk/freenet/src/freenet/client/Metadata.java 2005-10-28 15:12:45 UTC
(rev 7461)
+++ trunk/freenet/src/freenet/client/Metadata.java 2005-10-28 19:24:06 UTC
(rev 7462)
@@ -1,10 +1,12 @@
package freenet.client;
import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import freenet.keys.ClientCHK;
import freenet.keys.ClientKey;
@@ -104,7 +106,7 @@
}
if(noMIME) {
- mimeType = ClientMetadata.DEFAULT_MIME_TYPE;
+ mimeType = DefaultMIMETypes.DEFAULT_MIME_TYPE;
} else {
if(compressedMIME) {
short x = dis.readShort();
@@ -220,17 +222,67 @@
}
/**
+ * Create a Metadata object for an archive which does not have its own
+ * metadata.
+ * @param dir A map of names (string) to either files (same string) or
+ * directories (more HashMap's)
+ */
+ Metadata(HashMap dir) {
+ // Simple manifest - contains actual redirects.
+ // Not zip manifest, which is basically a redirect.
+ documentType = SIMPLE_MANIFEST;
+ noMIME = true;
+ mimeType = null;
+ clientMetadata = new ClientMetadata(null);
+ manifestEntries = new HashMap();
+ int count = 0;
+ for(Iterator i = dir.keySet().iterator();i.hasNext();) {
+ String key = (String) i.next();
+ count++;
+ Object o = dir.get(key);
+ Metadata target;
+ if(o instanceof String) {
+ // Zip internal redirect
+ target = new Metadata(ZIP_INTERNAL_REDIRECT,
key);
+ } else if(o instanceof HashMap) {
+ target = new Metadata((HashMap)o);
+ } else throw new IllegalArgumentException("Not String
nor HashMap: "+o);
+ byte[] data = target.writeToByteArray();
+ manifestEntries.put(key, data);
+ }
+ manifestEntryCount = count;
+ }
+
+ public Metadata(byte docType, String arg) {
+ if(docType == ZIP_INTERNAL_REDIRECT) {
+ documentType = docType;
+ // Determine MIME type
+ mimeType = DefaultMIMETypes.guessMIMEType(arg);
+ clientMetadata = new ClientMetadata(mimeType);
+ nameInArchive = arg;
+ } else
+ throw new IllegalArgumentException();
+ }
+
+ private byte[] writeToByteArray() {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ writeTo(baos);
+ return baos.toByteArray();
+ }
+
+ /**
* Read a key using the current settings.
+ * @throws IOException
*/
- private FreenetURI readKey(DataInputStream dis) {
+ private FreenetURI readKey(DataInputStream dis) throws IOException {
// Read URL
if(fullKeys) {
- int length = (dis.readByte() & 0xff);
+ int length = dis.readShort();
byte[] buf = new byte[length];
dis.readFully(buf);
- simpleRedirectKey = FreenetURI.fromFullBinaryKey(buf);
+ return FreenetURI.fromFullBinaryKey(buf);
} else {
- simpleRedirectKey =
ClientCHK.readRawBinaryKey(dis).getURI();
+ return ClientCHK.readRawBinaryKey(dis).getURI();
}
}
Modified: trunk/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- trunk/freenet/src/freenet/keys/FreenetURI.java 2005-10-28 15:12:45 UTC
(rev 7461)
+++ trunk/freenet/src/freenet/keys/FreenetURI.java 2005-10-28 19:24:06 UTC
(rev 7462)
@@ -1,5 +1,8 @@
package freenet.keys;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.util.LinkedList;
import java.util.StringTokenizer;
@@ -10,10 +13,13 @@
import freenet.support.IllegalBase64Exception;
/**
+ * Note that the metadata pairs below are not presently supported. They are
supported
+ * by the old (0.5) code however.
+ *
* FreenetURI handles parsing and creation of the Freenet URI format, defined
* as follows:
* <p>
- * <code>freenet:[EMAIL
PROTECTED],CryptoKey][,n1=v1,n2=v2,...][/docname][//metastring]</code>
+ * <code>freenet:[EMAIL
PROTECTED],CryptoKey[,n1=v1,n2=v2,...][/docname][//metastring]</code>
* </p>
* <p>
* where KeyType is the TLA of the key (currently SVK, SSK, KSK, or CHK). If
@@ -391,4 +397,45 @@
}
return l;
}
+
+ static final byte CHK = 1;
+ static final byte SSK = 2;
+
+ public static FreenetURI fromFullBinaryKey(byte[] buf) throws
IOException {
+ ByteArrayInputStream bais = new ByteArrayInputStream(buf);
+ DataInputStream dis = new DataInputStream(bais);
+ return fromFullBinaryKey(dis);
+ }
+
+ public static FreenetURI fromFullBinaryKey(DataInputStream dis) throws
IOException {
+ int x = 0;
+ byte type = dis.readByte();
+ String keyType;
+ if(type == CHK)
+ keyType = "CHK";
+ else if(type == SSK)
+ keyType = "SSK";
+ else
+ throw new MalformedURLException("Unrecognized type
"+type);
+ // routingKey is a hash, so is exactly 32 bytes
+ byte[] routingKey = new byte[32];
+ dis.readFully(routingKey);
+ // cryptoKey is a 256 bit AES key, so likewise
+ byte[] cryptoKey = new byte[32];
+ dis.readFully(cryptoKey);
+ // Number of bytes of extra depends on key type
+ int extraLen;
+ if(type == CHK)
+ extraLen = ClientCHK.EXTRA_LENGTH;
+ else
+ throw new UnsupportedOperationException("SSKs not
implemented yet!");
+ //extraLen = ClientSSK.EXTRA_LENGTH;
+ byte[] extra = new byte[extraLen];
+ dis.readFully(extra);
+ String docName = dis.readUTF();
+ int count = dis.readByte() & 0xff;
+ String[] metaStrings = new String[count];
+ for(int i=0;i<metaStrings.length;i++) metaStrings[i] =
dis.readUTF();
+ return new FreenetURI(keyType, docName, metaStrings,
routingKey, cryptoKey, extra);
+ }
}
_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs