/* * Created on 13.04.2005 */ package impl.owls.grounding; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URI; import java.net.URL; import org.mindswap.exceptions.ExecutionException; import org.mindswap.owl.EntityFactory; import org.mindswap.owl.OWLDataValue; import org.mindswap.owl.OWLFactory; import org.mindswap.owl.OWLIndividual; import org.mindswap.owl.OWLIndividualList; import org.mindswap.owl.OWLKnowledgeBase; import org.mindswap.owl.OWLObject; import org.mindswap.owl.OWLValue; import org.mindswap.owls.grounding.AtomicGrounding; import org.mindswap.owls.grounding.JavaAtomicGrounding; import org.mindswap.owls.grounding.JavaParameter; import org.mindswap.owls.grounding.JavaVariable; import org.mindswap.owls.grounding.MessageMapList; import org.mindswap.owls.process.Input; import org.mindswap.owls.process.Output; import org.mindswap.owls.process.Parameter; import org.mindswap.owls.vocabulary.MoreGroundings; import org.mindswap.owls.vocabulary.OWLS; import org.mindswap.query.ValueMap; import org.mindswap.utils.ReflectionUtils; import org.mindswap.utils.URIUtils; /** * A JavaAtomicGrounding grounds an OWL-S Service to a Java method invocation. The method call * is specified by its method signature in an OWL-S Ontology. The driving parts are: * * * @author Michael Daenzer, University of Zürich * * @see Grounding Ontology * @see org.mindswap.owls.grounding.AtomicGrounding * @see org.mindswap.owls.vocabulary.NextOnt * @see impl.owls.grounding.AtomicGroundingImpl */ public class JavaAtomicGroundingImpl extends AtomicGroundingImpl implements JavaAtomicGrounding { /** * @param ind */ public JavaAtomicGroundingImpl(OWLIndividual ind) { super(ind); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.JavaAtomicGrounding#setClaz(java.lang.String) */ public void setClaz(String claz) { setProperty(MoreGroundings.javaClass, claz); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.JavaAtomicGrounding#getClaz() */ public String getClaz() { return getPropertyAsString(MoreGroundings.javaClass); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.JavaAtomicGrounding#setMethod(java.lang.String) */ public void setMethod(String method) { setProperty(MoreGroundings.javaMethod, method); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.JavaAtomicGrounding#getMethod() */ public String getMethod() { return getPropertyAsString(MoreGroundings.javaMethod); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.AtomicGrounding#getDescriptionURL() */ public URL getDescriptionURL() { return null; } /* (non-Javadoc) * @see org.mindswap.owls.grounding.AtomicGrounding#addMessageMap(org.mindswap.owls.process.Parameter, java.lang.String, java.lang.String) */ public void addMessageMap(Parameter owlsParameter, String groundingParameter, String xsltTransformation) { } /* (non-Javadoc) * @see org.mindswap.owls.grounding.AtomicGrounding#getInputMap() */ public MessageMapList getInputMap() { return null; } /* (non-Javadoc) * @see org.mindswap.owls.grounding.AtomicGrounding#getOutputMap() */ public MessageMapList getOutputMap() { return null; } /* (non-Javadoc) * @see org.mindswap.owls.grounding.AtomicGrounding#invoke(org.mindswap.query.ValueMap) */ public ValueMap invoke(ValueMap values) throws ExecutionException { return invoke(values, OWLFactory.createKB()); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.AtomicGrounding#invoke(org.mindswap.query.ValueMap, org.mindswap.owl.OWLKnowledgeBase) */ public ValueMap invoke(ValueMap values, OWLKnowledgeBase kb) throws ExecutionException { Class claz = null; Method method = null; Class params[] = null; Object paramValues[] = null; ValueMap results = new ValueMap(); Object result = null; // get and check class String strClaz = getClaz(); if ((strClaz == null) || (strClaz.equals(""))) throw new ExecutionException("JavaAtomicGrounding: No Java Class defined in Grounding!"); // get and check method String strMethod = getMethod(); if ((strMethod == null) || (strMethod.equals(""))) throw new ExecutionException("JavaAtomicGrounding: No Java Method defined in Grounding!"); // prepare parameters int paramSize = getInputParameters().size(); params = new Class[paramSize]; for (int i = 0; i < paramSize; i++) params[i] = getJavaParameterTypeAt(i); // get class and method reference try { claz = Class.forName(strClaz); method = claz.getDeclaredMethod(strMethod, params); } catch (ClassNotFoundException e){ throw new ExecutionException("JavaAtomicGrounding: Class " + strClaz + " defined in Grounding not found." ); } catch (NoSuchMethodException e) { throw new ExecutionException("JavaAtomicGrounding: Method " + strMethod + " defined in Grounding not found." ); } catch (Exception e) { throw new ExecutionException("JavaAtomicGrounding: " + e.getClass().toString() + " ocurred: " + e.getMessage()); } // prepare inputs paramValues = new Object[paramSize]; for (int i = 0; i < params.length; i++) { OWLValue owlValue = values.getValue(getOWLSParameterAt(i)); if (owlValue.isDataValue()) paramValues[i] = ReflectionUtils.getCastedObjectFromStringValue(((OWLDataValue) owlValue).getLexicalValue(), params[i]); else if (owlValue.isIndividual()) { paramValues[i] = getJavaParameterAt(i, (OWLIndividual) owlValue); } //System.out.println( "Parameter " + i + " " + paramValues[i] ); } // invoke java method try { Object obj = claz.newInstance(); if (method.getReturnType().toString().equalsIgnoreCase("void")) method.invoke(obj, paramValues); else result = method.invoke(obj, paramValues); } catch (InvocationTargetException e) { throw new ExecutionException("JavaAtomicGrounding: Error in executed method\n" + e.getTargetException().toString() + " ocurred: "); } catch (Exception e) { throw new ExecutionException("JavaAtomicGrounding: Error while executing method\n" + e.getClass().toString() + " ocurred: "); } // set output if (result != null) { Parameter param = getOWLSOutput(); if (param == null) throw new ExecutionException("JavaAtomicGrounding: Output in Grounding not specified although method provides a return value."); if(param.getParamType().isDataType()) results.setValue(param, EntityFactory.createDataValue(result)); else results.setValue(param, transformResult(result)); } return results; } private OWLValue transformResult(Object result) { JavaVariable output = getOutput(); if (output == null) return null; String transformerName = output.getTransformator().trim(); if (transformerName != null && !transformerName.trim().equals("")) { try { Class transformerClass = Class.forName(transformerName); Constructor constructor = transformerClass.getConstructor(new Class[] {OWLKnowledgeBase.class}); JavaClassTransformator transformer = (JavaClassTransformator) constructor.newInstance(new Object[] {getKB()}); return transformer.transformToOWL(result); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } return null; } // returns the OWL-S Output Parameter private Parameter getOWLSOutput() { OWLObject owlsParam = getProperty(MoreGroundings.javaOutput).getProperty(MoreGroundings.owlsParameter); return (owlsParam == null) ? null : (Parameter) owlsParam.castTo(Parameter.class); } // returns the n-th OWL-S Input Parameter private Parameter getOWLSParameterAt(int index) { JavaParameter param = getInputParamter(index); if (param == null) return null; return param.getOWLSParameter(); } // returns the n-th Parameter of the Java Method specified in the OWL-S JavaAtomicProcessGrounding private Class getJavaParameterTypeAt(int index) { JavaParameter param = getInputParamter(index); if (param == null) return null; String transformerName = param.getTransformator().trim(); String javaType = param.getJavaType(); if (transformerName != null && !transformerName.trim().equals("")) { try { Class transformerClass = Class.forName(transformerName); Constructor constructor = transformerClass.getConstructor(new Class[] {OWLKnowledgeBase.class}); JavaClassTransformator transformer = (JavaClassTransformator) constructor.newInstance(new Object[] {getKB()}); return transformer.getJavaClass(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } else { return ReflectionUtils.getClassFromString(javaType); } } // returns the n-th Parameter of the Java Method specified in the OWL-S JavaAtomicProcessGrounding private Object getJavaParameterAt(int index, OWLIndividual owlValue) { JavaParameter param = getInputParamter(index); if (param == null) return null; String transformerName = param.getTransformator().trim(); String javaType = param.getJavaType(); if (transformerName != null && !transformerName.trim().equals("")) { try { Class transformerClass = Class.forName(transformerName); Constructor constructor = transformerClass.getConstructor(new Class[] {OWLKnowledgeBase.class}); JavaClassTransformator transformer = (JavaClassTransformator) constructor.newInstance(new Object[] {getKB()}); return transformer.transformFromOWL(owlValue); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } else { return ReflectionUtils.getClassFromString(javaType); } } /* (non-Javadoc) * @see org.mindswap.owls.grounding.JavaAtomicGrounding#setOutputVar(java.lang.String, java.lang.String, org.mindswap.owls.process.Output) */ public void setOutput(String name, String type, Output owlsParameter) { OWLIndividual ind = getOntology().createInstance(MoreGroundings.JavaVariable, URI.create(name)); ind.setProperty(MoreGroundings.javaType, type); ind.setProperty(MoreGroundings.owlsParameter, owlsParameter); setProperty(MoreGroundings.javaOutput, ind); } /* (non-Javadoc) * @see org.mindswap.owls.grounding.JavaAtomicGrounding#setInputVar(java.lang.String, java.lang.String, int, org.mindswap.owls.process.Input) */ public void setInputParameter(String name, String type, int index, Input owlsParameter) { OWLIndividual ind = getOntology().createInstance(MoreGroundings.JavaParameter, URIUtils.createURI(name)); ind.setProperty(MoreGroundings.javaType, type); ind.setProperty(MoreGroundings.owlsParameter, owlsParameter); ind.setProperty(MoreGroundings.paramIndex, Integer.toString(index)); addProperty(MoreGroundings.hasJavaParameter, ind); } @Override public String getGroundingType() { return AtomicGrounding.GROUNDING_JAVA; } @Override public String toString() { return getClaz() + "." + getMethod(); } private void removeAll() { if (hasProperty(MoreGroundings.javaClass)) removeProperties(MoreGroundings.javaClass); if (hasProperty(MoreGroundings.javaMethod)) removeProperties(MoreGroundings.javaMethod); // TODO an rdf:type property of the related input stays persistent. why???? if (hasProperty(MoreGroundings.hasJavaParameter)) { OWLIndividualList indList = getProperties(MoreGroundings.hasJavaParameter); for (int i = 0; i < indList.size(); i++) { OWLIndividual ind = indList.individualAt(i); if (ind.hasProperty(MoreGroundings.javaType)) ind.removeProperties(MoreGroundings.javaType); if (ind.hasProperty(MoreGroundings.owlsParameter)) ind.removeProperties(MoreGroundings.owlsParameter); if (ind.hasProperty(MoreGroundings.paramIndex)) ind.removeProperties(MoreGroundings.paramIndex); removeProperty(MoreGroundings.hasJavaParameter, ind); ind.delete(); } } if (hasProperty(MoreGroundings.javaOutput)) { OWLIndividual ind = getProperty(MoreGroundings.javaOutput); if (ind.hasProperty(MoreGroundings.javaType)) ind.removeProperties(MoreGroundings.javaType); if (ind.hasProperty(MoreGroundings.owlsParameter)) ind.removeProperties(MoreGroundings.owlsParameter); removeProperties(MoreGroundings.javaOutput); ind.delete(); } if (hasProperty(MoreGroundings.owlsProcess)) removeProperties(MoreGroundings.owlsProcess); if (hasProperty(OWLS.Grounding.owlsProcess)) removeProperties(OWLS.Grounding.owlsProcess); } @Override public void delete() { removeAll(); super.delete(); } public JavaParameter getInputParamter(Input input) { OWLIndividualList list = getPropertiesAs(MoreGroundings.hasJavaParameter, JavaParameter.class); for (int i = 0; i < list.size(); i++) { OWLIndividual ind = list.individualAt(i).getProperty(MoreGroundings.owlsParameter); if (ind.getURI().equals(input.getURI())) return (JavaParameter) list.individualAt(i); } return null; } public JavaParameter getInputParamter(int index) { OWLIndividualList list = getPropertiesAs(MoreGroundings.hasJavaParameter, JavaParameter.class); for (int i = 0; i < list.size(); i++) { String curIndex = list.individualAt(i).getProperty(MoreGroundings.paramIndex).getLexicalValue(); if (Integer.valueOf(curIndex).intValue() == index) return (JavaParameter) list.individualAt(i); } return null; } public JavaVariable getOutput() { return (JavaVariable) getPropertyAs(MoreGroundings.javaOutput, JavaVariable.class); } public OWLIndividualList getInputParameters() { OWLIndividualList list = getPropertiesAs(MoreGroundings.hasJavaParameter, JavaParameter.class); list.add("tempPlaceForSwap"); // loop through every element for (int i = 0; i < list.size() - 2; i++) { int element = Integer.parseInt(list.individualAt(i).getProperty( MoreGroundings.paramIndex).getLexicalValue()); int min = Integer.MAX_VALUE; int pos = i; // find the minimal element in the rest for (int j = i + 1; j < list.size() - 1; j++) { int temp = Integer.parseInt(list.individualAt(j).getProperty( MoreGroundings.paramIndex).getLexicalValue()); if (temp < min) { min = temp; pos = j; } } // swap it to the front if (min < element) { list.set(list.size() -1, list.get(i)); list.set(i, list.get(pos)); list.set(pos, list.get(list.size() - 1)); } } list.remove(list.size() - 1); return list; } public String getTransformator(JavaVariable variable) { return getPropertyAsString(MoreGroundings.transformatorClass); } public void setTransformator(String transformClass) { setProperty(MoreGroundings.transformatorClass, transformClass); } }