Author: toad
Date: 2005-10-28 15:12:45 +0000 (Fri, 28 Oct 2005)
New Revision: 7461

Modified:
   trunk/freenet/src/freenet/client/ArchiveHandler.java
   trunk/freenet/src/freenet/client/ArchiveManager.java
   trunk/freenet/src/freenet/client/ArchiveStoreContext.java
   trunk/freenet/src/freenet/client/FetchException.java
   trunk/freenet/src/freenet/client/Fetcher.java
   trunk/freenet/src/freenet/client/FetcherContext.java
   trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
Log:
Implicit archive support.


Modified: trunk/freenet/src/freenet/client/ArchiveHandler.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveHandler.java        2005-10-27 
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/ArchiveHandler.java        2005-10-28 
15:12:45 UTC (rev 7461)
@@ -14,7 +14,8 @@
         * @throws MetadataParseException If there was an error parsing 
intermediary metadata.
         */
        public abstract Bucket getMetadata(ArchiveContext archiveContext,
-                       FetcherContext fetchContext, ClientMetadata dm, int 
recursionLevel)
+                       FetcherContext fetchContext, ClientMetadata dm, int 
recursionLevel, 
+                       boolean dontEnterImplicitArchives)
                        throws ArchiveFailureException, ArchiveRestartException,
                        MetadataParseException, FetchException;
 
@@ -30,7 +31,8 @@
         */
        public abstract Bucket get(String internalName,
                        ArchiveContext archiveContext, FetcherContext 
fetchContext,
-                       ClientMetadata dm, int recursionLevel)
+                       ClientMetadata dm, int recursionLevel, 
+                       boolean dontEnterImplicitArchives)
                        throws ArchiveFailureException, ArchiveRestartException,
                        MetadataParseException, FetchException;
 

Modified: trunk/freenet/src/freenet/client/ArchiveManager.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-27 
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/ArchiveManager.java        2005-10-28 
15:12:45 UTC (rev 7461)
@@ -225,6 +225,7 @@
                 * - Turn the master Metadata object into binary metadata, with 
all its subsidiaries.
                 * - Create a .metadata entry containing this data.
                 */
+               
                // TODO implement!
        }
 
@@ -280,4 +281,15 @@
                        throw new Error("Unsupported cipher: AES 256/256!", e);
                }
        }
+
+       public static boolean isUsableArchiveType(String type) {
+               return type.equals("application/zip") || 
type.equals("application/x-zip");
+               // Update when add new archive types
+       }
+
+       public static short getArchiveType(String type) {
+               if(type.equals("application/zip") || 
type.equals("application/x-zip"))
+                       return Metadata.ARCHIVE_ZIP;
+               else throw new IllegalArgumentException(); 
+       }
 }

Modified: trunk/freenet/src/freenet/client/ArchiveStoreContext.java
===================================================================
--- trunk/freenet/src/freenet/client/ArchiveStoreContext.java   2005-10-27 
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/ArchiveStoreContext.java   2005-10-28 
15:12:45 UTC (rev 7461)
@@ -30,17 +30,13 @@
                // Need to do anything here?
        }
 
-       /* (non-Javadoc)
-        * @see 
freenet.client.ArchiveHandler#getMetadata(freenet.client.ArchiveContext, 
freenet.client.FetcherContext, freenet.client.ClientMetadata, int)
-        */
-       public Bucket getMetadata(ArchiveContext archiveContext, FetcherContext 
fetchContext, ClientMetadata dm, int recursionLevel) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
-               return get(".metadata", archiveContext, fetchContext, dm, 
recursionLevel);
+       public Bucket getMetadata(ArchiveContext archiveContext, FetcherContext 
fetchContext, ClientMetadata dm, int recursionLevel, 
+                       boolean dontEnterImplicitArchives) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
+               return get(".metadata", archiveContext, fetchContext, dm, 
recursionLevel, dontEnterImplicitArchives);
        }
 
-       /* (non-Javadoc)
-        * @see freenet.client.ArchiveHandler#get(java.lang.String, 
freenet.client.ArchiveContext, freenet.client.FetcherContext, 
freenet.client.ClientMetadata, int)
-        */
-       public Bucket get(String internalName, ArchiveContext archiveContext, 
FetcherContext fetchContext, ClientMetadata dm, int recursionLevel) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
+       public Bucket get(String internalName, ArchiveContext archiveContext, 
FetcherContext fetchContext, ClientMetadata dm, int recursionLevel, 
+                       boolean dontEnterImplicitArchives) throws 
ArchiveFailureException, ArchiveRestartException, MetadataParseException, 
FetchException {
 
                // Do loop detection on the archive that we are about to fetch.
                archiveContext.doLoopDetection(key);
@@ -62,7 +58,7 @@
                        
                        if(fetchContext == null) return null;
                        Fetcher fetcher = new Fetcher(key, fetchContext, 
archiveContext);
-                       FetchResult result = fetcher.realRun(dm, 
recursionLevel, key);
+                       FetchResult result = fetcher.realRun(dm, 
recursionLevel, key, dontEnterImplicitArchives);
                        manager.extractToCache(key, archiveType, result.data, 
archiveContext, this);
                        return manager.getCached(key, internalName);
                }

Modified: trunk/freenet/src/freenet/client/FetchException.java
===================================================================
--- trunk/freenet/src/freenet/client/FetchException.java        2005-10-27 
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/FetchException.java        2005-10-28 
15:12:45 UTC (rev 7461)
@@ -42,4 +42,6 @@
        static final int TOO_MUCH_RECURSION = 9;
        /** Tried to access an archive file but not in an archive */
        static final int NOT_IN_ARCHIVE = 10;
+       /** Has more metastrings, can't fulfill them */
+       static final int HAS_MORE_METASTRINGS = 11;
 }

Modified: trunk/freenet/src/freenet/client/Fetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/Fetcher.java       2005-10-27 22:02:36 UTC 
(rev 7460)
+++ trunk/freenet/src/freenet/client/Fetcher.java       2005-10-28 15:12:45 UTC 
(rev 7461)
@@ -30,7 +30,7 @@
                for(int i=0;i<ctx.maxArchiveRestarts;i++) {
                        try {
                                ClientMetadata dm = new ClientMetadata();
-                               return realRun(dm, 0, origURI);
+                               return realRun(dm, 0, origURI, 
ctx.dontEnterImplicitArchives);
                        } catch (ArchiveRestartException e) {
                                archiveContext = new ArchiveContext();
                                continue;
@@ -57,7 +57,7 @@
         * @throws ArchiveFailureException If we could not extract data from an 
archive.
         * @throws ArchiveRestartException 
         */
-       FetchResult realRun(ClientMetadata dm, int recursionLevel, FreenetURI 
uri) 
+       FetchResult realRun(ClientMetadata dm, int recursionLevel, FreenetURI 
uri, boolean dontEnterImplicitArchives) 
        throws FetchException, MetadataParseException, ArchiveFailureException, 
ArchiveRestartException {
                ClientKey key = ClientKey.getBaseKey(uri);
                LinkedList metaStrings = uri.listMetaStrings();
@@ -89,7 +89,10 @@
                
                Metadata metadata = Metadata.construct(data);
                
-               return runMetadata(dm, recursionLevel, key, metaStrings, 
metadata, null, key.getURI());
+               FetchResult result = runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, null, key.getURI(), dontEnterImplicitArchives);
+               if(metaStrings.isEmpty()) return result;
+               // Still got some meta-strings
+               throw new FetchException(FetchException.HAS_MORE_METASTRINGS);
        }
        
        /**
@@ -107,7 +110,9 @@
         * @throws FetchException If the fetch failed for some reason.
         * @throws ArchiveRestartException 
         */
-       private FetchResult runMetadata(ClientMetadata dm, int recursionLevel, 
ClientKey key, LinkedList metaStrings, Metadata metadata, ArchiveHandler 
container, FreenetURI thisKey) throws MetadataParseException, FetchException, 
ArchiveFailureException, ArchiveRestartException {
+       private FetchResult runMetadata(ClientMetadata dm, int recursionLevel, 
ClientKey key, LinkedList metaStrings, 
+                       Metadata metadata, ArchiveHandler container, FreenetURI 
thisKey, boolean dontEnterImplicitArchives) 
+       throws MetadataParseException, FetchException, ArchiveFailureException, 
ArchiveRestartException {
                
                if(metadata.isSimpleManifest()) {
                        String name = (String) metaStrings.removeFirst();
@@ -118,31 +123,68 @@
                                metadata = metadata.getDocument(name);
                                thisKey = thisKey.pushMetaString(name);
                        }
-                       return runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, container, thisKey);
+                       return runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
                } else if(metadata.isArchiveManifest()) {
                        container = ctx.archiveManager.makeHandler(thisKey, 
metadata.getArchiveType());
-                       Bucket metadataBucket = 
container.getMetadata(archiveContext, ctx, dm, recursionLevel);
+                       Bucket metadataBucket = 
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
                        metadata = Metadata.construct(metadataBucket);
-                       return runMetadata(dm, recursionLevel+1, key, 
metaStrings, metadata, container, thisKey);
+                       return runMetadata(dm, recursionLevel+1, key, 
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
                } else if(metadata.isArchiveInternalRedirect()) {
                        if(container == null)
                                throw new 
FetchException(FetchException.NOT_IN_ARCHIVE);
                        else {
-                               Bucket result = 
container.get(metadata.getZIPInternalName(), archiveContext, ctx, dm, 
recursionLevel);
+                               /* Implicit archive handling:
+                                * Sooner or later we reach a 
SimpleFileRedirect to data, a Splitfile to data,
+                                * or an ArchiveInternalRedirect to data.
+                                * 
+                                * In this case, if it is an archive type, if 
implicit archive handling is enabled, and if
+                                * we have more meta-strings, we can try to 
enter it.
+                                */
+                               if((!dontEnterImplicitArchives) && 
ArchiveManager.isUsableArchiveType(dm.getMIMEType()) && 
(!metaStrings.isEmpty())) {
+                                       // Possible implicit archive inside 
archive?
+                                       container = 
ctx.archiveManager.makeHandler(thisKey, 
ArchiveManager.getArchiveType(dm.getMIMEType()));
+                                       Bucket metadataBucket = 
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
+                                       metadata = 
Metadata.construct(metadataBucket);
+                                       return runMetadata(dm, 
recursionLevel+1, key, metaStrings, metadata, container, thisKey, 
dontEnterImplicitArchives);
+                               }
+                               Bucket result = 
container.get(metadata.getZIPInternalName(), archiveContext, ctx, dm, 
recursionLevel, true);
                                
dm.mergeNoOverwrite(metadata.getClientMetadata());
                                return new FetchResult(dm, result);
                        }
                } else if(metadata.isMultiLevelMetadata()) {
                        // Doesn't have to be a splitfile; could be from a ZIP 
or a plain file.
                        metadata.setSimpleRedirect();
-                       FetchResult res = runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, container, thisKey);
+                       FetchResult res = runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, container, thisKey, true);
                        metadata = Metadata.construct(res.data);
-                       return runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, container, thisKey);
+                       return runMetadata(dm, recursionLevel, key, 
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
                } else if(metadata.isSingleFileRedirect()) {
                        FreenetURI uri = metadata.getSingleTarget();
                        dm.mergeNoOverwrite(metadata.getClientMetadata());
-                       return realRun(dm, recursionLevel, uri);
+                       if((!dontEnterImplicitArchives) && 
ArchiveManager.isUsableArchiveType(dm.getMIMEType()) && 
(!metaStrings.isEmpty())) {
+                               ClientKey target = ClientKey.getBaseKey(uri);
+                               if(!(target.isMetadata())) {
+                                       // Target *is not* metadata.
+                                       // Therefore target is a usable archive.
+                                       // We might not have to fetch it.
+                                       container = 
ctx.archiveManager.makeHandler(uri, 
ArchiveManager.getArchiveType(dm.getMIMEType()));
+                                       Bucket metadataBucket = 
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
+                                       metadata = 
Metadata.construct(metadataBucket);
+                                       return runMetadata(dm, 
recursionLevel+1, key, metaStrings, metadata, container, thisKey, 
dontEnterImplicitArchives);
+                               }
+                       }
+                       return realRun(dm, recursionLevel, uri, 
dontEnterImplicitArchives);
                } else if(metadata.isSplitfile()) {
+                       // Straight data splitfile.
+                       // Might be used by parents for something else, in 
which case they will set dontEnterImplicitArchives.
+                       dm.mergeNoOverwrite(metadata.getClientMetadata()); // 
even splitfiles can have mime types!
+                       if((!dontEnterImplicitArchives) && 
ArchiveManager.isUsableArchiveType(dm.getMIMEType()) && 
(!metaStrings.isEmpty())) {
+                               // We know target is not metadata.
+                               container = 
ctx.archiveManager.makeHandler(thisKey, 
ArchiveManager.getArchiveType(dm.getMIMEType()));
+                               Bucket metadataBucket = 
container.getMetadata(archiveContext, ctx, dm, recursionLevel, true);
+                               metadata = Metadata.construct(metadataBucket);
+                               return runMetadata(dm, recursionLevel+1, key, 
metaStrings, metadata, container, thisKey, dontEnterImplicitArchives);
+                       }
+                       
                        SplitFetcher sf = new SplitFetcher(metadata, 
ctx.maxTempLength, archiveContext, ctx);
                        Bucket sfResult = sf.fetch(); // will throw in event of 
error
                        return new FetchResult(dm, sfResult);
@@ -151,5 +193,4 @@
                        throw new 
FetchException(FetchException.UNKNOWN_METADATA);
                }
        }
-
 }

Modified: trunk/freenet/src/freenet/client/FetcherContext.java
===================================================================
--- trunk/freenet/src/freenet/client/FetcherContext.java        2005-10-27 
22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/FetcherContext.java        2005-10-28 
15:12:45 UTC (rev 7461)
@@ -13,9 +13,11 @@
        final BucketFactory bucketFactory;
        final int maxRecursionLevel;
        final int maxArchiveRestarts;
+       final boolean dontEnterImplicitArchives;
        
        public FetcherContext(SimpleLowLevelClient client, long curMaxLength, 
                        long curMaxTempLength, int maxRecursionLevel, int 
maxArchiveRestarts,
+                       boolean dontEnterImplicitArchives,
                        ArchiveManager archiveManager, BucketFactory 
bucketFactory) {
                this.client = client;
                this.maxOutputLength = curMaxLength;
@@ -24,6 +26,7 @@
                this.bucketFactory = bucketFactory;
                this.maxRecursionLevel = maxRecursionLevel;
                this.maxArchiveRestarts = maxArchiveRestarts;
+               this.dontEnterImplicitArchives = dontEnterImplicitArchives;
        }
 
 }

Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2005-10-27 22:02:36 UTC (rev 7460)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2005-10-28 15:12:45 UTC (rev 7461)
@@ -13,6 +13,7 @@
        private long curMaxTempLength;
        static final int MAX_RECURSION = 10;
        static final int MAX_ARCHIVE_RESTARTS = 2;
+       static final boolean DONT_ENTER_IMPLICIT_ARCHIVES = true;
        
        public HighLevelSimpleClientImpl(SimpleLowLevelClient client, 
ArchiveManager mgr, BucketFactory bf) {
                this.client = client;
@@ -30,7 +31,7 @@
 
        public FetchResult fetch(FreenetURI uri) throws FetchException {
                FetcherContext context = new FetcherContext(client, 
curMaxLength, curMaxLength, 
-                               MAX_RECURSION, MAX_ARCHIVE_RESTARTS, 
archiveManager, bucketFactory);
+                               MAX_RECURSION, MAX_ARCHIVE_RESTARTS, 
DONT_ENTER_IMPLICIT_ARCHIVES, archiveManager, bucketFactory);
                Fetcher f = new Fetcher(uri, context, new ArchiveContext());
                return f.run();
        }

_______________________________________________
cvs mailing list
[email protected]
http://emu.freenetproject.org/cgi-bin/mailman/listinfo/cvs

Reply via email to