diff --git a/src/com/xmlcalabash/core/XProcConfiguration.java b/src/com/xmlcalabash/core/XProcConfiguration.java index 632036f3..2e4646a2 100644 --- a/src/com/xmlcalabash/core/XProcConfiguration.java +++ b/src/com/xmlcalabash/core/XProcConfiguration.java @@ -17,6 +17,7 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; +import java.lang.reflect.Method; import java.util.Hashtable; import java.util.Vector; import java.util.HashSet; @@ -82,7 +83,7 @@ public class XProcConfiguration { public String entityResolver = null; public String uriResolver = null; public String errorListener = null; - public Hashtable implementations = new Hashtable (); + public Hashtable implementations = new Hashtable (); public Hashtable serializationOptions = new Hashtable(); public LogOptions logOpt = LogOptions.WRAPPED; public Vector extensionFunctions = new Vector(); @@ -442,15 +443,31 @@ public void parse(XdmNode doc) { public boolean isStepAvailable(QName type) { - return implementations.containsKey(type); + if (implementations.containsKey(type)) { + Class klass = implementations.get(type); + try { + Method method = klass.getMethod("isAvailable"); + Boolean available = (Boolean) method.invoke(null); + return available.booleanValue(); + } catch (NoSuchMethodException e) { + return true; // Failure to implement the method... + } catch (InvocationTargetException e) { + return true; // ...or to implement it... + } catch (IllegalAccessException e) { + return true; // ...badly doesn't mean it's not available. + } + } else { + return false; + } } public XProcStep newStep(XProcRuntime runtime,XAtomicStep step){ - String className = implementations.get(step.getType()); - if (className == null) { - throw new UnsupportedOperationException("Misconfigured. No 'class' in configuration for " + step.getType()); + Class klass = implementations.get(step.getType()); + if (klass == null) { + throw new XProcException("Misconfigured. No 'class' in configuration for " + step.getType()); } + String className = klass.getName(); // FIXME: This isn't really very secure... if (runtime.getSafeMode() && !className.startsWith("com.xmlcalabash.")) { throw XProcException.dynamicError(21); @@ -810,7 +827,14 @@ private void parseImplementation(XdmNode node) { for (String tname : nameStr.split("\\s+")) { QName name = new QName(tname,node); - implementations.put(name, value); + try { + Class klass = Class.forName(value); + implementations.put(name, klass); + } catch (ClassNotFoundException e) { + // nop + } catch (NoClassDefFoundError e) { + // nop + } } } diff --git a/src/com/xmlcalabash/library/DefaultStep.java b/src/com/xmlcalabash/library/DefaultStep.java index 42d09941..40c2dc89 100644 --- a/src/com/xmlcalabash/library/DefaultStep.java +++ b/src/com/xmlcalabash/library/DefaultStep.java @@ -63,6 +63,10 @@ public XAtomicStep getStep() { return step; } + public static boolean isAvailable() { + return true; + } + public void setInput(String port, ReadablePipe pipe) { throw new XProcException("No inputs allowed."); }