Programatic java ATL launch not working - java

I have a huge problem:
I have an ATL transformation that works flawlessly when I use the normal way to do it, using the atl plugin.
But when I try to java launch, it cannot find the classes of a model (org.eclipse.emf.ecore.xmi.ClassNotFoundException: Class 'operationalTemplateGroup' is not found or is abstract)
Exemple:
I have a "operationalTemplateGroup" class on my model, but the metamodel describes it as :
<eClassifiers xsi:type="ecore:EClass" name="OPERATIONALTEMPLATEGROUP">
<eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
<details key="name" value="OPERATIONALTEMPLATEGROUP"/>
<details key="kind" value="elementOnly"/>
</eAnnotations>
See, OPERATIONALTEMPLATEGROUP and not operationalTemplateGroup, why the plugin can parse it but the java launcher dont?
I have this problem with only 1 model, the others are working fine, and if I change it to operationalTemplateGroup it will work, until the next class that has the same problem, ( About 6000 lines of code ).
Method:
public static void main(String[] args) {
try {
System.out.println("Running...");
/*
* Paths
*/
String inModelPath = "models/architectures/AToMS.acmehealth";
String inModelPath2 = "models/openehr/TemplatesAToMS.openehr2008v4";
String outModelPath = "models/richubi/TemplatesAToMS22.rich_interface_model";
String archMMPath = "metamodels/architectures/ACMEHealthv2.ecore";
String openEHRMMPath = "metamodels/openehr/openehr2008v4.ecore";
String richUbiMMPath = "metamodels/richubi/rich_interface_components.ecore";
System.out.println("inModelPath: " inModelPath);
System.out.println("inModelPath2: " inModelPath2);
System.out.println("outModelPath: " outModelPath);
System.out.println("archMMPath: " archMMPath);
System.out.println("openEHRMMPath: " openEHRMMPath);
System.out.println("richUbiMMPath: " richUbiMMPath);
/*
* Initializations
*/
ILauncher transformationLauncher = new EMFVMLauncher();
ModelFactory modelFactory = new EMFModelFactory();
IInjector injector = new EMFInjector();
IExtractor extractor = new EMFExtractor();
/*
* Load metamodels
*/
IReferenceModel archMetamodel = modelFactory.newReferenceModel();
injector.inject(archMetamodel, archMMPath);
IReferenceModel openEHRMetamodel = modelFactory.newReferenceModel();
injector.inject(openEHRMetamodel, openEHRMMPath);
IReferenceModel richUbiMetamodel = modelFactory.newReferenceModel();
injector.inject(richUbiMetamodel, richUbiMMPath);
System.out.println("Metamodels loaded.");
/*
* Load models and run transformation
*/
IModel inModel2 = modelFactory.newModel(openEHRMetamodel);
injector.inject(inModel2, inModelPath2); // ERROR HERE!!!!
IModel inModel = modelFactory.newModel(archMetamodel);
injector.inject(inModel, inModelPath);
IModel outModel = modelFactory.newModel(richUbiMetamodel);
System.out.println("IN, OUT models loaded.");
System.out.print("Running ATL trasformation...");
transformationLauncher.initialize(new HashMap<String, Object>());
transformationLauncher.addLibrary("LibHelpers",
new FileInputStream("transformations/LibHelpers.asm"));
transformationLauncher.addInModel(inModel, "archMM", "openEHRMM");
transformationLauncher.addInModel(inModel2, null, "openEHRMM");
transformationLauncher.addOutModel(outModel, "archM", "openEHRM");
transformationLauncher
.launch(ILauncher.RUN_MODE,
new NullProgressMonitor(),
new HashMap<String, Object>(),
new FileInputStream(
"/home/operador/workspace/Transformation/transformations/OpenEHRTemplates2RichUbi.asm"));
System.out.println("Done.");
System.out.print("Extracting OUT model...");
extractor.extract(outModel, outModelPath);
System.out.println("Done.");
/*
* Unload all models and metamodels (EMF-specific)
*/
EMFModelFactory emfModelFactory = (EMFModelFactory) modelFactory;
emfModelFactory.unload((EMFModel) inModel);
emfModelFactory.unload((EMFModel) outModel);
emfModelFactory.unload((EMFReferenceModel) archMetamodel);
emfModelFactory.unload((EMFReferenceModel) openEHRMetamodel);
} catch (ATLCoreException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

Related

How to invoke model from TensorFlow Java?

The following python code passes ["hello", "world"] into the universal sentence encoder and returns an array of floats denoting their encoded representation.
import tensorflow as tf
import tensorflow_hub as hub
module = hub.KerasLayer("https://tfhub.dev/google/universal-sentence-encoder/4")
model = tf.keras.Sequential(module)
print("model: ", model(["hello", "world"]))
This code works but I'd now like to do the same thing using the Java API. I've successfully loaded the module, but I am unable to pass inputs into the model and extract the output. Here is what I've got so far:
import org.tensorflow.Graph;
import org.tensorflow.SavedModelBundle;
import org.tensorflow.Session;
import org.tensorflow.Tensor;
import org.tensorflow.Tensors;
import org.tensorflow.framework.ConfigProto;
import org.tensorflow.framework.GPUOptions;
import org.tensorflow.framework.GraphDef;
import org.tensorflow.framework.MetaGraphDef;
import org.tensorflow.framework.NodeDef;
import org.tensorflow.util.SaverDef;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
public final class NaiveBayesClassifier
{
public static void main(String[] args)
{
new NaiveBayesClassifier().run();
}
protected SavedModelBundle loadModule(Path source, String... tags) throws IOException
{
return SavedModelBundle.load(source.toAbsolutePath().normalize().toString(), tags);
}
public void run()
{
try (SavedModelBundle module = loadModule(Paths.get("universal-sentence-encoder"), "serve"))
{
Graph graph = module.graph();
try (Session session = new Session(graph, ConfigProto.newBuilder().
setGpuOptions(GPUOptions.newBuilder().setAllowGrowth(true)).
setAllowSoftPlacement(true).
build().toByteArray()))
{
Tensor<String> input = Tensors.create(new byte[][]
{
"hello".getBytes(StandardCharsets.UTF_8),
"world".getBytes(StandardCharsets.UTF_8)
});
List<Tensor<?>> result = session.runner().feed("serving_default_inputs", input).
addTarget("???").run();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
I used https://stackoverflow.com/a/51952478/14731 to scan the model for possible input/output nodes. I believe the input node is "serving_default_inputs" but I can't figure out the output node. More importantly, I don't have to specify any of these values when invoking the code in python through Keras so is there a way to do the same using the Java API?
UPDATE: Thanks to roywei I can now that confirm the input node is serving_default_input and output node is StatefulPartitionedCall_1 but when I plug these names into the aforementioned code I get:
2020-05-22 22:13:52.266287: W tensorflow/core/framework/op_kernel.cc:1651] OP_REQUIRES failed at lookup_table_op.cc:809 : Failed precondition: Table not initialized.
Exception in thread "main" java.lang.IllegalStateException: [_Derived_]{{function_node __inference_pruned_6741}} {{function_node __inference_pruned_6741}} Error while reading resource variable EncoderDNN/DNN/ResidualHidden_0/dense/kernel/part_25 from Container: localhost. This could mean that the variable was uninitialized. Not found: Resource localhost/EncoderDNN/DNN/ResidualHidden_0/dense/kernel/part_25/class tensorflow::Var does not exist.
[[{{node EncoderDNN/DNN/ResidualHidden_0/dense/kernel/ConcatPartitions/concat/ReadVariableOp_25}}]]
[[StatefulPartitionedCall_1/StatefulPartitionedCall]]
at libtensorflow#1.15.0/org.tensorflow.Session.run(Native Method)
at libtensorflow#1.15.0/org.tensorflow.Session.access$100(Session.java:48)
at libtensorflow#1.15.0/org.tensorflow.Session$Runner.runHelper(Session.java:326)
at libtensorflow#1.15.0/org.tensorflow.Session$Runner.run(Session.java:276)
Meaning, I still cannot invoke the model. What am I missing?
I figured it out after roywei pointed me in the right direction.
I needed to use SavedModuleBundle.session() instead of constructing my own instance. This is because the loader initializes the graph variables.
Instead of passing a ConfigProto to the Session constructor, I passed it into the SavedModelBundle loader instead.
I needed to use fetch() instead of addTarget() to retrieve the output tensor.
Here is the working code:
public final class NaiveBayesClassifier
{
public static void main(String[] args)
{
new NaiveBayesClassifier().run();
}
public void run()
{
try (SavedModelBundle module = loadModule(Paths.get("universal-sentence-encoder"), "serve"))
{
try (Tensor<String> input = Tensors.create(new byte[][]
{
"hello".getBytes(StandardCharsets.UTF_8),
"world".getBytes(StandardCharsets.UTF_8)
}))
{
MetaGraphDef metadata = MetaGraphDef.parseFrom(module.metaGraphDef());
Map<String, Shape> nameToInput = getInputToShape(metadata);
String firstInput = nameToInput.keySet().iterator().next();
Map<String, Shape> nameToOutput = getOutputToShape(metadata);
String firstOutput = nameToOutput.keySet().iterator().next();
System.out.println("input: " + firstInput);
System.out.println("output: " + firstOutput);
System.out.println();
List<Tensor<?>> result = module.session().runner().feed(firstInput, input).
fetch(firstOutput).run();
for (Tensor<?> tensor : result)
{
{
float[][] array = new float[tensor.numDimensions()][tensor.numElements() /
tensor.numDimensions()];
tensor.copyTo(array);
System.out.println(Arrays.deepToString(array));
}
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
/**
* Loads a graph from a file.
*
* #param source the directory containing to load from
* #param tags the model variant(s) to load
* #return the graph
* #throws NullPointerException if any of the arguments are null
* #throws IOException if an error occurs while reading the file
*/
protected SavedModelBundle loadModule(Path source, String... tags) throws IOException
{
// https://stackoverflow.com/a/43526228/14731
try
{
return SavedModelBundle.loader(source.toAbsolutePath().normalize().toString()).
withTags(tags).
withConfigProto(ConfigProto.newBuilder().
setGpuOptions(GPUOptions.newBuilder().setAllowGrowth(true)).
setAllowSoftPlacement(true).
build().toByteArray()).
load();
}
catch (TensorFlowException e)
{
throw new IOException(e);
}
}
/**
* #param metadata the graph metadata
* #return the first signature, or null
*/
private SignatureDef getFirstSignature(MetaGraphDef metadata)
{
Map<String, SignatureDef> nameToSignature = metadata.getSignatureDefMap();
if (nameToSignature.isEmpty())
return null;
return nameToSignature.get(nameToSignature.keySet().iterator().next());
}
/**
* #param metadata the graph metadata
* #return the output signature
*/
private SignatureDef getServingSignature(MetaGraphDef metadata)
{
return metadata.getSignatureDefOrDefault("serving_default", getFirstSignature(metadata));
}
/**
* #param metadata the graph metadata
* #return a map from an output name to its shape
*/
protected Map<String, Shape> getOutputToShape(MetaGraphDef metadata)
{
Map<String, Shape> result = new HashMap<>();
SignatureDef servingDefault = getServingSignature(metadata);
for (Map.Entry<String, TensorInfo> entry : servingDefault.getOutputsMap().entrySet())
{
TensorShapeProto shapeProto = entry.getValue().getTensorShape();
List<Dim> dimensions = shapeProto.getDimList();
long firstDimension = dimensions.get(0).getSize();
long[] remainingDimensions = dimensions.stream().skip(1).mapToLong(Dim::getSize).toArray();
Shape shape = Shape.make(firstDimension, remainingDimensions);
result.put(entry.getValue().getName(), shape);
}
return result;
}
/**
* #param metadata the graph metadata
* #return a map from an input name to its shape
*/
protected Map<String, Shape> getInputToShape(MetaGraphDef metadata)
{
Map<String, Shape> result = new HashMap<>();
SignatureDef servingDefault = getServingSignature(metadata);
for (Map.Entry<String, TensorInfo> entry : servingDefault.getInputsMap().entrySet())
{
TensorShapeProto shapeProto = entry.getValue().getTensorShape();
List<Dim> dimensions = shapeProto.getDimList();
long firstDimension = dimensions.get(0).getSize();
long[] remainingDimensions = dimensions.stream().skip(1).mapToLong(Dim::getSize).toArray();
Shape shape = Shape.make(firstDimension, remainingDimensions);
result.put(entry.getValue().getName(), shape);
}
return result;
}
}
There are two ways to get the names:
1) Using Java:
You can read the input and output names from the org.tensorflow.proto.framework.MetaGraphDef stored in saved model bundle.
Here is an example on how to extract the information:
https://github.com/awslabs/djl/blob/master/tensorflow/tensorflow-engine/src/main/java/ai/djl/tensorflow/engine/TfSymbolBlock.java#L149
2) Using python:
load the saved model in tensorflow python and print the names
loaded = tf.saved_model.load("path/to/model/")
print(list(loaded.signatures.keys()))
infer = loaded.signatures["serving_default"]
print(infer.structured_outputs)
I recommend to take a look at Deep Java Library, it automatically handle the input, output names.
It supports TensorFlow 2.1.0 and allows you to load Keras models as well as TF Hub Saved Model. Take a look at the documentation here and here
Feel free to open an issue if you have problem loading your model.
You can load TF model with Deep Java Library
System.setProperty("ai.djl.repository.zoo.location", "https://storage.googleapis.com/tfhub-modules/google/universal-sentence-encoder/1.tar.gz?artifact_id=encoder");
Criteria.Builder<NDList, NDList> builder =
Criteria.builder()
.setTypes(NDList.class, NDList.class)
.optArtifactId("ai.djl.localmodelzoo:encoder")
.build();
ZooModel<NDList, NDList> model = ModelZoo.loadModel(criteria);
See https://github.com/awslabs/djl/blob/master/docs/load_model.md#load-model-from-a-url for detail
I need to do the same, but seems still lots of missing pieces RE DJL usage. E.g., what to do after this?:
ZooModel<NDList, NDList> model = ModelZoo.loadModel(criteria);
I finally found an example in the DJL source code. The key take-away is to not use NDList for the input/output at all:
Criteria<String[], float[][]> criteria =
Criteria.builder()
.optApplication(Application.NLP.TEXT_EMBEDDING)
.setTypes(String[].class, float[][].class)
.optModelUrls(modelUrl)
.build();
try (ZooModel<String[], float[][]> model = ModelZoo.loadModel(criteria);
Predictor<String[], float[][]> predictor = model.newPredictor()) {
return predictor.predict(inputs.toArray(new String[0]));
}
See https://github.com/awslabs/djl/blob/master/examples/src/main/java/ai/djl/examples/inference/UniversalSentenceEncoder.java for the complete example.

How can I update custom properties in alfresco workflow task using only Java?

First, I want to say thanks to everyone that took their time to help me figure this out because I was searching for more than a week for a solution to my problem. Here it is:
My goal is to start a custom workflow in Alfresco Community 5.2 and to set some custom properties in the first task trough a web script using only the Public Java API. My class is extending AbstractWebScript. Currently I have success with starting the workflow and setting properties like bpm:workflowDescription, but I'm not able to set my custom properties in the tasks.
Here is the code:
public class StartWorkflow extends AbstractWebScript {
/**
* The Alfresco Service Registry that gives access to all public content services in Alfresco.
*/
private ServiceRegistry serviceRegistry;
public void setServiceRegistry(ServiceRegistry serviceRegistry) {
this.serviceRegistry = serviceRegistry;
}
#Override
public void execute(WebScriptRequest req, WebScriptResponse res) throws IOException {
// Create JSON object for the response
JSONObject obj = new JSONObject();
try {
// Check if parameter defName is present in the request
String wfDefFromReq = req.getParameter("defName");
if (wfDefFromReq == null) {
obj.put("resultCode", "1 (Error)");
obj.put("errorMessage", "Parameter defName not found.");
return;
}
// Get the WFL Service
WorkflowService workflowService = serviceRegistry.getWorkflowService();
// Build WFL Definition name
String wfDefName = "activiti$" + wfDefFromReq;
// Get WorkflowDefinition object
WorkflowDefinition wfDef = workflowService.getDefinitionByName(wfDefName);
// Check if such WorkflowDefinition exists
if (wfDef == null) {
obj.put("resultCode", "1 (Error)");
obj.put("errorMessage", "No workflow definition found for defName = " + wfDefName);
return;
}
// Get parameters from the request
Content reqContent = req.getContent();
if (reqContent == null) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Missing request body.");
}
String content;
content = reqContent.getContent();
if (content.isEmpty()) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST, "Content is empty");
}
JSONTokener jsonTokener = new JSONTokener(content);
JSONObject json = new JSONObject(jsonTokener);
// Set the workflow description
Map<QName, Serializable> params = new HashMap();
params.put(WorkflowModel.PROP_WORKFLOW_DESCRIPTION, "Workflow started from JAVA API");
// Start the workflow
WorkflowPath wfPath = workflowService.startWorkflow(wfDef.getId(), params);
// Get params from the POST request
Map<QName, Serializable> reqParams = new HashMap();
Iterator<String> i = json.keys();
while (i.hasNext()) {
String paramName = i.next();
QName qName = QName.createQName(paramName);
String value = json.getString(qName.getLocalName());
reqParams.put(qName, value);
}
// Try to update the task properties
// Get the next active task which contains the properties to update
WorkflowTask wfTask = workflowService.getTasksForWorkflowPath(wfPath.getId()).get(0);
// Update properties
WorkflowTask updatedTask = workflowService.updateTask(wfTask.getId(), reqParams, null, null);
obj.put("resultCode", "0 (Success)");
obj.put("workflowId", wfPath.getId());
} catch (JSONException e) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
e.getLocalizedMessage());
} catch (IOException ioe) {
throw new WebScriptException(Status.STATUS_BAD_REQUEST,
"Error when parsing the request.",
ioe);
} finally {
// build a JSON string and send it back
String jsonString = obj.toString();
res.getWriter().write(jsonString);
}
}
}
Here is how I call the webscript:
curl -v -uadmin:admin -X POST -d #postParams.json localhost:8080/alfresco/s/workflow/startJava?defName=nameOfTheWFLDefinition -H "Content-Type:application/json"
In postParams.json file I have the required pairs for property/value which I need to update:
{
"cmprop:propOne" : "Value 1",
"cmprop:propTwo" : "Value 2",
"cmprop:propThree" : "Value 3"
}
The workflow is started, bpm:workflowDescription is set correctly, but the properties in the task are not visible to be set.
I made a JS script which I call when the workflow is started:
execution.setVariable('bpm_workflowDescription', 'Some String ' + execution.getVariable('cmprop:propOne'));
And actually the value for cmprop:propOne is used and the description is properly updated - which means that those properties are updated somewhere (on execution level maybe?) but I cannot figure out why they are not visible when I open the task.
I had success with starting the workflow and updating the properties using the JavaScript API with:
if (wfdef) {
// Get the params
wfparams = {};
if (jsonRequest) {
for ( var prop in jsonRequest) {
wfparams[prop] = jsonRequest[prop];
}
}
wfpackage = workflow.createPackage();
wfpath = wfdef.startWorkflow(wfpackage, wfparams);
The problem is that I only want to use the public Java API, please help.
Thanks!
Do you set your variables locally in your tasks? From what I see, it seems that you define your variables at the execution level, but not at the state level. If you take a look at the ootb adhoc.bpmn20.xml file (https://github.com/Activiti/Activiti-Designer/blob/master/org.activiti.designer.eclipse/src/main/resources/templates/adhoc.bpmn20.xml), you can notice an event listener that sets the variable locally:
<extensionElements>
<activiti:taskListener event="create" class="org.alfresco.repo.workflow.activiti.tasklistener.ScriptTaskListener">
<activiti:field name="script">
<activiti:string>
if (typeof bpm_workflowDueDate != 'undefined') task.setVariableLocal('bpm_dueDate', bpm_workflowDueDate);
if (typeof bpm_workflowPriority != 'undefined') task.priority = bpm_workflowPriority;
</activiti:string>
</activiti:field>
</activiti:taskListener>
</extensionElements>
Usually, I just try to import all tasks for my custom model prefix. So for you, it should look like that:
import java.util.Set;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.apache.log4j.Logger;
public class ImportVariables extends AbstractTaskListener {
private Logger logger = Logger.getLogger(ImportVariables.class);
#Override
public void notify(DelegateTask task) {
logger.debug("Inside ImportVariables.notify()");
logger.debug("Task ID:" + task.getId());
logger.debug("Task name:" + task.getName());
logger.debug("Task proc ID:" + task.getProcessInstanceId());
logger.debug("Task def key:" + task.getTaskDefinitionKey());
DelegateExecution execution = task.getExecution();
Set<String> executionVariables = execution.getVariableNamesLocal();
for (String variableName : executionVariables) {
// If the variable starts by "cmprop_"
if (variableName.startsWith("cmprop_")) {
// Publish it at the task level
task.setVariableLocal(variableName, execution.getVariableLocal(variableName));
}
}
}
}

Spring REST Web Service | Update an XML and send it in response

I am working on a Spring Restful Web service wherein I am returning an xml file as a response. This XML file is placed inside the main/resources folder of the MAVEN project build in eclipse. The service accepts certain parameters from the caller and based on those parameters, it should update the XML file. This project is deployed as WAR in the production server. On my local project, I can see the xml file being updated but in the production server it is not. How can I get this working in the production server ?
Below is the code for controller accepting the incoming request
#RestController
public class HelloWorldRestController {
#Autowired
UserService userService; // Service which will do all data
// retrieval/manipulation work
#Autowired
DialogServiceXml dialogService;
// Returning an xml file in the response
#CrossOrigin(origins = "*")
#RequestMapping(value = "/getUpdatedDialog", method = RequestMethod.POST, produces = "application/xml")
public ResponseEntity<InputStreamResource> downloadXMLFile(#RequestBody Dialog dialog,
UriComponentsBuilder ucBuilder) throws IOException {
// Update the xml file named : "mor_dialog.xml"
dialogService.updateXml(new StringBuilder(dialog.getClassName()), new StringBuilder(dialog.getResponse()));
// Pick up the updated file from the classpath
ClassPathResource xmlFile = null;
try {
xmlFile = new ClassPathResource("mor_dialog.xml");
} catch (Exception exception) {
exception.printStackTrace();
}
// Code to prevent caching so that always the latest version of the file
// is being sent.
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Cache-Control", "no-cache, np-store, must-revalidate");
httpHeaders.add("Pragma", "no-cache");
httpHeaders.add("Expires", "0");
//httpHeaders.add("Access-Control-Allow-Origin", "http://nlc-mor-furniture.mybluemix.net");
return ResponseEntity.ok().headers(httpHeaders).contentLength(xmlFile.contentLength())
.contentType(MediaType.parseMediaType("application/octet-stream"))
.body(new InputStreamResource(xmlFile.getInputStream()));
}
}
Below is the class that unmarshals the XML, updates it based on the input parameters, then marshals it back
#Service("dialogService")
public class DialogServiceXml implements DialogServiceXmlImpl {
#SuppressWarnings({ "rawtypes", "unchecked" })
#Override
public void updateXml(StringBuilder className, StringBuilder response) {
JAXBContext jaxbContext = null;
ClassLoader classLoader = getClass().getClassLoader();
try {
jaxbContext = JAXBContext.newInstance("com.sau.watson.dialog.xsd.beans");
Unmarshaller JAXBUnmarshaller = jaxbContext.createUnmarshaller();
Marshaller JAXBMarshaller = jaxbContext.createMarshaller();
JAXBMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
JAXBMarshaller.setProperty(Marshaller.JAXB_NO_NAMESPACE_SCHEMA_LOCATION, "WatsonDialogDocument_1.0.xsd");
File mor_dialog = new File(classLoader.getResource("mor_dialog.xml").getFile());
//File mor_dialog = new File(classLoader.getResource("../../mor_dialog.xml").getFile());
mor_dialog.setWritable(true);
//File mor_dialog_updated = new File(classLoader.getResource("mor_dialog_updated.xml").getFile());
InputStream is = new FileInputStream(mor_dialog);
JAXBElement dialog = (JAXBElement) JAXBUnmarshaller.unmarshal(is);
is.close();
//JAXBElement dialog = (JAXBElement) JAXBUnmarshaller.unmarshal(new FileInputStream("src/main/java/com/sau/watson/dialog/xml/mor_dialog.xml"));
DialogType dialogType = (DialogType) dialog.getValue();
// System.out.println(dialogType.toString());
// System.out.println(dialogType);
FlowType flowType = (FlowType) dialogType.getFlow();
for (FolderNodeType folderNodeType : flowType.getFolder()) {
// System.out.println(folderNodeType.getLabel());
if (folderNodeType.getLabel().equalsIgnoreCase("Library")) {
for (ChatflowNode libChatFlowNode : folderNodeType.getInputOrOutputOrDefault()) {
FolderNodeType libraryFolderNode = (FolderNodeType) libChatFlowNode;
// System.out.println(libraryFolderNode.getId());
// System.out.println(libraryFolderNode.getLabel());
StringBuilder classNameFromXml = new StringBuilder();
for (ChatflowNode node : libraryFolderNode.getInputOrOutputOrDefault()) {
InputNodeType inputNodeType = (InputNodeType) node;
// Getting the class. Class name are encapsulated
// inside the <grammar> node
/**
* <grammar> <item>Salesperson_Great</item>
* <item>Great</item> </grammar>
*/
for (Object grammerTypeObj : inputNodeType.getActionOrScriptOrGrammar()) {
GrammarType grammarType = (GrammarType) grammerTypeObj;
// We are always getting the first item as it is
// assumed that there is only one class in each
// grammar node
classNameFromXml
.append(grammarType.getItemOrSourceOrParam().get(0).getValue().toString());
System.out.println("Class Name is : " + className);
}
// We are always getting the first item as it is
// assumed that there is only one class in each
// grammar node
/*
* List<Object> grammarTypeObj =
* inputNodeType.getActionOrScriptOrGrammar();
* GrammarType grammarType = (GrammarType)
* grammarTypeObj;
*
* String className =
* grammarType.getItemOrSourceOrParam().get(0).
* getValue().toString();
*
* System.out.println("Class Name is : "+className);
*/
if (!classNameFromXml.toString().equalsIgnoreCase(className.toString())) {
continue;
}
// Getting all the response items corresponding to
// this class
for (ChatflowNode outputNodeObj : inputNodeType.getInputOrOutputOrDefault()) {
OutputNodeType outputNode = (OutputNodeType) outputNodeObj;
for (Object promptTypeObj : outputNode.getActionOrScriptOrPrompt()) {
PromptType promptType = (PromptType) promptTypeObj;
List<Serializable> responseItemObjs = promptType.getContent();
for (Object responseItemObj : responseItemObjs) {
/*
* if (responseItemObj instanceof
* String) {
* System.out.println(((String)
* responseItemObj).trim()); }
*/
if (responseItemObj instanceof JAXBElement) {
// System.out.println("JAXBElement
// Instance");
JAXBElement responseItem = (JAXBElement) responseItemObj;
System.out.println("The old response is : " + responseItem.getValue().toString());
responseItem.setValue(response.toString());
}
}
}
}
}
}
}
}
FileOutputStream os = new FileOutputStream(mor_dialog);
JAXBMarshaller.marshal(dialog, os);
//os.flush();
os.close();
//JAXBMarshaller.marshal(dialog, new FileOutputStream("src/main/java/com/sau/watson/dialog/xml/mor_dialog.xml"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
The src/main/resources folder is only available on your development machine before maven builds the war file. After building the war the resources are added to the war file from the root of the classpath.
If you want to be updating the file then you probably want to access the file from the file system rather than from the classpath.

Reading drools rules in rest java

I'm trying to read .drl drools rules in my REST with Java (JAX-RS) using Jersey.
I put my .drl files in WEB-INF/rules folder, and tried to read them with this lines of code
private RuleBase trainingRules;
private RuleBase kuperMaleTrainingResultsRules;
private RuleBase kuperFemaleTrainingResultsRules;
private RuleBase basicTrainingResultsRules;
private final String trainingRulesPath = "/WEB-INF/rules/ZatraziTrening.drl";
private final String kuperMaleTrainingResultsPath = "/WEB-INF/rules/KuperMuski.drl";
private final String kuperFemaleTrainingResultsPath = "/WEB-INF/rules/KuperZenski.drl";
private final String trainingResultsRulesPath = "/WEB-INF/rules/RezultatiTreninga.drl";
private static ControllerDrools INSTANCE;
private ControllerDrools() {
try {
this.trainingRules = loadRules(trainingRulesPath);
this.kuperMaleTrainingResultsRules = loadRules(kuperMaleTrainingResultsPath);
this.kuperFemaleTrainingResultsRules = loadRules(kuperFemaleTrainingResultsPath);
this.basicTrainingResultsRules = loadRules(trainingResultsRulesPath);
} catch (DroolsParserException | IOException e) {
// TODO: dodati ispis poruke u logger
e.printStackTrace();
}
}
private RuleBase loadRules(String rulesPath) throws DroolsParserException, IOException {
Reader source = new InputStreamReader(ControllerDrools.class.getResourceAsStream(rulesPath));
PackageBuilder builder = new PackageBuilder();
builder.addPackageFromDrl(source);
Package pkg = builder.getPackage();
// Kreiranje baze znanja i dodavanje paketa u nju
RuleBase ruleBase = RuleBaseFactory.newRuleBase();
ruleBase.addPackage(pkg);
return ruleBase;
}
public static ControllerDrools getInstance() {
if (INSTANCE == null) {
INSTANCE = new ControllerDrools();
}
return INSTANCE;
}
/**
* Get's the training from drools
* #param user
* #return training to do
*/
public Training getTrening(User user) {
user.setNumberOfTrainingInCategory(user.getNumberOfTrainingInCategory() + 1);
Training training = new Training();
training.setUser(user);
try {
WorkingMemory workingMemory = trainingRules.newStatefulSession();
workingMemory.insert(user);
workingMemory.insert(training);
workingMemory.insert(user.getCategory());
workingMemory.fireAllRules();
} catch (Exception e) {
// TODO: logger
e.printStackTrace();
}
return training;
}
but i get
java.lang.NullPointerException
java.io.Reader.<init>(Unknown Source)
java.io.InputStreamReader.<init>(Unknown Source)
loadRules(ControllerDrools.java:48)
which is this line
Reader source = new InputStreamReader(ControllerDrools.class.getResourceAsStream(rulesPath));
Any body knows how to read this rules ? Where to put them ?
Thank you very much for reading this, it means a lot to me.
Using ControllerDrools.class.getResourceAsStream(rulesPath), your path should be relative from your ControllerDrools class package.
To make your path absolute, you should add a leading slash "/rules/ZatraziTrening.drl"
You can also use the following syntax to have absolute path :
this.getClass().getClassLoader().getResourceAsStream(rulesPath)
If you use maven, i advise you to put drl files directly in "src/main/resources"

Calling Existing PipeLine in GATE

I am new to Java and I want to call my saved pipeline using GATE JAVA API through Eclipse
I am not sure how I could do this although I know how to create new documents etc
FeatureMap params = Factory.newFeatureMap();
params.put(Document.DOCUMENT_URL_PARAMETER_NAME, new URL("http://www.gate.ac.uk"));
params.put(Document.DOCUMENT_ENCODING_PARAMETER_NAME, "UTF-8");
// document features
FeatureMap feats = Factory.newFeatureMap();
feats.put("date", new Date());
Factory.createResource("gate.corpora.DocumentImpl", params, feats, "This is home");
//End Solution 2
// obtain a map of all named annotation sets
Document doc = Factory.newDocument("Document text");
Map <String, AnnotationSet> namedASes = doc.getNamedAnnotationSets();
System.out.println("No. of named Annotation Sets:" + namedASes.size());
// no of annotations each set contains
for (String setName : namedASes.keySet()) {
// annotation set
AnnotationSet aSet = namedASes.get(setName);
// no of annotations
System.out.println("No. of Annotations for " +setName + ":" + aSet.size());
There is a good example of GATE usage from java. Probably it does exactly what you want. BatchProcessApp.java.
In particular:
loading pipeline is done with lines
// load the saved application
CorpusController application =
(CorpusController)PersistenceManager.loadObjectFromFile(gappFile);
pipeli executed with
// run the application
application.execute();
Code is informative, clear and could be easy changed for your particular needs. The oxygen of open source project :)
Something like this could be used(do not forget to init GATE: set GATE home and etc):
private void getProcessedText(String textToProcess) {
Document gateDocument = null;
try {
// you can use your method from above to build document
gateDocument = createGATEDocument(textToProcess);
corpusController.getCorpus().add(gateDocument);
corpusController.execute();
// put here your annotations processing
} catch (Throwable ex) {
ex.printStackTrace();
} finally {
if (corpusController.getCorpus() != null) {
corpusController.getCorpus().remove(gateDocument);
}
if (gateDocument != null) {
Factory.deleteResource(gateDocument);
}
}
}
private CorpusController initPersistentGateResources() {
try {
Corpus corpus = Factory.newCorpus("New Corpus");
corpusController = (CorpusController) PersistenceManager.loadObjectFromFile(new File("PATH-TO-YOUR-GAPP-FILE"));
corpusController.setCorpus(corpus);
} catch (Exception ex) {
ex.printStackTrace();
}
return corpusController;
}

Categories