| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.stanbol.enhancer.servicesapi.helper; |
| |
| import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.get; |
| import static org.apache.stanbol.enhancer.servicesapi.helper.EnhancementEngineHelper.getReference; |
| import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getEngine; |
| import static org.apache.stanbol.enhancer.servicesapi.helper.ExecutionPlanHelper.getExecutionNodes; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.CHAIN_EXECUTION; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.COMPLETED; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENGINE_EXECUTION; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENHANCED_BY; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.ENHANCES; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.EXECUTION; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.EXECUTION_NODE; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.EXECUTION_PART; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.EXECUTION_PLAN; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.IS_DEFAULT_CHAIN; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STARTED; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_COMPLETED; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_FAILED; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_IN_PROGRESS; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_MESSAGE; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_SCHEDULED; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata.STATUS_SKIPPED; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan.CHAIN; |
| import static org.apache.stanbol.enhancer.servicesapi.rdf.Properties.RDF_TYPE; |
| |
| import java.util.Date; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.clerezza.rdf.core.BNode; |
| import org.apache.clerezza.rdf.core.Literal; |
| import org.apache.clerezza.rdf.core.LiteralFactory; |
| import org.apache.clerezza.rdf.core.MGraph; |
| import org.apache.clerezza.rdf.core.NonLiteral; |
| import org.apache.clerezza.rdf.core.Resource; |
| import org.apache.clerezza.rdf.core.Triple; |
| import org.apache.clerezza.rdf.core.TripleCollection; |
| import org.apache.clerezza.rdf.core.UriRef; |
| import org.apache.clerezza.rdf.core.impl.PlainLiteralImpl; |
| import org.apache.clerezza.rdf.core.impl.TripleImpl; |
| import org.apache.stanbol.commons.indexedgraph.IndexedMGraph; |
| import org.apache.stanbol.enhancer.servicesapi.Chain; |
| import org.apache.stanbol.enhancer.servicesapi.ContentItem; |
| import org.apache.stanbol.enhancer.servicesapi.EnhancementJobManager; |
| import org.apache.stanbol.enhancer.servicesapi.NoSuchPartException; |
| import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionMetadata; |
| import org.apache.stanbol.enhancer.servicesapi.rdf.ExecutionPlan; |
| /** |
| * This class defines utility methods for writing and updating |
| * Execution Metadata. This will be usually needed by |
| * {@link EnhancementJobManager} implementations. |
| * @author Rupert Westenthaler |
| * |
| */ |
| public class ExecutionMetadataHelper { |
| |
| private static final LiteralFactory lf = LiteralFactory.getInstance(); |
| |
| public static NonLiteral createChainExecutionNode(MGraph graph, NonLiteral executionPlan, |
| UriRef ciUri, boolean defaultChain){ |
| NonLiteral node = new BNode(); |
| graph.add(new TripleImpl(node, RDF_TYPE, EXECUTION)); |
| graph.add(new TripleImpl(node, RDF_TYPE, CHAIN_EXECUTION)); |
| graph.add(new TripleImpl(node, ENHANCES, ciUri)); |
| graph.add(new TripleImpl(ciUri, ENHANCED_BY, node)); |
| graph.add(new TripleImpl(node, STATUS, STATUS_SCHEDULED)); |
| graph.add(new TripleImpl(node, EXECUTION_PLAN, executionPlan)); |
| graph.add(new TripleImpl(node, IS_DEFAULT_CHAIN, |
| lf.createTypedLiteral(defaultChain))); |
| return node; |
| } |
| |
| public static NonLiteral createEngineExecution(MGraph graph, NonLiteral chainExecution, |
| NonLiteral executionNode){ |
| |
| NonLiteral node = new BNode(); |
| graph.add(new TripleImpl(node, RDF_TYPE, EXECUTION)); |
| graph.add(new TripleImpl(node, RDF_TYPE, ENGINE_EXECUTION)); |
| graph.add(new TripleImpl(node, EXECUTION_PART, chainExecution)); |
| graph.add(new TripleImpl(node, EXECUTION_NODE, executionNode)); |
| graph.add(new TripleImpl(node, STATUS, STATUS_SCHEDULED)); |
| return node; |
| } |
| /** |
| * Sets the state of the ExecutionNode to completed |
| * @param graph |
| * @param execution |
| * @param message An optional message |
| */ |
| public static void setExecutionCompleted(MGraph graph,NonLiteral execution,String message){ |
| Literal dateTime = lf.createTypedLiteral(new Date()); |
| setStatus(graph, execution,STATUS_COMPLETED); |
| graph.add(new TripleImpl(execution, COMPLETED, dateTime)); |
| if(message != null){ |
| graph.add(new TripleImpl(execution, STATUS_MESSAGE, new PlainLiteralImpl(message))); |
| } |
| } |
| /** |
| * Sets the state of the ExecutionNode to scheduled and deletes any started, |
| * completed times |
| * @param graph the graph holding the execution metadata |
| * @param execution the execution node |
| */ |
| public static void setExecutionScheduled(MGraph graph,NonLiteral execution){ |
| setStatus(graph, execution,STATUS_SCHEDULED); |
| Iterator<Triple> it = graph.filter(execution, STARTED, null); |
| while(it.hasNext()){ |
| it.next(); |
| it.remove(); |
| } |
| it = graph.filter(execution, COMPLETED, null); |
| while(it.hasNext()){ |
| it.next(); |
| it.remove(); |
| } |
| } |
| /** |
| * Set the parsed execution node to failed. |
| * @param graph |
| * @param execution |
| * @param message An message describing why the execution failed |
| */ |
| public static void setExecutionFaild(MGraph graph,NonLiteral execution,String message){ |
| Literal dateTime = lf.createTypedLiteral(new Date()); |
| setStatus(graph, execution,STATUS_FAILED); |
| graph.add(new TripleImpl(execution, COMPLETED, dateTime)); |
| if(message != null){ |
| graph.add(new TripleImpl(execution, STATUS_MESSAGE, new PlainLiteralImpl(message))); |
| } else { |
| throw new IllegalArgumentException("For faild Execution a STATUS message is required!"); |
| } |
| } |
| /** |
| * Sets an execution node to skipped. This sets both the start and the completed |
| * time to the current time. |
| * @param graph |
| * @param execution |
| * @param message An optional message why this execution was skipped |
| */ |
| public static void setExecutionSkipped(MGraph graph,NonLiteral execution,String message){ |
| Literal dateTime = lf.createTypedLiteral(new Date()); |
| setStatus(graph, execution,STATUS_SKIPPED); |
| graph.add(new TripleImpl(execution, STARTED, dateTime)); |
| graph.add(new TripleImpl(execution, COMPLETED, dateTime)); |
| if(message != null){ |
| graph.add(new TripleImpl(execution, STATUS_MESSAGE, new PlainLiteralImpl(message))); |
| } |
| } |
| /** |
| * Sets an execution node to in-progress. This also sets the start time to |
| * the current time |
| * @param graph |
| * @param execution |
| */ |
| public static void setExecutionInProgress(MGraph graph,NonLiteral execution){ |
| Literal dateTime = lf.createTypedLiteral(new Date()); |
| setStatus(graph, execution,STATUS_IN_PROGRESS); |
| graph.add(new TripleImpl(execution, STARTED, dateTime)); |
| } |
| |
| /** |
| * Removes the current value of {@link ExecutionMetadata#STATUS} and set it |
| * to the parsed value. |
| * @param graph |
| * @param execution |
| */ |
| private static void setStatus(MGraph graph, NonLiteral execution, UriRef status) { |
| Iterator<Triple> it = graph.filter(execution, STATUS, null); |
| while(it.hasNext()){ |
| it.next(); |
| it.remove(); |
| } |
| if(status != null){ |
| graph.add(new TripleImpl(execution, STATUS, status)); |
| } |
| } |
| |
| /** |
| * Getter for the {@link ExecutionMetadata#CHAIN_EXECUTION} node of an |
| * graph containing ChainExecution metadata for the parsed {@link Chain#getName()}. |
| * If both the execution metadata and the execution plan are in the same |
| * graph one need to parse the same triple collection instance for both |
| * the execution metadata and the execution plan. |
| * @param em the triple collection containing execution metadata |
| * @param ep the triple collection containing the execution plan |
| * @param chainName the name of the executed chain |
| * @return the node or <code>null</code> if not found. |
| */ |
| public static final NonLiteral getChainExecutionForChainName(TripleCollection em, TripleCollection ep, String chainName){ |
| final NonLiteral executionPlanNode = ExecutionPlanHelper.getExecutionPlan(ep, chainName); |
| if(executionPlanNode == null){ |
| return null; |
| } else { |
| return getChainExecutionForExecutionPlan(em, executionPlanNode); |
| } |
| } |
| |
| /** |
| * Getter for the {@link ExecutionMetadata#CHAIN_EXECUTION} node of an |
| * graph containing ChainExecution metadata for the parsed |
| * {@link ExecutionPlan#EXECUTION_PLAN} node |
| * @param graph the graph containing the Execution Metadata |
| * @param executionPlanNode the {@link ExecutionPlan#EXECUTION_PLAN} node |
| * @return the {@link ExecutionMetadata#CHAIN_EXECUTION} node |
| */ |
| public static NonLiteral getChainExecutionForExecutionPlan(TripleCollection graph, final NonLiteral executionPlanNode) { |
| if(graph == null){ |
| throw new IllegalArgumentException("The parsed graph with the execution metadata MUST NOT be NULL!"); |
| } |
| if(executionPlanNode == null){ |
| throw new IllegalArgumentException("The parsed execution plan node MUST NOT be NULL!"); |
| } |
| Iterator<Triple> it = graph.filter(null, ExecutionMetadata.EXECUTION_PLAN, executionPlanNode); |
| if(it.hasNext()){ |
| return it.next().getSubject(); |
| } else { |
| return null; |
| } |
| } |
| |
| /** |
| * Getter/Initialiser for the execution metadata content part of the parsed |
| * content item. This part is expected to be registered with the URI |
| * {@link ExecutionMetadata#CHAIN_EXECUTION}. If it does not already exist |
| * this method creates an empty graph and register it with the parsed |
| * content item otherwise it returns the existing part registered under that |
| * URI.<p> |
| * Typically users will also want to use |
| * {@link #initExecutionMetadata(MGraph, TripleCollection, UriRef, String, boolean)} |
| * to initialise the state based on the grpah returned by this method. |
| * NOTES:<ul> |
| * <li> If a content part is registered under the URI |
| * {@link ExecutionMetadata#CHAIN_EXECUTION} that is not of type |
| * {@link MGraph} this method will replace it with an empty {@link MGraph}. |
| * <li> This method acquires a write lock on the content item while checking |
| * for the content part. |
| * </ul> |
| * @param contentItem the contentItem |
| * @return the {@link MGraph} with the execution metadata as registered as |
| * content part with the URI {@link ExecutionMetadata#CHAIN_EXECUTION} to |
| * the {@link ContentItem} |
| * @throws IllegalArgumentException if the parsed content itme is <code>null</code>. |
| */ |
| public static MGraph initExecutionMetadataContentPart(ContentItem contentItem) { |
| if(contentItem == null){ |
| throw new IllegalArgumentException("The parsed ContentItme MUST NOT be NULL!"); |
| } |
| MGraph executionMetadata; |
| contentItem.getLock().writeLock().lock(); |
| try { |
| try { |
| executionMetadata = contentItem.getPart(CHAIN_EXECUTION, MGraph.class); |
| } catch (NoSuchPartException e) { |
| executionMetadata = new IndexedMGraph(); |
| contentItem.addPart(CHAIN_EXECUTION, executionMetadata); |
| } |
| } finally { |
| contentItem.getLock().writeLock().unlock(); |
| } |
| return executionMetadata; |
| } |
| |
| /** |
| * Initialises execution metadata based on the parsed parameter. If the parsed |
| * graph with the execution metadata is empty it will initialise the metadata |
| * based on the execution plan. If there are already metadata in the graph |
| * it will initialise the returned map based on the existing data.<p> |
| * This method can be therefore used to both:<ul> |
| * <li> create a new set of execution metadata: as needed before a |
| * {@link EnhancementJobManager} implementation can start processing a |
| * {@link ContentItem} by using an {@link Chain} |
| * <li> read existing executionMetadata allowing to let an |
| * {@link EnhancementJobManager} to continue from an uncompleted enhancement. |
| * </ul><p> |
| * If both the execution metadata and the execution plan are stored within the |
| * same graph users need to base this graph as both the first and second |
| * parameter |
| * @param em The graph containing the execution metadata. MUST NOT be NULL |
| * @param ep The graph containing the execution plan. MUST NOT be NULL |
| * @param ciUri the URI of the content item. MUST NOT be NULL |
| * @param chainName the name of the chain to execute. May be NULL if |
| * initialising from existing metadata. MUST NOT be NULL if initialising from |
| * empty execution metadata |
| * @param isDefaultChain if the chain to execute is the default chain. Will be |
| * ignored if initialising from existing execution metadata. MUST NOT be NULL |
| * if initialising from empty execution metadata |
| * @return A map containing all em:Execution nodes as key and the according |
| * ep:ExecutionNode of the execution plan as values. |
| * @throws IllegalArgumentException if any of the requirements stated in the |
| * documentation for the parameters is not fulfilled. |
| */ |
| public static final Map<NonLiteral,NonLiteral> initExecutionMetadata(MGraph em, TripleCollection ep, UriRef ciUri, String chainName, Boolean isDefaultChain){ |
| if(em == null){ |
| throw new IllegalArgumentException("The parsed ExecutionMetadata graph MUST NOT be NULL!"); |
| } |
| if(ciUri == null){ |
| throw new IllegalArgumentException("The parsed URI of the contentItem MUST NOT be NULL!"); |
| } |
| //1. check for the ChainExecution node for the parsed content item |
| final NonLiteral executionPlanNode; |
| NonLiteral chainExecutionNode = getChainExecutionForExecutionPlan(em, ciUri); |
| if(chainExecutionNode != null){ //init from existing executin metadata |
| // -> chainName and isDefaultChain may be null |
| //init from existing |
| executionPlanNode = getExecutionPlanNode(em, chainExecutionNode); |
| if(executionPlanNode == null){ |
| throw new IllegalArgumentException("The em:ChainExecution '" |
| + chainExecutionNode+"'that enhances ContentItem '" |
| + ciUri +"' does not define a link to an valid ExecutionPlan"); |
| } |
| isDefaultChain = get(em, chainExecutionNode, IS_DEFAULT_CHAIN, Boolean.class, lf); |
| String extractedChainName = EnhancementEngineHelper.getString(ep, executionPlanNode, CHAIN); |
| if(extractedChainName == null){ |
| throw new IllegalArgumentException("The em:ChainExecution '" |
| + chainExecutionNode + "'that enhances ContentItem '" |
| + ciUri + "' links to the ep:ExecutionPlan '" |
| + executionPlanNode+"' that does not define a ChainName (property: " |
| + CHAIN + ")!"); |
| } |
| if(chainName == null){ |
| chainName = extractedChainName; |
| } else if(!chainName.equals(extractedChainName)){ |
| throw new IllegalArgumentException("The em:ChainExecution '" |
| + chainExecutionNode + "'that enhances ContentItem '" |
| + ciUri + "' links to the ep:ExecutionPlan '" |
| + executionPlanNode + "' with the chain name '" |
| + extractedChainName + "' but '"+chainName+"' was parsed " |
| + "as expected chain name!"); |
| } |
| } else { //create a new one |
| // -> in that case chainName and isDefaultChain are required |
| executionPlanNode = ExecutionPlanHelper.getExecutionPlan(ep, chainName); |
| if(executionPlanNode == null){ |
| throw new IllegalArgumentException("The parsed ExectuonPlan graph does not contain an" + |
| "ExecutionPlan for a Chain with the name '"+chainName+"'!"); |
| } |
| if(isDefaultChain == null){ |
| throw new IllegalArgumentException("The isDefaultChain parameter MUST NOT" + |
| "be NULL if initialising from empty ExecutionMetadata!"); |
| } |
| chainExecutionNode = createChainExecutionNode(em, executionPlanNode, ciUri, isDefaultChain); |
| } |
| //2. check/init the EngineExecution nodes for for the ExecutionNodes of the ExecutionPlan |
| Map<NonLiteral,NonLiteral> executionsMap = new HashMap<NonLiteral,NonLiteral>(); |
| Set<NonLiteral> executionNodes = getExecutionNodes(ep, executionPlanNode); |
| Set<NonLiteral> executions = getExecutions(em, chainExecutionNode); |
| for(NonLiteral en : executionNodes) { |
| Iterator<Triple> it = em.filter(null, EXECUTION_NODE, en); |
| NonLiteral execution; |
| if(it.hasNext()){ |
| execution = it.next().getSubject(); |
| if(!executions.contains(execution)){ |
| throw new IllegalStateException("Execution '"+execution |
| + "' for ExecutionNode '"+en+"' (engine: '"+getEngine(ep, en) |
| + "') is not part of ChainExecution '" |
| + chainExecutionNode +"' (chain: '"+chainName+")!"); |
| } |
| } else { |
| execution = createEngineExecution(em, chainExecutionNode, en); |
| executions.add(execution); |
| } |
| executionsMap.put(execution,en); |
| } |
| //3. check that there are no executions that are not part of the |
| // parsed ExecutionPlan |
| for(NonLiteral e : executions){ |
| if(!executionsMap.containsKey(e)){ |
| NonLiteral en = getExecutionNode(em, e); |
| throw new IllegalStateException("ChainExecution '" |
| + chainExecutionNode +"' (chain: '"+chainName+") contains" |
| + "Execution '"+e+"' for ExecutionNode '" + en |
| + "' (engine: '"+ExecutionPlanHelper.getEngine(ep, en) |
| + "') that is not part of the pased ExecutionPlan '" |
| + executionPlanNode +"'(chain; '"+chainName+"')!"); |
| } |
| } |
| return executionsMap; |
| } |
| /** |
| * Getter for the ep:ExecutionNode for a given em:Execution. |
| * @param graph the graph containing the execution metadata |
| * @param execution the em:Execution node |
| * @return the ep:ExecutionNode node |
| */ |
| public static NonLiteral getExecutionNode(TripleCollection graph, NonLiteral execution){ |
| Iterator<Triple> it = graph.filter(execution, EXECUTION_NODE, null); |
| if(it.hasNext()){ |
| Triple t = it.next(); |
| Resource o = t.getObject(); |
| if(o instanceof NonLiteral){ |
| return (NonLiteral)o; |
| } else { |
| throw new IllegalStateException("Value of property "+ EXECUTION_NODE |
| + "MUST BE of type NonLiteral (triple: '"+t+"')!"); |
| } |
| } else { |
| //maybe an em:ChainExecution |
| return null; |
| } |
| } |
| |
| /** |
| * Get {@link ExecutionMetadata#EXECUTION} nodes that are |
| * {@link ExecutionMetadata#EXECUTION_PART} of the parsed |
| * {@link ExecutionMetadata#CHAIN_EXECUTION} node |
| * @param em the graph with the execution metadata |
| * @param chainExecutionNode the chain execution node |
| * @return the Set with all execution part of the chain execution |
| */ |
| public static Set<NonLiteral> getExecutions(TripleCollection em, NonLiteral chainExecutionNode) { |
| if(em == null){ |
| throw new IllegalArgumentException("The parsed graph with the Execution metadata MUST NOT be NULL!"); |
| } |
| if(chainExecutionNode == null){ |
| throw new IllegalArgumentException("The parsed chain execution plan node MUST NOT be NULL!"); |
| } |
| Set<NonLiteral> executionNodes = new HashSet<NonLiteral>(); |
| Iterator<Triple> it = em.filter(null, ExecutionMetadata.EXECUTION_PART, chainExecutionNode); |
| while(it.hasNext()){ |
| executionNodes.add(it.next().getSubject()); |
| } |
| return executionNodes; |
| } |
| |
| /** |
| * Getter for the ep:ExecutionPlan node for the parsed em:ChainExecution node |
| * @param em the execution metadata |
| * @param chainExecutionNode the chain execution node |
| * @return the execution plan node |
| */ |
| public static NonLiteral getExecutionPlanNode(TripleCollection em, NonLiteral chainExecutionNode){ |
| Iterator<Triple> it = em.filter(chainExecutionNode, EXECUTION_PLAN, null); |
| if(it.hasNext()){ |
| Triple t = it.next(); |
| Resource r = t.getObject(); |
| if(r instanceof NonLiteral){ |
| return (NonLiteral)r; |
| } else { |
| throw new IllegalStateException("Value of the property "+EXECUTION_PLAN |
| + " MUST BE a NonLiteral (triple: '"+t+"')!"); |
| } |
| } else { |
| return null; |
| } |
| |
| } |
| /** |
| * Getter for the ChainExecution used to enhance the content item |
| * @param em the graph with the execution metadata |
| * @param ciUri the ID of the content item |
| * @return the node that {@link ExecutionMetadata#ENHANCES} the {@link ContentItem} |
| */ |
| public static NonLiteral getChainExecution(TripleCollection em, UriRef ciUri){ |
| Iterator<Triple> it = em.filter(null, ENHANCES, ciUri); |
| if(it.hasNext()){ |
| return it.next().getSubject(); |
| } else { |
| return null; |
| } |
| } |
| /** |
| * Tests if the {@link ExecutionMetadata#STATUS status} if an |
| * {@link ExecutionMetadata#EXECUTION execution} is |
| * {@link ExecutionMetadata#STATUS_FAILED failed}. |
| * @param graph the graph with the execution metadata |
| * @param execution the execution node |
| * @return <code>true</code> if the status is faild. Otherwise <code>false</code>. |
| */ |
| public static boolean isExecutionFailed(TripleCollection graph, NonLiteral execution){ |
| return STATUS_FAILED.equals(getReference(graph,execution,STATUS)); |
| } |
| /** |
| * Tests if the {@link ExecutionMetadata#STATUS status} if an |
| * {@link ExecutionMetadata#EXECUTION execution} has already finished. This |
| * includes the states {@link ExecutionMetadata#STATUS_COMPLETED completed} |
| * and {@link ExecutionMetadata#STATUS_FAILED failed}. |
| * @param graph the graph with the execution metadata |
| * @param execution the execution node |
| * @return <code>true</code> if the execution has already finished |
| */ |
| public static boolean isExecutionFinished(TripleCollection graph, NonLiteral execution){ |
| UriRef status = getReference(graph,execution,STATUS); |
| return STATUS_FAILED.equals(status) || STATUS_COMPLETED.equals(status); |
| } |
| /** |
| * Getter for the started dateTime of an 'em:Execution' |
| * @param graph the graph |
| * @param execution the execution instance |
| * @return the time or <code>null</code> if not present |
| */ |
| public static Date getStarted(TripleCollection graph, NonLiteral execution){ |
| return get(graph, execution, ExecutionMetadata.STARTED, Date.class, lf); |
| } |
| /** |
| * Getter for the completed dateTime of an 'em:Execution' |
| * @param graph the graph |
| * @param execution the execution instance |
| * @return the time or <code>null</code> if not present |
| */ |
| public static Date getCompleted(TripleCollection graph, NonLiteral execution){ |
| return get(graph, execution, ExecutionMetadata.COMPLETED, Date.class, lf); |
| } |
| } |