Print

Print


Commit in GeomConverter on MAIN
src/org/lcsim/geometry/compact/converter/lcdd/Main.java+3-51.10 -> 1.11
src/org/lcsim/material/XMLMaterialManager.java+63-1041.5 -> 1.6
test/org/lcsim/geometry/compact/converter/lcdd/ConvertTest.java+3-111.5 -> 1.6
test/org/lcsim/material/test.xml+198added 1.1
                       /XMLMaterialManagerTest.java+3-51.1 -> 1.2
src/org/lcsim/util/cache/ByteFormat.java+71added 1.1
                        /CachingEntityResolver.java+37added 1.1
                        /FileCache.java+201added 1.1
+579-125
4 added + 4 modified, total 8 files
Fix GC-30
Test cases now run without needing network access

GeomConverter/src/org/lcsim/geometry/compact/converter/lcdd
Main.java 1.10 -> 1.11
diff -u -r1.10 -r1.11
--- Main.java	27 Jun 2005 21:57:35 -0000	1.10
+++ Main.java	28 Jun 2005 21:34:53 -0000	1.11
@@ -17,6 +17,7 @@
 import org.lcsim.geometry.compact.Detector;
 import org.lcsim.geometry.compact.CompactReader;
 import org.lcsim.geometry.compact.converter.Converter;
+import org.lcsim.util.cache.CachingEntityResolver;
 
 /**
  *
@@ -58,7 +59,8 @@
          outputter.output(doc,stream);
          stream.close();
          
-         SAXBuilder builder = createValidationBuilder();
+         SAXBuilder builder = new SAXBuilder();
+         builder.setEntityResolver(new CachingEntityResolver());
          builder.setValidation(true);
          builder.setFeature("http://apache.org/xml/features/validation/schema",true);
          builder.build(new ByteArrayInputStream(stream.toByteArray()));
@@ -70,10 +72,6 @@
          out.close();
       }
    }
-   SAXBuilder createValidationBuilder()
-   {
-      return new SAXBuilder();
-   }
    private static void usage()
    {
       System.out.println("java "+Main.class.getName()+" <compact> [<lcdd>]");

GeomConverter/src/org/lcsim/material
XMLMaterialManager.java 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- XMLMaterialManager.java	14 Jun 2005 18:10:37 -0000	1.5
+++ XMLMaterialManager.java	28 Jun 2005 21:34:54 -0000	1.6
@@ -1,9 +1,3 @@
-/*
- * XMLMaterialManager.java
- *
- * Created on June 6, 2005, 2:13 PM
- */
-
 package org.lcsim.material;
 
 import java.io.IOException;
@@ -29,18 +23,19 @@
  * from a GDML, LCDD or Compact XML file.
  *
  * TODO: Return implementation classes for Material and Element rather than
+ * TODO: Seems like an excessive number of methods are public
  * just XML elements.
  */
 public class XMLMaterialManager
 {
     /** Location of elements resource. */
-    public static final String elementResource = "/org/lcsim/material/elements.xml";
+    private static final String elementResource = "elements.xml";
     
     /** Location of materials resource. */
-    public static final String materialResource = "/org/lcsim/material/materials.xml";
+    private static final String materialResource = "materials.xml";
     
     /** Default fill material. */
-    public static final String defaultMaterialName = "Air";
+    private static final String defaultMaterialName = "Air";
     
     /** Static instance containing elements data. */
     static private XMLMaterialManager elements = new XMLMaterialManager(true);
@@ -90,12 +85,11 @@
         {
             try
             {
-                materials.loadFromResource(materialResource);
+                materials.loadFromStream(XMLMaterialManager.class.getResourceAsStream((materialResource)));
             }
             catch (Exception e)
             {
-                e.printStackTrace();
-                throw new RuntimeException(e.getMessage());
+                throw new RuntimeException("Error loading materials", e);
             }
         }
         else
@@ -104,10 +98,25 @@
         }
     }
     
+    /** Create a material manager that has elements as parent with additional materials from InputStream. */
+    public static XMLMaterialManager create(InputStream in) throws IOException
+    {
+       try
+       {
+           return new XMLMaterialManager(elements, in);
+       }
+       catch (JDOMException x)
+       {
+           IOException io = new IOException("Error parsing materials definitions");
+           io.initCause(x);
+           throw io;
+       }
+    }
+    
     /** Create a material manager that has elements as parent with additional materials from URL. */
-    public static XMLMaterialManager create(String url)
+    public static XMLMaterialManager create(URL url) throws IOException
     {
-        return new XMLMaterialManager(elements, url);
+        return create(url.openStream());
     }
     
     /** Create a material manager that has elements as parent with no initial material data. */
@@ -134,13 +143,12 @@
         }
     }
     
-    /** Ctor for XMLMaterialFactory with given parent and data from url. */
-    private XMLMaterialManager(XMLMaterialManager p, String url)
+    private XMLMaterialManager(XMLMaterialManager p, InputStream in) throws JDOMException, IOException
     {
         parent = p;
         createMaps();
-        loadFromURL(url);
-    }
+        loadFromStream(in);       
+    } 
     
     /** Ctor for XMLMaterialFactory with given parent and no initial material data. */
     private XMLMaterialManager(XMLMaterialManager p)
@@ -189,13 +197,13 @@
     /** Is the argument an element of type material? */
     public boolean isMaterial(Element e)
     {
-        return e.getName() == "material";
+        return "material".equals(e.getName());
     }
     
     /** Is the argument an element of type element? [sic] */
     public boolean isElement(Element e)
     {
-        return e.getName() == "element";
+        return "element".equals(e.getName());
     }
     
     /** Return size of the material map. */
@@ -399,101 +407,56 @@
         return findElementInDocument(matName);
     }
     
-    /* Load all materials and elements from a URL. */
-    public void loadFromURL(String url)
-    {
-        try
-        {
-            URL u = new URL(url);
-            loadFromStream(u.openStream());
-        }
-        catch (java.lang.Exception e)
-        {
-            e.printStackTrace();
-            throw new RuntimeException(e.getMessage());
-        }
-    }
-    
     /* Load all materials and elements from an InputStream. */
-    public void loadFromStream(InputStream in) throws JDOMException, IOException
+    private void loadFromStream(InputStream in) throws JDOMException, IOException
     {
         setCurrentDocument(makeDocument(in) );
         loadFromDocument();
     }
     
-    public void loadFromResource(String res) throws IOException, JDOMException
-    {
-        loadFromStream(this.getClass().getResourceAsStream(res) );
-    }
-    
-    public Document makeDocument(String url) throws MalformedURLException, IOException, JDOMException
-    {
-        URL u = new URL(url);
-        InputStream in = u.openStream();
-        Document d = makeDocument(in);
-        return d;
-    }
-    
-    public Document makeDocument(InputStream in) throws JDOMException, IOException
+    private Document makeDocument(InputStream in) throws JDOMException, IOException
     {
         SAXBuilder builder = new SAXBuilder();
         return builder.build(in);
     }
     
     /** Load all materials and elements from the current document. */
-    public void loadFromDocument()
+    public void loadFromDocument() throws JDOMException
     {
         loadFromDocument(currentDoc);
     }
     
     /** Core method for loading material and element XML data from an external entity. */
-    public void loadFromDocument(Document d)
+    public void loadFromDocument(Document d) throws JDOMException
     {
-        Element root;
-        try
-        {
-            root = getMaterialsRoot(d);
-        }
-        catch (JDOMException jde)
-        {
-            throw new RuntimeException("Document has no materials root: " + d.getBaseURI() );
-        }
+        Element root = getMaterialsRoot(d);
         
         /* DEBUG: track number of materials and elements read. */
         //int mcount, ecount;
         //mcount = ecount = 0;
         
-        for ( Object o : root.getChildren() )
-        {
-            Element e = (Element) o;
-            
-            try
+        for ( Element e : (List<Element>) root.getChildren() )
+        {   
+            String elemName = e.getName();
+            if ("material".equals(elemName))
             {
-                String elemName = e.getName();
-                if ( elemName == "material")
-                {
-                    addMaterial(e);
-                    
-                    /* DEBUG: print materials read and track count. */
-                    //System.out.println("read material: " + e.getAttributeValue("name") );
-                    //++ecount;
-                }
-                else if ( elemName == "element")
-                {
-                    addElement(e);
-                    
-                    /* DEBUG: print elements read and track count. */
-                    //System.out.println("read element: " + e.getAttributeValue("name") );
-                    //++mcount;
-                }
-                else
-                {
-                    System.err.println("WARNING - Unknown tag in materials block: " + elemName);
-                }
+                addMaterial(e);
+
+              /* DEBUG: print materials read and track count. */
+              //System.out.println("read material: " + e.getAttributeValue("name") );
+              //++ecount;
             }
-            catch (JDOMException jde)
+            else if ("element".equals(elemName))
             {
-                throw new RuntimeException(jde.getMessage());
+                addElement(e);
+
+                /* DEBUG: print elements read and track count. */
+                //System.out.println("read element: " + e.getAttributeValue("name") );
+                //++mcount;
+            }
+            else
+            {
+                System.err.println("WARNING - Unknown tag in materials block: " + elemName);
             }
         }
         //if ( mcount == 0 && ecount == 0)
@@ -515,23 +478,22 @@
     {
         if ( e != null )
         {
-            if ( e.getName() == "material" )
+            if ( "material".equals(e.getName()))
             {
                 List l = e.getChildren("composite");
                 
-                if ( l.size() == 0 )
+                if ( l.isEmpty() )
                 {
                     l = e.getChildren("fraction");
                 }
                 
-                if ( l.size() == 0 )
+                if ( l.isEmpty() )
                 {
                     throw new JDOMException("Material does not contain fraction or composite tags.");
                 }
                 
-                for ( Object o : l )
+                for ( Element ce : (List<Element>) l )
                 {
-                    Element ce = (Element) o;
                     
                     String ref = ce.getAttributeValue("ref");
                     
@@ -586,24 +548,22 @@
         
         Element m = getMaterial(matName);
         
-        if ( m.getName() == "material" )
+        if ( "material".equals(m.getName()))
         {
             List l = m.getChildren("composite");
             
-            if ( l.size() == 0 )
+            if ( l.isEmpty() )
             {
                 l = m.getChildren("fraction");
             }
             
-            if ( l.size() == 0 )
+            if ( l.isEmpty() )
             {
                 throw new JDOMException("Material does not contain fraction or composite tags.");
             }
             
-            for ( Object o : l )
+            for ( Element ce : (List<Element>) l )
             {
-                Element ce = (Element) o;
-                
                 String ref = ce.getAttributeValue("ref");
                 
                 /* Add if element. */
@@ -731,7 +691,7 @@
         {
             Element e = (Element) o;
             /* material */
-            if ( e.getName().equals("material") )
+            if ( "material".equals(e.getName()) )
             {
                 Material m = makeLCDDMaterial(e);
                 //System.out.println("LCDD -> " + m.getAttributeValue("name"));
@@ -813,12 +773,11 @@
         {
             try
             {
-                loadFromResource(elementResource);
+                loadFromStream(XMLMaterialManager.class.getResourceAsStream(elementResource));
             }
             catch (Exception e)
             {
-                e.printStackTrace();
-                throw new RuntimeException(e.getMessage());
+                throw new RuntimeException("Error loading elements",e);
             }
         }
         else

GeomConverter/test/org/lcsim/geometry/compact/converter/lcdd
ConvertTest.java 1.5 -> 1.6
diff -u -r1.5 -r1.6
--- ConvertTest.java	27 Jun 2005 21:57:36 -0000	1.5
+++ ConvertTest.java	28 Jun 2005 21:34:55 -0000	1.6
@@ -1,14 +1,7 @@
 package org.lcsim.geometry.compact.converter.lcdd;
-
 import junit.framework.*;
-import java.io.IOException;
 import java.io.InputStream;
-import org.jdom.JDOMException;
-import org.jdom.input.SAXBuilder;
-import org.lcsim.geometry.compact.ElementFactory.ElementCreationException;
-import org.xml.sax.EntityResolver;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
+
 
 /**
  *
@@ -16,7 +9,6 @@
  */
 public class ConvertTest extends TestCase
 {
-   
    public ConvertTest(String testName)
    {
       super(testName);
@@ -33,6 +25,6 @@
    public void testMain() throws Exception
    {
       InputStream in = ConvertTest.class.getResourceAsStream("/org/lcsim/geometry/compact/sdjan03_compact.xml");
-      new Main(true).convert("sdjan03",in, null);      
-   }  
+      new Main(true).convert("sdjan03",in,null);
+   }
 }
\ No newline at end of file

GeomConverter/test/org/lcsim/material
test.xml added at 1.1
diff -N test.xml
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ test.xml	28 Jun 2005 21:34:55 -0000	1.1
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<materials>
+
+      <!-- elements -->
+      <element name="Aluminum_e" formula="Al" Z="13.0">
+	<atom type="A" unit="g/mole" value="26.98" />
+      </element>
+
+      <element name="Argon_e" Z="18.0" N="40" >
+	<atom type="A" unit="g/mol" value="39.9480" />
+      </element>
+
+      <element name="Beryllium_e" formula="Be" Z="4.0">
+	<atom type="A" unit="g/mol" value="9.012182" />
+      </element>
+
+      <element name="Bromine_e" formula="Br" Z="35.">
+	<atom value="79.905"/>
+      </element>
+
+      <element name="Boron_e" formula="B" Z="5.">
+	<atom value="10.811"/>
+      </element>
+      
+      <element name="Carbon_e" formula="C" Z="6.">
+	<atom value="12.01" />
+      </element>
+      
+      <element name="Fluorine_e" formula="F" Z="9.">
+	<atom value="18.998" />
+      </element>    
+
+      <element name="Chlorine_e" formula="Cl" Z="17.">
+	<atom value="35.45" />
+      </element>
+
+      <element name="Hydrogen_e" formula="H" Z="1.">
+	<atom value="1.01" />
+      </element>
+
+      <element name="Iron_e" formula="Fe" Z="26.">
+	<atom value="55.85" />
+      </element>
+
+      <element  name="Nitrogen_e"  Z="7.0"  N="14" >
+	<atom type="A" unit="g/mol" value=" 14.0100" />
+      </element>
+
+      <element  name="Oxygen_e"  Z="8.0"  N="16" >
+	<atom type="A" unit="g/mol" value=" 16.0000" />
+      </element>
+
+      <element name="Silicon_e" formula="Si" Z="14.">
+	<atom value="28.09" />
+      </element>
+
+      <element name="Sodium_e" formula="Na" Z="11.">
+	<atom value="22.989770" />
+      </element>
+      
+      <element name="Tungsten_e" formula="W" Z="74.">
+	<atom value="183.84" />
+      </element>
+
+      <element name="Titanium_e" formula="Ti" Z="22.">
+	<atom value="47.867" />
+      </element>
+
+      <!-- materials -->
+      <material  name="Air"  >
+	<D type="density" unit="g/cm3" value="0.0012"/>
+	<fraction n="0.7803"  ref="Nitrogen_e"/>
+	<fraction n="0.2103"  ref="Oxygen_e"/>
+	<fraction n="0.0094"  ref="Argon_e"/>
+      </material>
+
+      <material name="Aluminum">
+	<D type="density" unit="g/cm3" value="2.70" />
+	<composite n="1" ref="Aluminum_e" />
+      </material>
+
+      <material name="Beryllium">
+	<D type="density" unit="g/cm3" value="1.848" />
+	<composite n="1" ref="Beryllium_e" />
+      </material>
+
+      <material name="Epoxy">
+	<D type="density" value="1.3" unit="g/cm3"/>
+	<composite n="44" ref="Hydrogen_e"/>
+	<composite n="15" ref="Carbon_e"/>
+	<composite n="7" ref="Oxygen_e"/>
+      </material>
+
+      <material name="Quartz">
+	<D type="density" value="2.2" unit="g/cm3"/>
+	<composite n="1" ref="Silicon_e"/>
+	<composite n="2" ref="Oxygen_e"/>
+      </material>
+
+      <material name="G10">
+	<D type="density" value="1.7" unit="g/cm3" />
+	<fraction n="0.08" ref="Chlorine_e" />
+	<fraction n="0.773" ref="Quartz" />
+	<fraction n="0.147" ref="Epoxy" />
+      </material>
+
+      <material name="Iron">
+	<D type="density" value="7.87" unit="g/cm3" />
+	<composite n="1" ref="Iron_e" />
+      </material>
+
+      <material name="Polystyrene">
+	<D value="1.032" unit="g/cm3" />
+	<composite n="19" ref="Carbon_e"/>
+	<composite n="21" ref="Hydrogen_e" />
+      </material>
+
+      <material name="Silicon">
+	<D type="density" value="2.33" unit="g/cm3" />
+	<composite n="1" ref="Silicon_e" />
+      </material>
+
+      <material name="Tungsten">
+	<D type="density" value="19.3" unit="g/cm3"/>
+	<composite n="1" ref="Tungsten_e" />
+      </material>
+
+      <material name="Titanium">
+	<D type="density" value="4.5" unit="g/cm3"/>
+	<composite n="1" ref="Titanium_e" />
+      </material>
+      
+     <material name="Steel235">
+	<D value="7.85" unit="g/cm3" />
+	<fraction n="0.998" ref="Iron_e" />
+	<fraction n=".002" ref="Carbon_e" />
+      </material>
+     
+      <material name="SiliconOxide">
+      <D type="density" value="2.65" unit="g/cm3"/>
+	<composite n="1" ref="Silicon_e" />
+        <composite n="2" ref="Oxygen_e" />
+      </material>
+      
+      <material name="BoronOxide">
+      <D type="density" value="2.46" unit="g/cm3"/>
+	<composite n="2" ref="Boron_e" />
+        <composite n="3" ref="Oxygen_e" />
+      </material>
+     
+      <material name="SodiumOxide">
+      <D type="density" value="2.65" unit="g/cm3"/>
+	<composite n="2" ref="Sodium_e" />
+        <composite n="1" ref="Oxygen_e" />
+      </material>
+      
+      <material name="AluminumOxide">
+      <D type="density" value="3.89" unit="g/cm3"/>
+	<composite n="2" ref="Aluminum_e" />
+        <composite n="3" ref="Oxygen_e" />
+      </material>
+                         
+      <material name="PyrexGlass">
+       <D type="density" value="2.23" unit="g/cm3"/>
+	<fraction n="0.806" ref="SiliconOxide" />
+	<fraction n="0.130" ref="BoronOxide" />
+        <fraction n="0.040" ref="SodiumOxide" />
+        <fraction n="0.023" ref="AluminumOxide" />        
+      </material>
+      
+      <material name="CarbonFiber">
+       <D type="density" value="1.5" unit="g/cm3"/>
+	<fraction n="0.65" ref="Carbon_e" />
+	<fraction n="0.35" ref="Epoxy" />    
+      </material>
+      
+      <material name="Rohacell31">
+       <D type="density" value="0.032" unit="g/cm3"/>
+	<composite n="9"  ref="Carbon_e" />
+	<composite n="13" ref="Hydrogen_e" />
+	<composite n="2"  ref="Oxygen_e" />
+	<composite n="1"  ref="Nitrogen_e" />
+      </material> 
+      
+      <material name="RPCGas">
+       <D type="density" value="0.0037" unit="g/cm3"/>
+	<composite n="209"  ref="Carbon_e" />
+	<composite n="239" ref="Hydrogen_e" />
+	<composite n="381"  ref="Fluorine_e" />
+      </material> 
+      
+      <material name="PolystyreneFoam">
+       <D type="density" value="0.0056" unit="g/cm3"/>
+	<fraction n="1.0"  ref="Polystyrene" />
+      </material> 
+         
+</materials>

GeomConverter/test/org/lcsim/material
XMLMaterialManagerTest.java 1.1 -> 1.2
diff -u -r1.1 -r1.2
--- XMLMaterialManagerTest.java	9 Jun 2005 03:35:33 -0000	1.1
+++ XMLMaterialManagerTest.java	28 Jun 2005 21:34:55 -0000	1.2
@@ -8,13 +8,11 @@
 
 import java.io.IOException;
 import java.net.MalformedURLException;
+import java.net.URL;
 import junit.framework.*;
 import org.jdom.Element;
-import org.jdom.Document;
 import org.jdom.JDOMException;
 
-
-
 /**
  *
  * @author jeremym
@@ -24,7 +22,7 @@
 {
     static public final String materialName = "Aluminum";
     static public final String formula = "Al";
-    public static String defURL = "http://www.slac.stanford.edu/~jeremym/test.xml";
+    public static URL defURL = XMLMaterialManagerTest.class.getResource("test.xml");
     
     public XMLMaterialManagerTest(String testName)
     {
@@ -36,7 +34,7 @@
         return new TestSuite(XMLMaterialManagerTest.class);
     }
     
-    public void test_basic() throws JDOMException
+    public void test_basic() throws JDOMException, IOException
     {
         XMLMaterialManager f = XMLMaterialManager.create(defURL);
         

GeomConverter/src/org/lcsim/util/cache
ByteFormat.java added at 1.1
diff -N ByteFormat.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ByteFormat.java	28 Jun 2005 21:34:56 -0000	1.1
@@ -0,0 +1,71 @@
+package org.lcsim.util.cache;
+
+import java.text.DecimalFormat;
+import java.text.FieldPosition;
+import java.text.Format;
+import java.text.ParsePosition;
+
+/**
+ * A formatter for formatting byte sizes. For example, formatting 12345 byes results in
+ * "12.1 kB" and 1234567 results in "1.18 MB".
+ *
+ * @author Bill Lynch
+ * @author Tony Johnson
+ */
+public class ByteFormat extends Format
+{
+   
+   private final static String[] mags = {" B"," kB"," MB"," GB"," TB"," PB"};
+   private final static DecimalFormat formatter = new DecimalFormat("#,##0.0");
+   /**
+    * Formats a long which represent a number of bytes.
+    */
+   public String format(long bytes)
+   {
+      return format(new Long(bytes));
+   }
+   
+   /**
+    * Format the given object (must be a Long).
+    *
+    * @param obj assumed to be the number of bytes as a Long.
+    * @param buf the StringBuffer to append to.
+    * @param pos
+    * @return A formatted string representing the given bytes in more human-readable form.
+    */
+   public StringBuffer format(Object obj, StringBuffer buf, FieldPosition pos)
+   {
+      if (obj instanceof Long)
+      {
+         long numBytes = ((Long)obj).longValue();
+         if (numBytes > 1024)
+         {
+            int mag = 1;
+            for (; mag<mags.length; mag++)
+            {
+               if (numBytes < 1024*1024) break;
+               numBytes /= 1024;
+            }
+            
+            buf.append(formatter.format((double)numBytes / 1024.0)).append(mags[mag]);
+         }
+         else
+         {
+            buf.append(numBytes).append(mags[0]);
+         }
+      }
+      return buf;
+   }
+   
+   /**
+    * In this implementation, returns null always.
+    *
+    * @param source
+    * @param pos
+    * @return returns null in this implementation.
+    */
+   public Object parseObject(String source, ParsePosition pos)
+   {
+      return null;
+   }
+}

GeomConverter/src/org/lcsim/util/cache
CachingEntityResolver.java added at 1.1
diff -N CachingEntityResolver.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ CachingEntityResolver.java	28 Jun 2005 21:34:56 -0000	1.1
@@ -0,0 +1,37 @@
+package org.lcsim.util.cache;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.net.URL;
+import org.xml.sax.EntityResolver;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * An entity resolver which caches schemas locally. This makes it possible to run
+ * the tests without a network connection, provided the cache has been previously
+ * seeded.
+ * @author tonyj
+ * @version $Id: CachingEntityResolver.java,v 1.1 2005/06/28 21:34:56 tonyj Exp $
+ */
+public class CachingEntityResolver implements EntityResolver
+{
+   private FileCache fileCache;
+   
+   public CachingEntityResolver() throws IOException
+   {
+      fileCache = new FileCache();
+   }
+   public CachingEntityResolver(File cacheDirectory) throws IOException
+   {
+      fileCache = new FileCache(cacheDirectory);
+   }
+   public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException
+   {
+      File file = fileCache.getCachedFile(new URL(systemId));
+      InputSource result = new InputSource(new FileInputStream(file));
+      result.setSystemId(systemId);
+      return result;
+   }
+}
\ No newline at end of file

GeomConverter/src/org/lcsim/util/cache
FileCache.java added at 1.1
diff -N FileCache.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ FileCache.java	28 Jun 2005 21:34:56 -0000	1.1
@@ -0,0 +1,201 @@
+package org.lcsim.util.cache;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+
+/**
+ * A utility for downloading and caching files
+ * @author tonyj
+ */
+public class FileCache
+{
+   private static final File home = new File(System.getProperty("user.home"),".cache");
+   private static final ByteFormat format = new ByteFormat();
+   private File cache;
+   private PrintStream print = System.out;
+   
+   /**
+    * Create a FileCache using the default cache location
+    * @throws java.io.IOException If the cache directory cannot be created
+    */
+   public FileCache() throws IOException
+   {
+      this(home);
+   }
+   
+   /**
+    * Create a file cache using an explicit cache location
+    * @param cacheDirectory The directory to use for storing cached files
+    * @throws java.io.IOException If the cache directory cannot be created
+    */
+   public FileCache(File cacheDirectory) throws IOException
+   {
+      setCacheDirectory(cacheDirectory);
+   }
+   /**
+    * Get a file from the cache. If the file is already in the cache and up-to-date the existing 
+    * file will be returned. Otherwise the file will be downloaded first, and then moved
+    * to the cache.
+    * @param url Teh URL of the file to download
+    * @throws java.io.IOException If the file cannot be downloaded, or if an error occurs writing to the cache.
+    * @return The location of the cached file
+    */
+   public File getCachedFile(URL url) throws IOException
+   {
+      return getCachedFile(url,null);
+   }
+   
+   /**
+    * Get a file from the cache. If the file is already in the cache and up-to-date the existing 
+    * file will be returned. Otherwise the file will be downloaded first, validated, and then moved
+    * to the cache.
+    * @param url Teh URL of the file to download
+    * @param validator A Validator that will be used to check the integrity of the downloaded file before it is 
+    * placed in the cache
+    * @throws java.io.IOException If the file cannot be downloaded, or if an error occurs writing to the cache, or if the file
+    * fails validation.
+    * @return The location of the cached file
+    */
+   public File getCachedFile(URL url, Validator validator) throws IOException
+   {
+      File cacheFile = new File(cache,URLEncoder.encode(url.toExternalForm(),"UTF-8"));
+      boolean downloadRequired = !cacheFile.exists();
+      if (cacheFile.exists() && !Boolean.getBoolean("org.lcsim.offline"))
+      {
+         // If we can access the URL, check if the cachefile is up-to-date
+         try
+         {
+            URLConnection connection = url.openConnection();
+            connection.setConnectTimeout(5000);
+            long updated = connection.getLastModified();
+            long cached = cacheFile.lastModified();
+            if (updated > cached) downloadRequired = true;
+         }
+         catch (IOException x)
+         {
+            // Just assume file in cache is OK.
+         }
+      }
+      if (downloadRequired)
+      {
+         URLConnection connection = url.openConnection();
+         connection.setConnectTimeout(10000);
+         long size  = connection.getContentLength();
+         InputStream in = connection.getInputStream();
+         if (in != null)
+         {
+            if (print != null) print.println("Downloading..."+url);
+            File temp = File.createTempFile("det",null,cache);
+            temp.deleteOnExit();
+            OutputStream out = new FileOutputStream(temp);
+            byte[] buffer = new byte[8096];
+            try
+            {
+               long got = 0;
+               for (;;)
+               {
+                  int l = in.read(buffer);
+                  if (l < 0) break;
+                  out.write(buffer,0,l);
+                  if (out != null) 
+                  { 
+                     got += l;
+                     print.print("Got ");
+                     print.print(format.format(got));
+                     print.print('/');
+                     print.print(format.format(size));
+                     print.print('\r');
+                     print.flush();
+                  }
+               }
+            }
+            finally
+            {
+               in.close();
+               out.close();
+            }
+            if (validator != null) validator.checkValidity(url,temp);
+            // File looks ok, move it into the cache
+            if (cacheFile.exists())
+            {
+               boolean ok = cacheFile.delete();
+               if (!ok) throw new IOException("Error while deleting old cache file");
+            }
+            boolean ok = temp.renameTo(cacheFile);
+            if (!ok) throw new IOException("Error while moving file to cache");
+         }
+         else throw new IOException("Could not open "+url);
+      }
+      return cacheFile;
+   }
+
+
+   /**
+    * Get the directory used for caching
+    * @return The cache directory
+    */
+   public File getCacheDirectory()
+   {
+      return this.cache;
+   }
+
+   /**
+    * Set a new cache directory location
+    * @param cacheDirectory The directory to use.
+    * @throws java.io.IOException If the specified directory cannot be created, or already exists and is not a directory.
+    */
+   public void setCacheDirectory(File cacheDirectory) throws IOException
+   {
+      if (!cacheDirectory.exists())
+      {
+         boolean ok = cacheDirectory.mkdirs();
+         if (!ok) throw new IOException("Unable to create: "+cacheDirectory.getAbsoluteFile());
+      }
+      else if (!cacheDirectory.isDirectory())
+      {
+         throw new IOException("Not a directory");
+      }
+      this.cache = cacheDirectory;
+   }
+
+   /**
+    * Gets the print stream used for diagnostic messages if a file is downloaded.
+    * @return The current diagnostic print stream, or <CODE>null</CODE> if none exists.
+    */
+   public PrintStream getPrintStream()
+   {
+
+      return this.print;
+   }
+
+   /**
+    * Set the print stream to be used for diagnostic messages
+    * @param printStream The print stream to use, or <CODE>null</CODE> to disable diagnostic messages
+    */
+   public void setPrintStream(PrintStream printStream)
+   {
+      this.print = printStream;
+   }
+   /**
+    * An interface to be implemented by cache validators
+    * @see #getCachedFile(URL,Validator)
+    */
+   public static interface Validator
+   {
+      /**
+       * Called after a file has been downloaded but before it is placed in the cache,
+       * This method should throw an IOException if the file fails to validate.
+       * @param url The URL being downloaded
+       * @param file The file that needs to be validated
+       * @throws java.io.IOException If validation fails
+       */
+      void checkValidity(URL url, File file) throws IOException;
+   }
+}
\ No newline at end of file
CVSspam 0.2.8