Commit in GeomConverter on MAIN | |||
src/org/lcsim/geometry/compact/converter/lcdd/Main.java | +3 | -5 | 1.10 -> 1.11 |
src/org/lcsim/material/XMLMaterialManager.java | +63 | -104 | 1.5 -> 1.6 |
test/org/lcsim/geometry/compact/converter/lcdd/ConvertTest.java | +3 | -11 | 1.5 -> 1.6 |
test/org/lcsim/material/test.xml | +198 | added 1.1 | |
/XMLMaterialManagerTest.java | +3 | -5 | 1.1 -> 1.2 |
src/org/lcsim/util/cache/ByteFormat.java | +71 | added 1.1 | |
/CachingEntityResolver.java | +37 | added 1.1 | |
/FileCache.java | +201 | added 1.1 | |
+579 | -125 |
Fix GC-30 Test cases now run without needing network access
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>]");
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
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
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>
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);
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; + } +}
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
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