JaRMoS  1.1
Java Reduced Model Simulations
 All Classes Namespaces Files Functions Variables Enumerator Groups Pages
AModelManager.java
Go to the documentation of this file.
1 package jarmos.io;
2 
5 import jarmos.Log;
7 import jarmos.ModelType;
8 import jarmos.Parameters;
14 
15 import java.io.BufferedReader;
16 import java.io.IOException;
17 import java.io.InputStream;
18 import java.io.InputStreamReader;
19 import java.net.URI;
20 import java.text.DateFormat;
21 import java.text.ParseException;
22 import java.util.ArrayList;
23 import java.util.Calendar;
24 import java.util.Date;
25 import java.util.List;
26 
27 import javax.xml.XMLConstants;
28 import javax.xml.parsers.DocumentBuilder;
29 import javax.xml.parsers.DocumentBuilderFactory;
30 import javax.xml.parsers.ParserConfigurationException;
31 import javax.xml.transform.dom.DOMSource;
32 import javax.xml.transform.stream.StreamSource;
33 import javax.xml.validation.Schema;
34 import javax.xml.validation.SchemaFactory;
35 import javax.xml.validation.Validator;
36 
37 import org.w3c.dom.Document;
38 import org.w3c.dom.Element;
39 import org.w3c.dom.Node;
40 import org.w3c.dom.NodeList;
41 import org.xml.sax.SAXException;
42 
61 public abstract class AModelManager {
62 
69  public class ModelManagerException extends Exception {
70 
71  private static final long serialVersionUID = 7411589173897801550L;
72 
76  public ModelManagerException(String msg) {
77  super(msg);
78  }
79 
84  public ModelManagerException(String msg, Exception inner) {
85  super(msg, inner);
86  }
87 
88  }
89 
95  public static final String CLASSES_JARFILE = "classes.jar";
96 
100  public static final String info_filename = "site_info.html";
101 
102  private DocumentBuilder db = null;
103  private Validator dv = null;
104  private String mdir = "notset";
105  private List<IMessageHandler> mhandlers;
106  private Node modelnode = null;
107  private Document modelxml = null;
108  private ModelType mtype = ModelType.Unknown;
109 
110  private MathObjectReader mor = null;
111 
124  public AModelManager() {
125  mhandlers = new ArrayList<IMessageHandler>();
126  try {
127  // Create the document builder
128  DocumentBuilderFactory bf = DocumentBuilderFactory.newInstance();
129  bf.setIgnoringElementContentWhitespace(true);
130 
131  db = bf.newDocumentBuilder();
132 
133  InputStream in = getClass().getResourceAsStream("/model.xsd");
134 
135  // Create the schema validator (if xsd was found)
136  if (in != null) {
137  try {
138  SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
139  Schema s = sf.newSchema(new StreamSource(in));
140  // dv = s.newValidator();
141  } catch (IllegalArgumentException e) { //
142  /*
143  * See constructor comment on what happens here.. Set Validator to null if the
144  * IllegalArgumentException gets thrown
145  */
146  dv = null;
147  }
148  } else
149  Log.e("AModelManager", "No model.xsd validation resource found!");
150  } catch (ParserConfigurationException e) {
151  throw new RuntimeException("Error creating a XML document builder", e);
152  } catch (SAXException e) {
153  throw new RuntimeException("Error creating a XML schema validator", e);
154  }
155  }
156 
161  mhandlers.add(h);
162  }
163 
173  public Object loadModelClass(String name) throws ModelManagerException {
174  ClassLoader cl = getClassLoader();
175  String pkg = getModelPackageStr();
176  try {
177  Class<?> af = cl.loadClass(pkg + name);
178  return af.newInstance();
179  } catch (Exception e) {
180  throw new ModelManagerException("Error loading the model class '" + name + "' of package '"
181  + (pkg != "" ? pkg : "(default)") + "'.", e);
182  }
183  }
184 
192  public BufferedReader getBufReader(String filename) throws IOException {
193  int buffer_size = 8192;
194 
195  InputStreamReader isr = new InputStreamReader(getInStream(filename));
196  return new BufferedReader(isr, buffer_size);
197  }
198 
211  public ClassLoader getClassLoader() {
212  return ClassLoader.getSystemClassLoader();
213  }
214 
223  protected abstract String[] getFolderList() throws IOException;
224 
230  protected abstract String getLoadingMessage();
231 
240  public final InputStream getInStream(String filename) throws IOException {
241  int pos = filename.indexOf(".bin");
242  sendMessage((pos > -1) ? filename.substring(0, pos) : filename);
243  return getInStreamImpl(filename);
244  }
245 
257  protected abstract InputStream getInStreamImpl(String filename) throws IOException;
258 
266  return mor;
267  }
268 
276  public List<ModelDescriptor> getModelDescriptors() throws ModelManagerException {
278  }
279 
290  public List<ModelDescriptor> getModelDescriptors(IProgressReporter pr) throws ModelManagerException {
291  ArrayList<ModelDescriptor> res = new ArrayList<ModelDescriptor>();
292  String[] list = null;
293  try {
294  list = getFolderList();
295  } catch (IOException e) {
296  throw new ModelManagerException("Listing model folders failed.", e);
297  }
298  // Set loading message
299  pr.init(getLoadingMessage(), list.length);
300  int cnt = 0;
301  for (String modeldir : list) {
302  pr.progress(++cnt);
303  if (isValidModelDir(modeldir)) {
304  useModel(modeldir);
305  // Check for the correct model type
306  ModelType mtype = ModelType.parse(getModelXMLAttribute("type"));
307  if (mtype == ModelType.Unknown)
308  continue;
309 
310  InputStream img = null;
311  String imgfile = getModelXMLTagValue("description.image");
312  if (modelFileExists(imgfile)) {
313  try {
314  img = getInStream(imgfile);
315  } catch (IOException e) {
316  // ignore
317  }
318  } else
319  img = getClass().getClassLoader().getResourceAsStream("notfound.png");
320  // Get model date
321  Date d = null;
322  try {
323  d = DateFormat.getDateInstance().parse(getModelXMLTagValue("description.created"));
324  } catch (ParseException e) {
325  d = Calendar.getInstance().getTime();
326  }
327  ModelDescriptor md = new ModelDescriptor(modeldir, getModelXMLTagValue("description.name"), mtype, img,
328  d);
329  md.shortDescription = getModelXMLTagValue("description.short", "");
330  res.add(md);
331  }
332  }
333  pr.finish();
334  return res;
335  }
336 
341  public String getModelDir() {
342  return mdir;
343  }
344 
346  FieldDescriptor[] res = null;
347  Element params = getModelXMLElement("visual.fields");
348  if (params != null) {
349  NodeList nl = params.getElementsByTagName("field");
350  res = new FieldDescriptor[nl.getLength()];
351  String hlp;
352  FieldDescriptor f;
353  for (int i = 0; i < nl.getLength(); i++) {
354  Node n = nl.item(i);
355  f = new FieldDescriptor(SolutionFieldType.valueOf(getNodeAttributeValue(n, "type")));
356  f.Name = n.getTextContent();
357  hlp = getNodeAttributeValue(n, "mapping");
358  f.Mapping = hlp != null ? FieldMapping.valueOf(hlp) : FieldMapping.UNKNOWN;
359  res[i] = f;
360  }
361  }
362  return res;
363  }
364 
371  return mtype;
372  }
373 
379  public abstract URI getModelURI();
380 
389  public String getModelXMLAttribute(String attrib_name) {
390  assert attrib_name != null;
391 
392  if (modelnode != null) {
393  return getNodeAttributeValue(modelnode, attrib_name);
394  }
395  return null;
396  }
397 
408  public String getModelXMLAttribute(String attrib_name, String tagname) {
409  assert attrib_name != null;
410  assert tagname != null;
411 
412  Element e = getModelXMLElement(tagname);
413  return (e != null) ? getNodeAttributeValue(e, attrib_name) : null;
414  }
415 
416  // private String[] getXMLElementChildNames(String tags) {
417  // String[] res = null;
418  // Element parent = getModelXMLElement(tags);
419  // if (parent != null) {
420  // res = new String[parent.getChildNodes().getLength()];
421  // for (int nidx = 0; nidx < res.length; nidx++) {
422  // res[nidx] = parent.getChildNodes().item(nidx).getNodeName();
423  // }
424  // }
425  // return res;
426  // }
427 
428  private Element getModelXMLElement(String tags) {
429  if (modelxml != null) {
430  Element cur = modelxml.getDocumentElement();
431  String[] elems = tags.split("\\.");
432  for (String elem : elems) {
433  NodeList nl = cur.getElementsByTagName(elem);
434  if (nl != null && nl.getLength() > 0) {
435  cur = (Element) nl.item(0);
436  } else {
437  cur = null;
438  break;
439  }
440  }
441  if (cur != null) {
442  return cur;
443  }
444  }
445  return null;
446  }
447 
454  public String getModelXMLTagValue(String tagname) {
455  return getModelXMLTagValue(tagname, null);
456  }
457 
471  public String getModelXMLTagValue(String tagname, String default_value) {
472  Element res = getModelXMLElement(tagname);
473  return (res != null) ? res.getTextContent() : default_value;
474  }
475 
482  public String getModelPackageStr() {
483  String thepackage = getModelXMLTagValue("package");
484  return thepackage != null ? thepackage + "." : "";
485  }
486 
493  private String getNodeAttributeValue(Node n, String attrib_name) {
494  assert n != null;
495  assert attrib_name != null;
496 
497  Node a = n.getAttributes().getNamedItem(attrib_name);
498  if (a != null) {
499  return a.getNodeValue();
500  } else
501  return null;
502  }
503 
510  Element params = getModelXMLElement("parameters");
511  if (params != null) {
512  Parameters p = new Parameters();
513  NodeList nl = params.getElementsByTagName("param");
514  double[] cur = new double[nl.getLength()];
515  for (int i = 0; i < nl.getLength(); i++) {
516  Node n = nl.item(i);
517  String name = getNodeAttributeValue(n, "name");
518  // Set \mu_i if no name is given.
519  if (name == null) {
520  name = "\u00B5_" + i;
521  }
522  // Add
523  p.addParam(name, Double.parseDouble(getNodeAttributeValue(n, "min")),
524  Double.parseDouble(getNodeAttributeValue(n, "max")));
525  // Extract default values and set as current, take min value if
526  // no default is set
527  String def = getNodeAttributeValue(n, "default");
528  cur[i] = def != null ? Double.parseDouble(def) : p.getMinValue(i);
529  }
530  p.setCurrent(cur);
531  return p;
532  }
533  return null;
534  }
535 
548  public boolean isValidModelDir(String dir) {
549  assert dir != null;
550 
551  /*
552  * Store current model directory if set, and temporarily set the model dir to dir. This is done as subclass
553  * implementations will of course depend on getModelDir() when calling modelFileExists().
554  */
555  String olddir = mdir;
556  mdir = dir;
557  if (!modelFileExists("model.xml"))
558  return false;
559  try {
560  try {
561  db.parse(getInStream("model.xml"));
562  } catch (SAXException e) {
563  return false;
564  }
565  try {
566  if (dv != null) {
567  dv.validate(new DOMSource(modelxml));
568  }
569  } catch (SAXException se) {
570  Log.e("AModelManager", "Invalid model.xml: " + se.getMessage(), se);
571  return false;
572  }
573  } catch (IOException e) {
574  throw new RuntimeException("I/O error while checking if model directory is valid.", e);
575  }
576  // Restore old model dir
577  mdir = olddir;
578  return true;
579  }
580 
587  public abstract boolean modelFileExists(String filename);
588 
593  mhandlers.remove(h);
594  }
595 
596  protected void sendMessage(String msg) {
597  for (IMessageHandler h : mhandlers) {
598  h.sendMessage(msg);
599  }
600  }
601 
615  public void useModel(String location) throws ModelManagerException {
616  assert isValidModelDir(location);
617 
618  this.mdir = location;
619  Log.d("ModelManager", "Loading model from " + getModelURI());
620  try {
621  modelxml = db.parse(getInStream("model.xml"));
622  } catch (Exception e) {
623  throw new ModelManagerException("Unexpected Exception in AModelManager.setModelDir: " + e.getMessage(), e);
624  }
625 
626  modelxml.normalize();
627  modelnode = modelxml.getElementsByTagName("model").item(0);
628 
629  String type = getModelXMLAttribute("type");
630  mtype = ModelType.parse(type);
631  if (mtype == ModelType.Unknown)
632  throw new ModelManagerException("Unknown model type: " + type);
633 
634  // Parse model data machine format
635  mor = new MathObjectReader();
636  String machformat = getModelXMLAttribute("machformat");
637  if ("le".equals(machformat)) {
638  mor.MachineFormat = MachineFormats.LittleEndian;
639  } else {
640  mor.MachineFormat = MachineFormats.BigEndian;
641  }
642  }
643 
651  public boolean xmlTagExists(String tagname) {
652  return getModelXMLElement(tagname) != null;
653  }
654 }
abstract String getLoadingMessage()
A short message that writes &quot;loading SD models&quot; dependent on the actual instance. ...
An interface for classes capable of sending messages.
Unknown field mapping type.
MathObjectReader getMathObjReader()
Use this method in order to get a MathObjectReader instance fitted for the current selected model...
void removeMessageHandler(IMessageHandler h)
Parameters getParameters()
Reads the parameters from the model XML file and returns a Parameters object.
ModelManagerException(String msg, Exception inner)
void useModel(String location)
Sets the specified source as current model path.
Reading matrices and vectors with a bunch of convenient overloads for different sources and output fo...
BufferedReader getBufReader(String filename)
abstract boolean modelFileExists(String filename)
Returns whether the specified file exists in the current model folder.
boolean isValidModelDir(String dir)
Checks if a model.xml file exists in the specified directory and performs xsd-validation.
double getMinValue(int i)
final InputStream getInStream(String filename)
Returns an InputStream instance streaming the contents of the file given by filename.
static final String CLASSES_JARFILE
The name of the jar file inside a models directory containing .class files in java bytecode...
List< ModelDescriptor > getModelDescriptors(IProgressReporter pr)
Scans all directories given by getFolderList() for valid models and returns a list of model descripto...
FieldDescriptor[] getModelFieldTypes()
Known model types within the JaRMoSBase project.
Definition: ModelType.java:9
This class serves as base class for accessing various types of models at different locations...
static final String info_filename
The model&#39;s info html file name (imported from rbappmit, might change later)
abstract URI getModelURI()
Returns an URI for the current model location/directory.
A class for model parameters.
Definition: Parameters.java:17
This enum contains all so far known (to JaRMoSBase) types of logical solution fields.
Object loadModelClass(String name)
Loads a class available in the precompiled classes associated with the current model.
Unknown
This model type is unknown to JaRMoSBase.
Definition: ModelType.java:13
Enum for both known machine formats.
Represents a short description of a model managed by a model manager.
void sendMessage(String msg)
String getModelPackageStr()
Returns the package of any java source files associated with this model.
The field mapping determines how the DoF of the solution are mapped into the given geometry...
ModelType getModelType()
Returns the model type as given in the model.xml attribute &quot;type&quot; of the &quot;model&quot; tag.
Provides a Log class imitating the Android Log class when not used on android systems.
Definition: Log.java:11
This Exception gets thrown when an error occurs regarding the functionality of the ModelManager...
String getModelXMLTagValue(String tagname)
Works as the overload with default value, but returns null if no matchin element is found...
abstract String[] getFolderList()
Returns the list of all models directories available at the ModelManagers source location.
String getModelXMLTagValue(String tagname, String default_value)
Returns the text content of a tag inside the model.xml file.
Simple progress reporting implementation using the Java standard console.
AModelManager()
Constructs a new ModelManager and a private DocumentBuilder and SchemaFactory.
String getModelXMLAttribute(String attrib_name)
Returns the attribute value of any attributes of the &quot;model&quot; tag in the model.xml file...
List< ModelDescriptor > getModelDescriptors()
Scans all directories given by getFolderList() for valid models and returns a list of model descripto...
String getModelXMLAttribute(String attrib_name, String tagname)
Returns the attribute value of any attributes of the tag given by tagname in the model.xml file.
Contains information about the logical solution fields.
void addMessageHandler(IMessageHandler h)
abstract InputStream getInStreamImpl(String filename)
Template method.
ClassLoader getClassLoader()
This method yields access to any specialized class loaders in subclasses.
boolean xmlTagExists(String tagname)
Checks if a specified tag exists inside the current models model.xml file.
Simple interface for progress reporting.