Revision: 2344
          http://vexi.svn.sourceforge.net/vexi/?rev=2344&view=rev
Author:   mkpg2
Date:     2007-09-27 08:46:56 -0700 (Thu, 27 Sep 2007)

Log Message:
-----------
Feature. Basic font repository. Install fonts. Test case.
Changed download monitoring slightly.
Fix. Testcase leaving stream open (write xml without xml/explicit close)

Modified Paths:
--------------
    trunk/core/org.vexi.core/src/org/vexi/core/Resources.java
    trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp
    trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java
    trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java
    trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java
    trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t
    trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java

Added Paths:
-----------
    trunk/core/org.vexi.core/src_junit/testdeployment/VeraSans.vexi

Modified: trunk/core/org.vexi.core/src/org/vexi/core/Resources.java
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Resources.java   2007-09-27 
15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Resources.java   2007-09-27 
15:46:56 UTC (rev 2344)
@@ -1,5 +1,6 @@
 package org.vexi.core;
 
+import java.awt.Font;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
@@ -21,10 +22,11 @@
 import org.ibex.js.JS;
 import org.ibex.js.JSExn;
 import org.ibex.js.JSU;
+import org.ibex.js.Thread;
+import org.ibex.js.JS.Enumeration;
+import org.ibex.js.JS.Keys;
 import org.ibex.js.JSU.Wrapper;
-import org.ibex.js.Thread;
 import org.ibex.util.Basket;
-import org.ibex.util.Callable;
 import org.ibex.util.Encode;
 import org.ibex.util.InputStreamToByteArray;
 import org.ibex.util.Log;
@@ -61,13 +63,6 @@
     //private static final boolean precache = false;
     //private static final boolean download = true;
 
-    private static final boolean zipfile = true;
-    private static final String[] datefmts = {
-        "EEE, dd MMM yyyy HH:mm:ss zzz", 
-        "EEEE, dd-MMM-yy HH:mm:ss zzz", 
-        "EEE MMM d HH:mm:ss yyyy"
-    };
-       
     public static Fountain fountainForNames(final JS[] urls) throws JSExn{
        if(urls.length==0) return null;
        if(urls.length==1){
@@ -127,7 +122,7 @@
                newStream = new RemoteArchive(cacheableName);
             }
             else {
-                newStream = new Fountain.HTTP(cacheableName);
+                newStream = new RemoteFile(cacheableName);
             }
         } else {
                
@@ -300,7 +295,7 @@
     }
 
     /** convert a path (or URL) to a file name */
-    private static String pathToFileName(String path) {
+    static String pathToFileName(String path) {
         return path.replace('/', '_').replace('\\', '_').replace(':', '_');
     }
 
@@ -316,126 +311,152 @@
         }
     };
     
-    public static class RemoteArchive extends Fountain{
-
-       String url;
+    public static class RemoteArchive extends RemoteFile{
        Fountain.Zip cache;
        
-               public RemoteArchive(String url) { while (url.endsWith("/")) 
url = url.substring(0, url.length() - 1); this.url = url;  }
+               public RemoteArchive(String url) { super(url);}
 
                public JS _get(JS key) throws JSExn {
-                       try {if(cache == null)cache(this);} catch (IOException 
e) {
-                               throw new JSExn(e.getMessage());}
+                       cache_(this);
                        return cache._get(key);
                }
                
                public InputStream getInputStream() throws IOException {
                        // First download we check and potentially update the 
cache 
-                       if(cache == null){cache(this);}
+                       cache(this); // FIXME - should take principal as 
argument?
                        return cache.getInputStream();
                }
                
-           /** pull the specified file from a URL and store it in a temporary 
local .vexi file 
-            * @throws IOException */
+           /** pull the specified file from a URL and store it in a temporary 
local .vexi file
+            * @param principal    
+            * @throws IOException 
+            * @throws JSExn */
                public void cache(final JS principal) throws IOException {
-                           int BUFFER_SIZE = 1024;
-                   byte[] buffer = new byte[BUFFER_SIZE];
+                       if(cache!=null) return;
+                       super.cache(principal);
+                       cache = new Fountain.Zip(super.cache);
+           }
+               
+               private void cache_(final JS principal) throws JSExn {
+                       try{cache(principal);}catch(IOException e){throw new 
JSExn(e.getMessage());}
+               }
+               
+               public Keys keys() throws JSExn {
+                       cache_(this); // FIXME - should take principal as 
argument
+                       return cache.keys();
+               }
+               
+    }
+    
+    static public class RemoteFile extends Fountain{
 
-               Log.uInfo(Main.class, "Downloading vexi file from " + url);
-               
-               Fountain httpStream = new Fountain.ProgressWatcher(new 
Fountain.HTTP(url), new Callable(){
-                               public Object run(Object o) throws Exception {
-                                       Trap t = principal.getTrap(SC_Progress);
-                                       //Log.uInfo("Blah", o);
-                                       // FEATURE - if not run yet, update 
previous 
-                                       // scheduled JS arg. 
-                                       if(t!=null && (t=t.write())!=null) 
-                                               Thread.runInNew(t.function(), 
new JS[]{(JS)o});
-                                       return null;
-                               }});
-               //HTTP.HTTPInputStream his = 
(HTTP.HTTPInputStream)HttpStream.getHeadStream();
-               // get the timestamp on the remote file
-               long remoteModifiedDate = 0;
-               String remoteModified = null;
-                       try {
-                               JS info = httpStream.getInfo();
-                               remoteModified = 
JSU.toString(info.get(SC_lastModified));
-                               Trap t = principal.getTrap(SC_Downloading);
-                               if(t!=null && (t=t.write())!=null) 
-                                       Thread.runInNew(t.function(), new 
JS[]{info});
-                       } catch (JSExn e1) {
-                               // Should not happen!
-                               Log.error(Resources.class, e1);
-                       }
-               
-               if (remoteModified!=null && !remoteModified.equals("")) {
-                       // Try parsing the date using each of the date formats 
specified in RFC2616
-                       DateFormat dfmt;
-                       Date dt = null;
-                       for (int i=0; dt==null && i<datefmts.length; i++) {
-                               dfmt = new SimpleDateFormat(datefmts[i]);
-                               try { dt = dfmt.parse(remoteModified); } catch 
(ParseException e) { dt = null; }
-                       }
-                       if (dt==null) remoteModifiedDate = 0; // unable to 
parse remote date, so ignore it
-                       else          remoteModifiedDate = dt.getTime();
-               }
+       String url;
+       String filename;
+       Fountain.File cache;
+       
 
-               String fname = getTempDir() + pathToFileName(url);
-               java.io.File localFile = new java.io.File(fname);
+       public RemoteFile(String url, String filename) { 
+               while (url.endsWith("/")) url = url.substring(0, url.length() - 
1); 
+               this.url = url;
+               this.filename = filename;
+       }
 
-               // if the file exists, then compare the timestamps
-               if (localFile.exists()) {
-                       long localModified = localFile.lastModified();
-                       if (remoteModifiedDate > 0) {
-                               if (remoteModifiedDate <= localModified) {
-                                       // if the local file is newer or the 
same age, then just use it
-                                       Log.uInfo(Resources.class, "... using 
cached copy of vexi file");
-                               cache = new Zip(new 
File(localFile.getAbsolutePath()));
-                               return;
-                               }
-                       }
-               }
+       public RemoteFile(String url) {
+               this(url, Resources.getTempDir() + 
Resources.pathToFileName(url));
+       }
 
-               // download the file
-               FileOutputStream fos = new FileOutputStream(localFile);
-               int len;
-               InputStream is = httpStream.getInputStream();
-               while ((len=is.read(buffer, 0, buffer.length)) >= 0) {
-                       fos.write(buffer, 0, len);
-               }
-               fos.close();
-               is.close();
+       public InputStream getInputStream() throws IOException {
+               // First download we check and potentially update the cache 
+               if(cache == null){cache(this);}
+               return cache.getInputStream();
+       }
 
-               // set the local file's timestamp
-               if (remoteModifiedDate > 0) {
-                       localFile.setLastModified(remoteModifiedDate);
-               }
+       /** pull the specified file from a URL and store it in a temporary 
local .vexi file
+        * @param principal    
+        * @throws IOException 
+        * @throws JSExn */
+       public void cache(final JS principal) throws IOException {
+               Log.uInfo(Main.class, "Downloading vexi file from " + url);
+               try{
+                       Fountain.ProgressWatcher httpStream = new 
Fountain.ProgressWatcher(principal, new Fountain.HTTP(url));
+                       Trap finishTrap = principal.getTrap(SC_finish);
+                       finishTrap=finishTrap==null?null:finishTrap.write();
+                       
+                       // get the timestamp on the remote file
+                       JS info = httpStream.getInfo();
+                       long remoteModifiedDate = 
parseDate(JSU.toString(info.get(SC_lastModified)));
 
-               Log.uInfo(Resources.class, "Done downloading to file " + 
localFile.getAbsolutePath());
-               cache = new Zip(new File(localFile.getAbsolutePath()));
-           }
-               
-               public void addTrap(JS key, JS f) throws JSExn {
-                       //TODO - worthwhile optimisation or not?
-                       //String s = JSU.toString(key);
-                       //if(s.equals("Downloading") || s.equals("Progress")) 
watch=true;
-                       super.addTrap(key, f);
-               }
-               
+                       java.io.File localFile = new java.io.File(filename);
+
+                       // if the file exists and we know the remote 
+                       // modification date - then compare the timestamps
+                       if (localFile.exists() && remoteModifiedDate > 0) {
+                               long localModified = localFile.lastModified();
+                               if (remoteModifiedDate <= localModified) {
+                                       // if the local file is newer or the 
same age, then just use it
+                                       Log.uInfo(Resources.class, "... using 
cached copy of file " + url);
+                                       cache = new 
File(localFile.getAbsolutePath());
+                                       if(finishTrap!=null) 
Thread.runInNew(finishTrap.function(), new JS[]{JSU.F});
+                                       return;
+                               }
+                       }
+
+                       Resources.streamToFile(localFile, 
httpStream.getInputStream());
+
+                       // set the local file's timestamp
+                       if (remoteModifiedDate > 0) {
+                               localFile.setLastModified(remoteModifiedDate);
+                       }
+
+                       Log.uInfo(Resources.class, "Done downloading to file " 
+ localFile.getAbsolutePath());
+                       cache = new File(localFile.getAbsolutePath());
+                       if(finishTrap!=null) 
Thread.runInNew(finishTrap.function(), new JS[]{JSU.T});
+               }catch(JSExn e){
+                       throw new IOException(e);
+               }
+       }
+
+       public void addTrap(JS key, JS f) throws JSExn {
+               //FEATURE - worthwhile optimisation or not?
+               //String s = JSU.toString(key);
+               //if(s.equals("Downloading") || s.equals("Progress")) 
watch=true;
+               super.addTrap(key, f);
+       }
+
+        private static final String[] datefmts = {
+            "EEE, dd MMM yyyy HH:mm:ss zzz", 
+            "EEEE, dd-MMM-yy HH:mm:ss zzz", 
+            "EEE MMM d HH:mm:ss yyyy"
+        };
+       static private long parseDate(String remoteModified){
+               if (remoteModified!=null && !remoteModified.equals("")) {
+                       // Try parsing the date using each of the date formats 
specified in RFC2616
+                       DateFormat dfmt;
+                       Date dt = null;
+                       for (int i=0; dt==null && i<datefmts.length; i++) {
+                               dfmt = new SimpleDateFormat(datefmts[i]);
+                               try { dt = dfmt.parse(remoteModified); } catch 
(ParseException e) { dt = null; }
+                       }
+                       if (dt!=null) return dt.getTime();
+                       //unable to parse remote date, so it will be ignored 
+               }
+               return 0; 
+       }
     }
+    
+    final static int BUFFER_SIZE = 1024;
+    static void streamToFile(java.io.File localFile, InputStream is ) throws 
IOException{
+       byte[] buffer = new byte[BUFFER_SIZE];
+       FileOutputStream fos = new FileOutputStream(localFile);
+       int len;
+       while ((len=is.read(buffer, 0, buffer.length)) >= 0) {
+               fos.write(buffer, 0, len);
+       }
+       fos.close();
+       is.close();
+    }
+    
 
-    /*
-    public static class Stream extends JS.Immutable{
-       
-       public JS get(JS key) throws JSExn {
-               String keyStr = JSU.toString(key);
-               // TODO preprocess...
-               if("".equals(keyStr)){
-               
-               return super.get(key);
-       }
-       
-    }*/
     public static JS parseUTF8(JS[] args) throws JSExn {
        if(args == null) return null;
        try {
@@ -450,7 +471,6 @@
        return null;
     }
 
-
        public static void writeUTF8(JS[] args) throws JSExn {
                try{
                        OutputStream out = Fountain.getOutputStream(args[0]);
@@ -484,7 +504,8 @@
                                        String key = JSU.toString(arg);
                                        if(key.equals("startElement") || 
                                           key.equals("endElement") ||
-                                          key.equals("characters"))
+                                          key.equals("characters") ||
+                                          key.equals("close"))
                                                return METHOD;
                                        return super.get(arg);
                                }
@@ -519,7 +540,10 @@
                                                String chars = 
JSU.toString(args[0]);
                                                out.write(chars);
                                                return null;
-                                       }       
+                                       }else if(key.equals("close")){  
+                                               out.close();
+                                               return null;
+                                       }
                                        }catch(IOException e){
                                                throw new JSExn(e.getMessage());
                                        }
@@ -530,9 +554,7 @@
                }catch(IOException e){
                        throw new JSExn(e.getMessage());
                }
-                
        }
-               
        
     
     static private class XMLHelper extends XML {
@@ -620,6 +642,71 @@
             }
         }
     }
+    
+    
+    static final File FONTDIR = new File(getTempDir() + "/fonts");
+    static{
+       FONTDIR.mkdirs();
+    }
+    ////////
+    // FONT STUFF
 
-  
+    static public void installFont(JS stream) throws JSExn{
+       try {
+               // FEATURE - verify (signed vexi files)
+               // FEATURE - version (install if a later version)
+               // FEATURE - don't cache remote archive somehow -
+               // though may not be possible if we want to do versioning
+
+               Log.warn(Resources.class, "Installing fonts without 
verification");
+
+               Keys ks = stream.keys();
+               
+               Enumeration E = ks.iterator();
+               while(E.hasNext()){
+                       JS key =  E.next();
+                       Fountain f = (Fountain) stream.get(key);
+                       // Find out font name from .ttf
+                       InputStream is = f.getInputStream();
+                       Font font = Font.createFont(Font.TRUETYPE_FONT, is);
+                       String filename = font.getName();
+                       is.close();
+                       // Copy .ttf to font directory
+                       is = f.getInputStream();
+                       streamToFile(new File(FONTDIR,filename+".ttf"), is);
+                       Log.warn(Resources.class, "Installing font " + 
filename);
+               }
+       } catch (Exception e) {
+               Log.error(Resources.class, e);
+               throw new JSExn("Error installing font");
+               }
+    }
+       
+    static JS installedFonts = new JS.Immutable() {
+               public JS get(JS key) throws JSExn {
+                       String s = JSU.toString(key);
+                       // FEATURE true type collections (.ttc)
+                       File f = new File(FONTDIR, s + ".ttf");
+                       if(f.exists()){
+                               return new Fountain.File(f.getPath());
+                       }
+                       return null;
+               }
+               public Keys keys() throws JSExn {
+                       return new Keys(installedFonts){
+                               protected JS contains(JS key) throws JSExn {
+                                       return 
JSU.B(installedFonts.get(key)!=null);
+                               }
+                               public Enumeration iterator() throws JSExn {
+                                       return new Enumeration(null) {
+                                               String[] files = FONTDIR.list();
+                                   private int n = 0;
+                                   public boolean _hasNext() { return n < 
files.length; }
+                                   public JS _next() { return 
JSU.S(files[n++]); }
+                               };
+                               }
+                               protected JS size() throws JSExn {return 
JSU.N((FONTDIR.listFiles().length));}
+                       };
+               }
+       };
 }

Modified: trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp 2007-09-27 15:32:42 UTC 
(rev 2343)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp 2007-09-27 15:46:56 UTC 
(rev 2344)
@@ -113,7 +113,6 @@
            case "stream": return getSub(name);
            case "stream.homedir": return Resources.fountainForName("file:" + 
System.getProperty("user.home"));
            case "stream.tempdir": return Resources.fountainForName("file:" + 
System.getProperty("java.io.tempdir"));
-           case "stream.watch": return METHOD;
            case "stream.unzip": return METHOD;
            case "stream.uncab": return METHOD;
            case "stream.cache": return METHOD;
@@ -131,6 +130,8 @@
            case "thread.sleep": return METHOD;
            case "ui": return getSub(name);
         case "ui.font": return getSub(name);
+        case "ui.font.install": return METHOD;
+        case "ui.font.installed": return Resources.installedFonts;
         case "ui.font.wait": return METHOD;
         case "ui.font.width": return METHOD;
         case "ui.font.height": return METHOD;
@@ -236,7 +237,8 @@
                        case "stream.parse.utf8": return 
Resources.parseUTF8(args);
                        case "thread.sleep": JSU.sleep(JSU.toInt(args[0])); 
return null;
                        case "ui.browser": 
Platform.newBrowserWindow(JSU.toString(args[0])); return null;
-                    case "ui.insets":
+                       case "ui.font.install": Resources.installFont(args[0]); 
return null;
+                       case "ui.insets":
                         if(args[0] == null) throw new JSExn("can't discern 
insets for a null frame");
                         Box b = null;
                         try{ b = (Box)args[0]; }
@@ -256,15 +258,6 @@
                     //#switch(JSU.toString(method))
                        case "regexp": return new JSRegexp(args[0], args[1]);
                        case "stream.parse.xml": Resources.parseXML(args); 
return null;
-                    case "stream.watch":
-                        final JS func = args[1];
-                        return new Fountain.ProgressWatcher((Fountain)args[0],
-                                                            new Callable() {
-                                                                public Object 
run(Object o) throws Exception {
-                                                                    JS[] args 
= (JS[])o;
-                                                                    return 
func.call(null, args);
-                                                                }
-                                                            });
                     case "stream.write.utf8": Resources.writeUTF8(args); 
return null;
                     //#end
                 case 3:

Modified: trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java 
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java 
2007-09-27 15:46:56 UTC (rev 2344)
@@ -1,7 +1,9 @@
 package org.vexi.core;
 
+import java.awt.Font;
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
@@ -11,6 +13,7 @@
 import junit.framework.TestSuite;
 
 import org.ibex.js.Fountain;
+import org.ibex.js.JS;
 import org.ibex.js.JSU;
 
 import test.Util;
@@ -22,7 +25,7 @@
        public static void main(String[] args) throws Exception {
                //new Local().testLocalInJarB();
                Remote r = new Remote();
-               r.setUp();      r.testDownload(); r.tearDown();
+               r.setUp();      r.testInstallFont(); r.tearDown();
        }
        
        static public Test suite() {
@@ -80,8 +83,11 @@
        }
 
        static public class Remote extends TestCase{
+               static final int PORT=7070; 
+               static final int RATE=Integer.MAX_VALUE; // no throttling  
+               
                static NanoHTTPD server = null;
-               static final String URL = "http://localhost:"; + NanoHTTPD.PORT 
+ "/"; 
+               static final String URL = "http://localhost:"; + PORT + "/"; 
                
                static public boolean deleteDirectory(File path) {
                        if( path.exists() ) {
@@ -99,7 +105,7 @@
                }
                
                protected void setUp() throws Exception {
-                       NanoHTTPD.start();
+                       NanoHTTPD.start(PORT,RATE);
                        // Set user.home and VEXIDIR_NAME to control
                        // where the temp dir is put
                        System.setProperty("user.home", ".");
@@ -126,6 +132,19 @@
                        System.out.println("HI");
                }
                
+               public void testInstallFont() throws Exception{
+                       // TODO delete cache
+                       File installed = new File(Resources.FONTDIR,"Bitstream 
Vera Sans.ttf");
+                       if(installed.exists() && !installed.delete()) fail();
+                       Fountain f = Resources.cacheableForName(URL + 
"VeraSans.vexi");
+                       JS fontJS = 
Resources.installedFonts.get(JSU.S("Bitstream Vera Sans"));
+                       assertNull(fontJS);
+                       Resources.installFont(f);
+                       assertTrue(installed.exists());
+                       fontJS = Resources.installedFonts.get(JSU.S("Bitstream 
Vera Sans"));
+                       assertNotNull(fontJS);
+               }
+               
        }
        
 

Modified: 
trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java     
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java     
2007-09-27 15:46:56 UTC (rev 2344)
@@ -39,7 +39,7 @@
        return new CoreTestCase(resourceDirs, fileName){
                protected void setUp() throws Exception {
                        createDotVexi(new 
File(NanoHTTPD.class.getResource(".").getPath()));
-               NanoHTTPD.start();
+               NanoHTTPD.start(7070,Integer.MAX_VALUE);
                }
                
                protected void tearDown() throws Exception {

Modified: trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java 
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java 
2007-09-27 15:46:56 UTC (rev 2344)
@@ -74,6 +74,7 @@
                                        File save_ = new 
File(tmpDir,"save.txt");
                                        TestCase.assertTrue(!save_.exists() || 
save_.delete());
                                        Fountain.File save = new 
Fountain.File(save_.getPath(),true);
+                                       //save.remove();
                                        Thread.beforeNonJS();
                                        try{
                                                JS function = Util.getStatic(v, 
main, "runtest");

Modified: trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t
===================================================================
--- trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t       
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t       
2007-09-27 15:46:56 UTC (rev 2344)
@@ -1,11 +1,12 @@
 <vexi xmlns:ui="vexi://ui" xmlns="">
        
+       static.ret = null;
        static.hasException = function(f /*...*/){
                var exn = false;
            try{
                switch(arguments.length-1){
-               case 1: f(arguments[1]); break;
-               case 2: f(arguments[1], arguments[2]); break;
+               case 1: ret=f(arguments[1]); break;
+               case 2: ret=f(arguments[1], arguments[2]); break;
                }
            }catch(e){ vexi.log.info(e);exn = true;}
            return exn;
@@ -24,9 +25,10 @@
            assertBadArgs(vexi.stream.parse.xml,null, {});
            assertBadArgs(vexi.stream.parse.xml,stream);
            assertBadArgs(vexi.stream.parse.xml,stream, null);
+           assertBadArgs(vexi.stream.write.xml,{});
            assertGoodArgs(vexi.stream.parse.xml,stream, {});
-           assertBadArgs(vexi.stream.write.xml,{});
            assertGoodArgs(vexi.stream.write.xml,stream);
+           ret.close(); // as we opened a stream we need to make sure its 
closed
     };
     
     <ui:box/>

Modified: trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java    
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java    
2007-09-27 15:46:56 UTC (rev 2344)
@@ -1,15 +1,34 @@
 package testdeployment;
 
-import java.io.*;
-import java.util.*;
-import java.net.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
 
 import org.ibex.util.Log;
 
-import test.core.download.TestDownload;
-
 /**
- * MODIFIED - slightly, to suit test purposes (mikeg).
+ * MODIFIED - slightly
+ * 1) to suit test purposes (mikeg).
+ * 2) added basic bandwidth throttling.           
  * 
  * 
  * A simple, tiny, nicely embeddable HTTP 1.0 server in Java
@@ -50,14 +69,20 @@
  */
 public class NanoHTTPD
 {
-       //static int logLevel = Log.INFO;
+       public final int PORT;
+    private final int MAX_BYTES_PER_SECOND;
        
-       static public int PORT = 7070;
+       private static boolean log = true;
        private static NanoHTTPD singleton;
        
+
+       
        static public void start() throws Exception{
-               if(singleton==null) singleton = new NanoHTTPD(PORT);
+               start(7070,Integer.MAX_VALUE);
        }
+       static public void start(int port, int rate) throws Exception{
+               if(singleton==null) singleton = new NanoHTTPD(port,rate);
+       }
        
        static public void stop() throws IOException{
                if(singleton!=null){
@@ -109,7 +134,7 @@
                
                if(myFileDir==null) myFileDir = new File("."); 
                
-               return serveFile( uri, header, myFileDir, true );
+               return serveFile( uri, method, header, myFileDir, true );
        }
 
        /**
@@ -207,8 +232,10 @@
         * Throws an IOException if the socket is already in use
         * @throws InterruptedException 
         */
-       public NanoHTTPD( int port ) throws IOException, InterruptedException
-       {
+       public NanoHTTPD(int port, int rate) throws IOException, 
InterruptedException
+       {       
+               PORT = port;
+               MAX_BYTES_PER_SECOND = rate;
                myFileDir = new 
File(NanoHTTPD.class.getResource(".").getPath());;
                myTcpPort = port;
 
@@ -237,7 +264,7 @@
                                        {
                                                ioe.printStackTrace();
                                        }
-                                       System.out.println("NanoHTTPD, finished 
serving");
+                                       Log.warn(NanoHTTPD.class, "finished 
serving");
                                }
                        });
                myThread.setDaemon( true );
@@ -262,7 +289,7 @@
                }
 
                // Change port if requested
-               int port = 80;
+               int port = 7070;
                if ( args.length > 0 && lopt != 0 )
                        port = Integer.parseInt( args[0] );
 
@@ -273,7 +300,7 @@
                NanoHTTPD nh = null;
                try
                {
-                       nh = new NanoHTTPD( port );
+                       nh = new NanoHTTPD( port, 600);
                }
                catch( Exception ioe )
                {
@@ -553,7 +580,7 @@
         * Serves file from homeDir and its' subdirectories (only).
         * Uses only URI, ignores all headers and HTTP parameters.
         */
-       public Response serveFile( String uri, Properties header, File homeDir,
+       public Response serveFile( String uri, String method, Properties 
header, File homeDir,
                                                           boolean 
allowDirectoryListing )
        {
                // Make sure we won't die of an exception later
@@ -677,13 +704,18 @@
                                        catch ( NumberFormatException nfe ) {}
                                }
                        }
-
-                       FileInputStream fis = new FileInputStream( f );
-                       fis.skip( startFrom );
-                       Response r = new Response( HTTP_OK, mime, fis );
+                       InputStream is = null;
+                       if("HEAD".equals(method)){
+                               is = new ByteArrayInputStream(new byte[]{});
+                       }else{
+                               is = new FileInputStream( f );
+                               is.skip( startFrom );
+                       }
+                       Response r = new Response( HTTP_OK, mime, is );
                        r.addHeader( "Content-length", "" + (f.length() - 
startFrom));
                        r.addHeader( "Content-range", "" + startFrom + "-" +
                                                (f.length()-1) + "/" + 
f.length());
+                       r.addHeader( "last-modified", 
""+formatDate(f.lastModified()));
                        return r;
                }
                catch( IOException ioe )
@@ -692,6 +724,11 @@
                }
        }
 
+       private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE, 
dd MMM yyyy HH:mm:ss zzz");
+       private static String formatDate(long t){
+               return sdf.format(new Date(t));
+       }
+       
        /**
         * Hashtable mapping (String)FILENAME_EXTENSION -> (String)MIME_TYPE
         */

Added: trunk/core/org.vexi.core/src_junit/testdeployment/VeraSans.vexi
===================================================================
(Binary files differ)


Property changes on: 
trunk/core/org.vexi.core/src_junit/testdeployment/VeraSans.vexi
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn

Reply via email to