19 added files
LCGO
diff -N GNUmakefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ GNUmakefile 29 Sep 2006 16:27:16 -0000 1.1
@@ -0,0 +1,68 @@
+JDOM=jdom-1.0.jar
+JEL=jel-0.9.10.jar
+XERCES=xercesImpl-2.8.0.jar
+
+WORK=/tmp/work
+DIST=/tmp/dist
+
+CLASSPATH=$(WORK)/jars/$(JDOM):$(WORK)/jars/$(JEL)
+
+.PHONY : all
+all: test
+
+$(WORK)/jars/$(JDOM):
+ mkdir -p $(WORK)/jars
+ wget -P $(WORK)/jars http://www.ibiblio.org/maven/jdom/jars/$(JDOM)
+
+$(WORK)/jars/$(JEL):
+ mkdir -p $(WORK)/jars
+ wget -P $(WORK)/jars http://java.freehep.org/maven/jel/jars/$(JEL)
+
+$(WORK)/jars/$(XERCES):
+ mkdir -p $(WORK)/jars
+ wget -P $(WORK)/jars http://www.ibiblio.org/maven/xerces/jars/$(XERCES)
+
+$(DIST)/lib/%.jar.so : $(WORK)/jars/%.jar
+ mkdir -p $(DIST)/lib
+ gcj -fPIC -findirect-dispatch -shared -o $@ $<
+
+# Not currently used
+%.jar.a : %.jar
+ gcj -c -findirect-dispatch -o $<.o $<
+ ar rcs $@ $<.o
+ rm $<.o
+
+$(DIST)/include/hep/lcgo/xml/reader/%.h: $(WORK)/jars/LCGO.jar
+ mkdir -p $(DIST)/include/hep/lcgo/xml/reader
+ gcjh --classpath=$< -d $(DIST)/include hep.lcgo.xml.reader.$*
+
+$(WORK)/jars/LCGO.jar: src/java/hep/lcgo/xml/reader/*.java src/java/hep/lcgo/xml/reader/util/*.java src/java/hep/lcgo/util/cache/*.java
+ mkdir -p $(WORK)/classes
+ gcj -d $(WORK)/classes --classpath=$(CLASSPATH) -C $^
+ fastjar -cf $@ -C $(WORK)/classes .
+
+$(WORK)/includes: src/include/* $(DIST)/include/hep/lcgo/xml/reader/LCGOReader.h $(DIST)/include/hep/lcgo/xml/reader/Detector.h $(DIST)/include/hep/lcgo/xml/reader/Constant.h
+ cp -r src/include/*.h $(DIST)/include
+ touch $@
+
+$(WORK)/dist: $(DIST)/lib/$(XERCES).so $(DIST)/lib/$(JDOM).so $(DIST)/lib/$(JEL).so $(DIST)/lib/LCGO.jar.so $(DIST)/lib/LCGO.so $(WORK)/includes
+ touch $@
+
+$(DIST)/lib/LCGO.so: src/cpp/*.cc $(WORK)/includes
+ gcj -o $@ -fPIC -shared -I$(DIST)/include src/cpp/*.cc
+
+test: test.cc $(WORK)/dist
+ g++ -o $@ -I$(DIST)/include $< $(DIST)/lib/*.so -lgcj
+
+.PHONY : run
+run: test
+ ./test
+
+
+.PHONY : clean
+clean:
+ -rm -rf $(WORK)
+ -rm -rf $(DIST)
+ -rm test
+
+
LCGO
diff -N GeometryReaderTest.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ GeometryReaderTest.xml 29 Sep 2006 16:27:16 -0000 1.1
@@ -0,0 +1,222 @@
+<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
+ xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd">
+
+ <!-- info tag containing author, version, time, unique id (url) -->
+ <info name="GeometryReaderTest">
+ <comment>
+ Test of org.lcsim.geometry.GeometryReader
+ </comment>
+ </info>
+
+ <!-- Constants -->
+ <define>
+
+ <constant name="cm" value="10"/>
+
+ <!-- world -->
+ <constant name="world_side" value="15000" />
+ <constant name="world_x" value="world_side" />
+ <constant name="world_y" value="world_side" />
+ <constant name="world_z" value="world_side" />
+
+ <!-- tracking region -->
+ <constant name="tracking_region_radius" value="127.0*cm"/>
+ <constant name="tracking_region_zmax" value="168.0*cm"/>
+
+ <constant name="vertex_inner_r" value="1.2*cm"/>
+ <constant name="vertex_delta_r" value="1.2*cm"/>
+ <constant name="vertex_outer_z" value="12.5*cm"/>
+
+ </define>
+
+ <materials>
+
+ <!-- so can easily replace references
+ with something more realistic later -->
+ <material name="MuonAir">
+ <D type="density" unit="g/cm3" value="0.0012"/>
+ <fraction n="0.7803" ref="N"/>
+ <fraction n="0.2103" ref="O"/>
+ <fraction n="0.0094" ref="Ar"/>
+ </material>
+
+ </materials>
+
+ <detectors>
+ <detector id="1" name="VertexBarrel" type="MultiLayerTracker" readout="VtxBarrHits">
+ <layer id="1" inner_r = "vertex_inner_r" outer_z = "2.5*cm">
+ <slice material = "Silicon" thickness = "0.01*cm" sensitive = "yes" />
+ </layer>
+ <layer id="2" inner_r = "vertex_inner_r + 1 * vertex_delta_r" outer_z = "vertex_outer_z">
+ <slice material = "Silicon" thickness = "0.01*cm" sensitive = "yes" />
+ </layer>
+ <layer id="3" inner_r = "vertex_inner_r + 2 * vertex_delta_r" outer_z = "vertex_outer_z">
+ <slice material = "Silicon" thickness = "0.01*cm" sensitive = "yes" />
+ </layer>
+ <layer id="4" inner_r = "vertex_inner_r + 3 * vertex_delta_r" outer_z = "vertex_outer_z" >
+ <slice material = "Silicon" thickness = "0.01*cm" sensitive = "yes" />
+ </layer>
+ <layer id="5" inner_r = "vertex_inner_r + 4 * vertex_delta_r" outer_z = "vertex_outer_z">
+ <slice material = "Silicon" thickness = "0.01*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+
+ <detector id="2" name="BarrelTracker" type="MultiLayerTracker" readout="TkrBarrHits">
+ <layer id="1" inner_r = "20.0*cm" outer_z = "26.67*cm">
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="2" inner_r = "46.25*cm" outer_z = "61.67*cm">
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="3" inner_r = "72.5*cm" outer_z = "96.67*cm">
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="4" inner_r = "98.75*cm" outer_z = "131.67*cm" >
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="5" inner_r = "125.0*cm" outer_z = "166.67*cm">
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+
+ <detector id="3" name="EndcapTracker" type="DiskTracker" reflect="true" readout="TkrEndcapHits">
+ <layer id="1" inner_r = "4.0*cm" inner_z = "27.1*cm" outer_r = "20.50*cm">
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="2" inner_r = "4.0*cm" inner_z = "27.12*cm" outer_r = "20.50*cm">
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="3" inner_r = "7.9*cm" inner_z = "62.1*cm" outer_r = "46.75*cm">
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="4" inner_r = "7.9*cm" inner_z = "62.12*cm" outer_r = "46.75*cm" >
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="5" inner_r = "11.7*cm" inner_z = "97.1*cm" outer_r = "73.0*cm" >
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="6" inner_r = "11.7*cm" inner_z = "97.12*cm" outer_r = "73.0*cm">
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="7" inner_r = "15.6*cm" inner_z = "132.1*cm" outer_r = "99.25*cm">
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="8" inner_r = "15.6*cm" inner_z = "132.12*cm" outer_r = "99.25*cm">
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="9" inner_r = "19.5*cm" inner_z = "167.1*cm" outer_r = "125.50*cm" >
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ <layer id="10" inner_r = "19.5*cm" inner_z = "167.12*cm" outer_r = "125.50*cm" >
+ <slice material = "Silicon" thickness = "0.02*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+ <detector id="4" name="EMBarrel" type="CylindricalBarrelCalorimeter" readout="EcalBarrHits">
+ <dimensions inner_r = "127.0*cm" outer_z = "184.0*cm" />
+ <layer repeat="30">
+ <slice material = "Tungsten" thickness = "0.25*cm" />
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.04*cm" sensitive = "yes" />
+ <slice material = "Copper" thickness = "0.1*cm" />
+ <slice material = "Air" thickness = "0.06*cm" />
+ </layer>
+ </detector>
+ <detector id="5" name="EMEndcap" reflect="true" type="CylindricalEndcapCalorimeter" readout="EcalEndcapHits">
+ <dimensions inner_r = "20.0*cm" inner_z = "168.0*cm" outer_r = "125.0*cm" />
+ <layer repeat="30" >
+ <slice material = "Tungsten" thickness = "0.25*cm" />
+ <slice material = "G10" thickness = "0.05*cm" />
+ <slice material = "Silicon" thickness = "0.04*cm" sensitive = "yes" />
+ <slice material = "Copper" thickness = "0.1*cm" />
+ <slice material = "Air" thickness = "0.06*cm" />
+ </layer>
+ </detector>
+ <detector id="6" name="HADBarrel" type="CylindricalBarrelCalorimeter" readout="HcalBarrHits">
+ <dimensions inner_r = "144.0*cm" outer_z = "286.0*cm" />
+ <layer repeat="34">
+ <slice material = "Steel235" thickness = "2.0*cm" />
+ <slice material = "Polystyrene" thickness = "1.0*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+ <detector id="7" name="HADEndcap" reflect="true" type="CylindricalEndcapCalorimeter" readout="HcalEndcapHits">
+ <dimensions inner_r = "20.0*cm" inner_z = "184.0*cm" outer_r = "142.0*cm" />
+ <layer repeat="34" >
+ <slice material = "Steel235" thickness = "2.0*cm" />
+ <slice material = "Polystyrene" thickness = "1.0*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+ <detector id="8" name="MuonBarrel" type="CylindricalBarrelCalorimeter" readout="MuonBarrHits" detectorType="calorimeter">
+ <dimensions inner_r = "337.0*cm" outer_z = "287.0*cm" />
+ <layer repeat="32">
+ <slice material = "Iron" thickness = "5.0*cm" />
+ <slice material = "Air" thickness = "1.5*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+ <detector id="9" name="MuonEndcap" reflect="true" type="CylindricalEndcapCalorimeter" readout="MuonEndcapHits">
+ <dimensions inner_r = "20.0*cm" inner_z = "287.0*cm" outer_r = "636.0*cm" />
+ <layer repeat="32">
+ <slice material = "Iron" thickness = "5.0*cm" />
+ <slice material = "Air" thickness = "1.5*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+ <detector id="10" name="LumEndcap" reflect="true" type="CylindricalEndcapCalorimeter" readout="LumEndcapHits">
+ <dimensions inner_r = "0.0001*cm" inner_z = "310.0*cm" outer_r = "9.2*cm" />
+ <layer repeat="1">
+ <slice material="Beryllium" thickness = "10.*cm" />
+ <slice material="Tungsten" thickness = "35.*cm" sensitive = "yes" />
+ </layer>
+ </detector>
+ </detectors>
+ <readouts>
+ <readout name="MuonBarrHits">
+ <segmentation type="ProjectiveCylinder" thetaBins="150" phiBins="300"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="MuonEndcapHits">
+ <segmentation type="ProjectiveZPlane" thetaBins="150" phiBins="300"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="LumEndcapHits">
+ <segmentation type="ProjectiveZPlane" thetaBins="600" phiBins="1200"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="HcalEndcapHits">
+ <segmentation type="ProjectiveZPlane" thetaBins="600" phiBins="1200"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="HcalBarrHits">
+ <segmentation type="ProjectiveCylinder" thetaBins="600" phiBins="1200"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="EcalEndcapHits">
+ <segmentation type="ProjectiveZPlane" thetaBins="840" phiBins="1680"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="EcalBarrHits">
+ <segmentation type="ProjectiveCylinder" thetaBins="840" phiBins="1680"/>
+ <id>layer:7,system:3,barrel:3,theta:32:11,phi:11</id>
+ </readout>
+ <readout name="TkrBarrHits">
+ <id>layer:10,system:3,barrel:3</id>
+ </readout>
+ <readout name="TkrEndcapHits">
+ <id>layer:10,system:3,barrel:3</id>
+ </readout>
+ <readout name="VtxBarrHits">
+ <id>layer:10,system:3,barrel:3</id>
+ </readout>
+ </readouts>
+ <fields>
+ <field type="Solenoid" name="GlobalSolenoid"
+ inner_field="5.0"
+ outer_field="-0.6"
+ zmax="1000"
+ outer_radius="144*cm+(2+1)*34*cm"/>
+ </fields>
+</lccdd>
LCGO
diff -N test.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ test.cc 29 Sep 2006 16:27:16 -0000 1.1
@@ -0,0 +1,17 @@
+#include <iostream>
+#include "LCGO.h"
+#include "java/util/Map.h"
+
+int main(int argc, char *argv[])
+{
+ using namespace hep::lcgo::xml::reader;
+ using namespace java::util;
+ using namespace std;
+
+ LCGO lcgo("GeometryReaderTest.xml");
+ Detector* det = lcgo.getDetector();
+ Map* constants = det->getConstants();
+
+ cout << det << endl;
+ cout << constants << endl;
+}
LCGO/src/cpp
diff -N LCGO.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LCGO.cc 29 Sep 2006 16:27:17 -0000 1.1
@@ -0,0 +1,18 @@
+#include "LCGO.h"
+
+LCGO::LCGO(char* file)
+{
+ JvCreateJavaVM(NULL);
+ JvAttachCurrentThread(NULL, NULL);
+
+ hep::lcgo::xml::reader::LCGOReader* reader = new hep::lcgo::xml::reader::LCGOReader();
+ detector = reader->read(JvNewStringLatin1(file));
+}
+hep::lcgo::xml::reader::Detector* LCGO::getDetector()
+{
+ return detector;
+}
+LCGO::~LCGO()
+{
+ JvDetachCurrentThread();
+}
LCGO/src/cpp
diff -N LCGOUtil.cc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LCGOUtil.cc 29 Sep 2006 16:27:17 -0000 1.1
@@ -0,0 +1,15 @@
+#include "LCGOUtil.h"
+
+std::ostream& operator << (std::ostream& os, const java::lang::Object* obj)
+{
+ jstring value = ((java::lang::Object*) obj)->toString();
+ int l = JvGetStringUTFLength(value);
+ char* result = (char*) JvMalloc(l+1);
+ JvGetStringUTFRegion(value,0,l,result);
+ *(result+l)='\0';
+
+ os<<result;
+
+ JvFree(result);
+ return os;
+}
LCGO/src/include
diff -N LCGO.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LCGO.h 29 Sep 2006 16:27:17 -0000 1.1
@@ -0,0 +1,22 @@
+#ifndef LCGO_INCLUDED
+#define LCGO_INCLUDED
+
+#include <gcj/cni.h>
+#include "hep/lcgo/xml/reader/LCGOReader.h"
+#include "hep/lcgo/xml/reader/Detector.h"
+#include "hep/lcgo/xml/reader/Constant.h"
+#include "LCGOUtil.h"
+
+
+
+class LCGO {
+ public:
+ LCGO(char* file);
+ ~LCGO();
+ hep::lcgo::xml::reader::Detector* getDetector();
+
+ private:
+ hep::lcgo::xml::reader::Detector* detector;
+};
+
+#endif
LCGO/src/include
diff -N LCGOUtil.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LCGOUtil.h 29 Sep 2006 16:27:17 -0000 1.1
@@ -0,0 +1,11 @@
+#ifndef LCGOUTIL_INCLUDED
+#define LCGOUTIL_INCLUDED
+
+#include <iostream>
+
+#include <gcj/cni.h>
+#include "java/lang/Object.h"
+
+std::ostream& operator << (std::ostream& os, const java::lang::Object* obj);
+
+#endif
LCGO/src/java/hep/lcgo/util/cache
diff -N ByteFormat.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ByteFormat.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,71 @@
+package hep.lcgo.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;
+ }
+}
LCGO/src/java/hep/lcgo/util/cache
diff -N FileCache.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ FileCache.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,208 @@
+package hep.lcgo.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(getCacheRoot(),".cache");
+ private static final ByteFormat format = new ByteFormat();
+ private File cache;
+ private PrintStream print = System.out;
+
+ public static File getCacheRoot()
+ {
+ String cacheDir = System.getProperty("hep.lcgo.cacheDir");
+ if (cacheDir == null) cacheDir = System.getProperty("user.home");
+ return new File(cacheDir);
+ }
+
+ /**
+ * 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("hep.lcgo.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
LCGO/src/java/hep/lcgo/xml/reader
diff -N Constant.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Constant.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,46 @@
+package hep.lcgo.xml.reader;
+
+import org.jdom.DataConversionException;
+import org.jdom.Element;
+
+/**
+ * The class created when a constant definition is found in the XML file.
+ * @author tonyj
+ * @version $Id: Constant.java,v 1.1 2006/09/29 16:27:18 tonyj Exp $
+ */
+public class Constant
+{
+ private final String name;
+ private final double value;
+ /**
+ * Construct a new Constant
+ * @param constant The JDOM element corresponding to the constant definition.
+ * @throws org.jdom.DataConversionException If an XML error occurs while handling the node.
+ */
+ protected Constant(Element constant) throws DataConversionException
+ {
+ name = constant.getAttributeValue("name");
+ value = constant.getAttribute("value").getDoubleValue();
+ }
+ /**
+ * Get the name of this constant
+ * @return The name.
+ */
+ public String getName()
+ {
+ return name;
+ }
+ /**
+ * The value of this constant (after expression evaluation).
+ * @return The value.
+ */
+ public double getValue()
+ {
+ return value;
+ }
+
+ public String toString()
+ {
+ return String.valueOf(value);
+ }
+}
LCGO/src/java/hep/lcgo/xml/reader
diff -N Detector.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Detector.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,75 @@
+package hep.lcgo.xml.reader;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.jdom.Element;
+
+/**
+ * Default class created to represent the parsed detector.
+ * @author tonyj
+ * @version $Id: Detector.java,v 1.1 2006/09/29 16:27:18 tonyj Exp $
+ */
+public class Detector
+{
+ private Header header;
+ private final Map/*<String,Constant>*/ constants = new HashMap/*<String,Constant>*/();
+
+
+ /**
+ * Called by the reader to create a new Detector
+ * @param element The JDOM element corresponding to the detector definition in the XML file.
+ */
+ protected Detector(Element element)
+ {
+
+ }
+
+ /**
+ * Called by the reader to associate a header with this detector
+ * @param header The header.
+ */
+ protected void setHeader(Header header)
+ {
+ this.header = header;
+ }
+ /**
+ * Get the header associated with this detector.
+ * @return The header
+ */
+ public Header getHeader()
+ {
+ return header;
+ }
+
+ /**
+ * Get the detector name from the header.
+ * @return the detector name
+ */
+ public String getDetectorName()
+ {
+ return getHeader().getDetectorName();
+ }
+
+ /**
+ * Called by the reader to add a constant to this detector.
+ * @param c The constant to add.
+ */
+ protected void addConstant(Constant c)
+ {
+ constants.put(c.getName(),c);
+ }
+ /**
+ * Get the constants associated with this detector.
+ * @return A map of containing all of the constants, indexed by name.
+ */
+ public Map/*<String,Constant>*/ getConstants()
+ {
+ return constants;
+ }
+
+ public String toString()
+ {
+ return "Detector: "+header.getDetectorName()+" version: "+header.getVersion();
+ }
+
+}
\ No newline at end of file
LCGO/src/java/hep/lcgo/xml/reader
diff -N Header.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Header.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,110 @@
+package hep.lcgo.xml.reader;
+
+import org.jdom.Element;
+
+/**
+ * The header of the LCGO detector description.
+ *
+ * @author tonyj
+ */
+public class Header
+{
+ private String name;
+ private String title = "NONE";
+ private String author = "NONE";
+ private String version = "NONE";
+ private String url = "NONE";
+ private String comment = "NONE";
+
+ protected Header(Element info)
+ {
+ if (info.getAttributeValue("name") != null)
+ {
+ name = info.getAttributeValue("name");
+ }
+ else
+ {
+ throw new RuntimeException("info element for this detector is missing the name attribute.");
+ }
+
+ if (info.getChild("author") != null)
+ {
+ author = info.getAttributeValue("author");
+ }
+
+ if (info.getChild("title") != null)
+ {
+ title = info.getAttributeValue("title");
+ }
+
+ if (info.getAttribute("version") != null)
+ {
+ version = info.getAttributeValue("version");
+ }
+
+ if (info.getAttribute("url") != null)
+ {
+ url = info.getAttributeValue("url");
+ }
+
+ if (info.getChild("comment") != null)
+ {
+ comment = info.getChild("comment").getTextNormalize();
+ }
+ }
+
+ /**
+ * Get the detector name.
+ *
+ * @return The name.
+ */
+ public String getDetectorName()
+ {
+ return name;
+ }
+
+ /**
+ * Get the author of this detector description.
+ *
+ * @return The author.
+ */
+ public String getAuthor()
+ {
+ return author;
+ }
+
+ /**
+ * Get the version of the detector.
+ *
+ * @return The version
+ */
+ public String getVersion()
+ {
+ return version;
+ }
+
+ /**
+ * The URL providing more information about this detector.
+ *
+ * @return The URL.
+ */
+ public String getURL()
+ {
+ return url;
+ }
+
+ /**
+ * A comment describing the detector
+ *
+ * @return The comment.
+ */
+ public String getComment()
+ {
+ return comment;
+ }
+
+ public String getTitle()
+ {
+ return title;
+ }
+}
\ No newline at end of file
LCGO/src/java/hep/lcgo/xml/reader
diff -N LCGOElementFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LCGOElementFactory.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,20 @@
+package hep.lcgo.xml.reader;
+
+import hep.lcgo.xml.reader.util.DefaultElementFactory;
+
+/**
+ *
+ * @author jeremym
+ */
+public class LCGOElementFactory extends DefaultElementFactory
+{
+
+ /** Creates a new instance of CompactElementFactory */
+ public LCGOElementFactory()
+ {
+ super();
+ register(Constant.class);
+ register(Detector.class);
+ register(Header.class);
+ }
+}
LCGO/src/java/hep/lcgo/xml/reader
diff -N LCGOReader.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ LCGOReader.java 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,117 @@
+package hep.lcgo.xml.reader;
+
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Iterator;
+import java.util.Map;
+
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import org.jdom.input.SAXBuilder;
+import hep.lcgo.xml.reader.util.CachingEntityResolver;
+import hep.lcgo.xml.reader.util.ElementFactory;
+import hep.lcgo.xml.reader.util.JDOMExpressionFactory;
+import hep.lcgo.xml.reader.util.ElementFactory.ElementCreationException;
+
+/**
+ * A tool for reading xml files containing LCGO detector descriptions.
+ *
+ * This class does not create subclass objects. For example, CylindricalBarrelCalorimeter
+ * is inserted into Detector as a generic Subdetector. To get subclasses, use the
+ * org.lcsim.geometry.GeometryReader class, which extends this.
+ *
+ * @author tonyj
+ * @version $Id: LCGOReader.java,v 1.1 2006/09/29 16:27:18 tonyj Exp $
+ *
+ */
+public class LCGOReader
+{
+ private ElementFactory factory;
+
+ /**
+ * Create a CompactReader using a DefaultElementFactory.
+ */
+ public LCGOReader()
+ {
+ this(new LCGOElementFactory());
+ }
+ /**
+ * Create a CompactReader using the specified ElementFactory.
+ * @param factory The ElementFactory to be used for creating elements as the file is parsed.
+ */
+ public LCGOReader(ElementFactory factory)
+ {
+ this.factory = factory;
+ }
+
+ public Detector read(String fileName) throws IOException, JDOMException, ElementCreationException
+ {
+ InputStream in = new FileInputStream(fileName);
+ try
+ {
+ return read(in);
+ }
+ finally
+ {
+ in.close();
+ }
+ }
+ /**
+ * Read a compact geometry XML file.
+ * @param in The input stream to read.
+ * @throws java.io.IOException If an IO error occurs while reading the stream.
+ * @throws org.jdom.JDOMException If invalid XML is found while reading the file.
+ * @throws org.lcsim.geometry.compact.ElementFactory.ElementCreationException If the ElementFactory throws an ElementCreationException.
+ * @return The parsed detector description.
+ */
+ public Detector read(InputStream in) throws IOException, JDOMException, ElementCreationException
+ {
+ JDOMExpressionFactory jdom = new JDOMExpressionFactory();
+ SAXBuilder builder = new SAXBuilder("org.apache.xerces.parsers.SAXParser");
+ builder.setFactory(jdom);
+
+ builder.setValidation(true);
+ builder.setFeature("http://apache.org/xml/features/validation/schema", true);
+
+ // Add an EntityResolver that caches to ~/.cache
+ builder.setEntityResolver(new CachingEntityResolver());
+
+ Document doc = builder.build(in);
+
+ Element lccdd = doc.getRootElement();
+ Detector det = (Detector) factory.createElement(Detector.class,lccdd,null);
+
+ readHeader(lccdd, det, jdom);
+ return det;
+ }
+
+ private void readHeader(Element lccdd, Detector det, JDOMExpressionFactory jdom) throws JDOMException, ElementCreationException
+ {
+ Element info = lccdd.getChild("info");
+ det.setHeader((Header) factory.createElement(Header.class,info,null));
+ Element define = lccdd.getChild("define");
+ for (Iterator i = define.getChildren("constant").iterator(); i.hasNext(); )
+ {
+ Element constant = (Element) i.next();
+ Constant c = (Constant) factory.createElement(Constant.class,constant,null);
+ jdom.addConstant(c.getName(),c.getValue());
+ det.addConstant(c);
+ }
+ }
+ // Fixme: Should not be here
+ public static void main(String[] args) throws FileNotFoundException, IOException, JDOMException, ElementCreationException
+ {
+ LCGOReader reader = new LCGOReader();
+ Detector det = reader.read(new FileInputStream(args[0]));
+ Map constants = det.getConstants();
+ for (Iterator i = constants.entrySet().iterator(); i.hasNext(); )
+ {
+ Map.Entry entry = (Map.Entry) i.next();
+ Constant c = (Constant) entry.getValue();
+ System.out.println(entry.getKey()+"="+c.getValue());
+ }
+ }
+}
LCGO/src/java/hep/lcgo/xml/reader
diff -N package.html
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ package.html 29 Sep 2006 16:27:18 -0000 1.1
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+
+<html>
+ <body>
+ A package for reading LCGO geometry XML files.
+ </body>
+</html>
LCGO/src/java/hep/lcgo/xml/reader/util
diff -N CachingEntityResolver.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ CachingEntityResolver.java 29 Sep 2006 16:27:19 -0000 1.1
@@ -0,0 +1,38 @@
+package hep.lcgo.xml.reader.util;
+
+import hep.lcgo.util.cache.FileCache;
+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 2006/09/29 16:27:19 tonyj Exp $
+ */
+public class CachingEntityResolver implements EntityResolver
+{
+ private final 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
LCGO/src/java/hep/lcgo/xml/reader/util
diff -N DefaultElementFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ DefaultElementFactory.java 29 Sep 2006 16:27:19 -0000 1.1
@@ -0,0 +1,100 @@
+package hep.lcgo.xml.reader.util;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import org.jdom.Element;
+import org.jdom.JDOMException;
+import hep.lcgo.xml.reader.util.ElementFactory.ElementCreationException;
+
+
+/**
+ * The default implementation of ElementFactory.
+ * @author tonyj
+ */
+public class DefaultElementFactory implements ElementFactory
+{
+ private List/*<Class>*/ classes = new ArrayList/*<Class>*/();
+ private Map/*<Class,String>*/ packageMap = new HashMap/*<Class,String>*/();
+
+ /**
+ * Create the default element factory.
+ */
+ public DefaultElementFactory()
+ {}
+
+ public Object /*<T> T*/ createElement(Class/*<T>*/ c, Element node, String type) throws JDOMException, ElementCreationException
+ {
+ if (type != null)
+ {
+ Class/*<T>*/ cand = getElementClass(c,type);
+ if (cand != null) return create(cand,node);
+ }
+ for (Iterator i = classes.iterator(); i.hasNext(); )
+ {
+ Class cand = (Class) i.next();
+ if (c.isAssignableFrom(cand)) return create(/*(Class<? extends T>)*/ cand,node);
+ }
+ throw new ElementCreationException("Unknown element "+c);
+ }
+
+ public void register(Class elementClass,String packageName)
+ {
+ packageMap.put(elementClass,packageName);
+ }
+ /**
+ * Register a class with the factory. Future calls to create any class which is a subclass
+ * of this class will cause a new instance of this class to be created. The class specificed
+ * must have a constructor which takes a jdom Element as its argument.
+ * @param elementClass The class to register.
+ */
+ public void register(Class elementClass)
+ {
+ classes.add(0,elementClass);
+ }
+ private Object/*<T> T*/ create(Class/*<T>*/ type, Element node) throws ElementCreationException
+ {
+ try
+ {
+ Constructor/*<T>*/ c = type.getDeclaredConstructor(new Class[]{Element.class});
+ c.setAccessible(true);
+ return c.newInstance(new Object[]{node});
+ }
+ catch (NoSuchMethodException x)
+ {
+ throw new ElementCreationException("Could not create element: "+type,x);
+ }
+ catch (InvocationTargetException x)
+ {
+ throw new ElementCreationException("Could not create element: "+type,x.getTargetException());
+ }
+ catch (InstantiationException x)
+ {
+ throw new ElementCreationException("Could not create element: "+type,x.getCause());
+ }
+ catch (IllegalAccessException x)
+ {
+ throw new ElementCreationException("Could not create element: "+type,x);
+ }
+ }
+ public Class/*<T> Class<T>*/ getElementClass(Class/*<T>*/ type, String name) throws ElementCreationException
+ {
+ String packageName = packageMap.get(type).toString();
+ if (packageName == null) return null;
+ String key = packageName+"."+name;
+ try
+ {
+ Class result = Class.forName(key);
+ if (!type.isAssignableFrom(result)) throw new ElementCreationException("Element "+key+" is of wrong type");
+ return /*(Class<T>)*/ result;
+ }
+ catch (ClassNotFoundException x)
+ {
+ return null;
+ }
+ }
+}
\ No newline at end of file
LCGO/src/java/hep/lcgo/xml/reader/util
diff -N ElementFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ ElementFactory.java 29 Sep 2006 16:27:19 -0000 1.1
@@ -0,0 +1,28 @@
+package hep.lcgo.xml.reader.util;
+
+import org.jdom.Element;
+import org.jdom.JDOMException;
+
+/**
+ * An interface that must be implemented by all element factories.
+ *
+ * By providing their own implementation of ElementFactory users can cause custom classes to be
+ * created by the reader.
+ * @author tonyj
+ * @version $Id: ElementFactory.java,v 1.1 2006/09/29 16:27:19 tonyj Exp $
+ */
+public interface ElementFactory
+{
+ Object /*<T> T*/ createElement(Class/*<T>*/ c, Element node, String type) throws JDOMException, ElementCreationException;
+ static class ElementCreationException extends Exception
+ {
+ ElementCreationException(String message)
+ {
+ super(message);
+ }
+ ElementCreationException(String message, Throwable cause)
+ {
+ super(message /*,cause*/);
+ }
+ }
+}
\ No newline at end of file
LCGO/src/java/hep/lcgo/xml/reader/util
diff -N JDOMExpressionFactory.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ JDOMExpressionFactory.java 29 Sep 2006 16:27:19 -0000 1.1
@@ -0,0 +1,161 @@
+package hep.lcgo.xml.reader.util;
+
+import gnu.jel.CompilationException;
+import gnu.jel.CompiledExpression;
+import gnu.jel.DVMap;
+import gnu.jel.Evaluator;
+import gnu.jel.Library;
+import java.util.HashMap;
+import java.util.Map;
+import org.jdom.Attribute;
+import org.jdom.DataConversionException;
+import org.jdom.DefaultJDOMFactory;
+import org.jdom.Namespace;
+
+/**
+ *
+ * @author tonyj
+ */
+public class JDOMExpressionFactory extends DefaultJDOMFactory
+{
+ private final Object[] resolver = { new Resolver() };
+ private final Library jelLibrary = setUpLibrary();
+ private final Map/*<String,Double>*/ constants = new HashMap/*<String,Double>*/();
+
+ public void addConstant(String name, double value)
+ {
+ constants.put(name,new Double(value));
+ }
+
+ public org.jdom.Attribute attribute(String name, String value, int type, Namespace namespace)
+ {
+ return new CustomAttribute(name,value,type,namespace);
+ }
+
+ public org.jdom.Attribute attribute(String name, String value, Namespace namespace)
+ {
+ return new CustomAttribute(name,value,namespace);
+ }
+
+ public org.jdom.Attribute attribute(String name, String value, int type)
+ {
+ return new CustomAttribute(name,value,type);
+ }
+
+ public org.jdom.Attribute attribute(String name, String value)
+ {
+ return new CustomAttribute(name,value);
+ }
+
+ private class CustomAttribute extends Attribute
+ {
+ CustomAttribute(String name, String value)
+ {
+ super(name,value);
+ }
+ CustomAttribute(String name, String value, int type)
+ {
+ super(name,value,type);
+ }
+ CustomAttribute(String name, String value, Namespace namespace)
+ {
+ super(name,value,namespace);
+ }
+ CustomAttribute(String name, String value, int type, Namespace namespace)
+ {
+ super(name,value,type,namespace);
+ }
+
+ public long getLongValue() throws DataConversionException
+ {
+ String expression = super.getValue();
+ try
+ {
+ CompiledExpression expr = Evaluator.compile(expression,jelLibrary,Long.TYPE);
+ return expr.evaluate_long(resolver);
+ }
+ catch (Throwable x)
+ {
+ DataConversionException xx = new DataConversionException(expression,"long");
+ xx.initCause(x);
+ throw xx;
+ }
+ }
+
+ public int getIntValue() throws DataConversionException
+ {
+ String expression = super.getValue();
+ try
+ {
+ CompiledExpression expr = Evaluator.compile(expression,jelLibrary,Integer.TYPE);
+ return expr.evaluate_int(resolver);
+ }
+ catch (Throwable x)
+ {
+ DataConversionException xx = new DataConversionException(expression,"int");
+ xx.initCause(x);
+ throw xx;
+ }
+ }
+
+ public float getFloatValue() throws DataConversionException
+ {
+ String expression = super.getValue();
+ try
+ {
+ CompiledExpression expr = Evaluator.compile(expression,jelLibrary,Float.TYPE);
+ return expr.evaluate_float(resolver);
+ }
+ catch (Throwable x)
+ {
+ DataConversionException xx = new DataConversionException(expression,"float");
+ xx.initCause(x);
+ throw xx;
+ }
+ }
+
+ public double getDoubleValue() throws DataConversionException
+ {
+ String expression = super.getValue();
+ try
+ {
+ CompiledExpression expr = Evaluator.compile(expression,jelLibrary,Double.TYPE);
+ return expr.evaluate_double(resolver);
+ }
+ catch (Throwable x)
+ {
+ DataConversionException xx = new DataConversionException(expression,"double");
+ xx.initCause(x);
+ throw xx;
+ }
+ }
+ }
+ private Library setUpLibrary()
+ {
+ try
+ {
+ Class[] staticLib = { Math.class };
+ Class[] dynamicLib = { Resolver.class };
+ Library lib = new Library(staticLib,dynamicLib,null,(Resolver) resolver[0],null);
+ lib.markStateDependent("random",null);
+ return lib;
+ }
+ catch (CompilationException x)
+ {
+ throw new RuntimeException(x); // should never happen
+ }
+ }
+
+ public class Resolver extends DVMap
+ {
+ public String getTypeName(String str)
+ {
+ if (constants.containsKey(str)) return "Double";
+ return null;
+ }
+ public double getDoubleProperty(String str)
+ {
+ return ((Number) constants.get(str)).doubleValue();
+ }
+ }
+}
CVSspam 0.2.8