use of au.gov.asd.tac.constellation.plugins.PluginInteraction in project constellation by constellation-app.
the class ExtractWordsFromTextPlugin method edit.
@Override
public void edit(final GraphWriteMethods wg, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException, PluginException {
interaction.setProgress(0, 0, "Extracting...", true);
/*
Retrieving attributes
*/
final Map<String, PluginParameter<?>> extractEntityParameters = parameters.getParameters();
final String contentAttribute = extractEntityParameters.get(ATTRIBUTE_PARAMETER_ID).getStringValue();
final String words = extractEntityParameters.get(WORDS_PARAMETER_ID).getStringValue() == null ? null : extractEntityParameters.get(WORDS_PARAMETER_ID).getStringValue().trim();
final boolean useRegex = extractEntityParameters.get(USE_REGEX_PARAMETER_ID).getBooleanValue();
final boolean wholeWordOnly = extractEntityParameters.get(WHOLE_WORDS_ONLY_PARAMETER_ID).getBooleanValue();
final int wordLength = parameters.getParameters().get(MIN_WORD_LENGTH_PARAMETER_ID).getIntegerValue();
final boolean removeSpecialChars = extractEntityParameters.get(REMOVE_SPECIAL_CHARS_PARAMETER_ID).getBooleanValue();
final boolean toLowerCase = extractEntityParameters.get(LOWER_CASE_PARAMETER_ID).getBooleanValue();
final boolean types = extractEntityParameters.get(SCHEMA_TYPES_PARAMETER_ID).getBooleanValue();
final String inOrOut = extractEntityParameters.get(IN_OR_OUT_PARAMETER_ID).getStringValue();
final boolean selectedOnly = extractEntityParameters.get(SELECTED_ONLY_PARAMETER_ID).getBooleanValue();
final boolean regexOnly = extractEntityParameters.get(REGEX_ONLY_PARAMETER_ID).getBooleanValue();
if (!OUTGOING.equals(inOrOut) && !INCOMING.equals(inOrOut)) {
var msg = String.format("Parameter %s must be '%s' or '%s'", REGEX_ONLY_PARAMETER_ID, OUTGOING, INCOMING);
throw new PluginException(PluginNotificationLevel.ERROR, msg);
}
final boolean outgoing = OUTGOING.equals(inOrOut);
/*
Retrieving attribute IDs
*/
final int vertexIdentifierAttributeId = VisualConcept.VertexAttribute.IDENTIFIER.ensure(wg);
final int vertexTypeAttributeId = AnalyticConcept.VertexAttribute.TYPE.ensure(wg);
final int transactionTypeAttributeId = AnalyticConcept.TransactionAttribute.TYPE.ensure(wg);
final int transactionDatetimeAttributeId = TemporalConcept.TransactionAttribute.DATETIME.ensure(wg);
final int transactionContentAttributeId = wg.getAttribute(GraphElementType.TRANSACTION, contentAttribute);
final int transactionSelectedAttributeId = VisualConcept.TransactionAttribute.SELECTED.ensure(wg);
//
if (transactionContentAttributeId == Graph.NOT_FOUND) {
final NotifyDescriptor nd = new NotifyDescriptor.Message(String.format("The specified attribute %s does not exist.", contentAttribute), NotifyDescriptor.WARNING_MESSAGE);
DialogDisplayer.getDefault().notify(nd);
return;
}
final int transactionCount = wg.getTransactionCount();
if (regexOnly) {
// This choice ignores several other parameters, so is a bit simpler
// even if there code commonalities, but combining the if/else
// code would make things even more complex.
//
// The input words are treated as trusted regular expressions,
// so the caller has to know what they're doing.
// This is power-use mode.
//
// Each line of the input words is a regex.
// Use them as-is for the power users.
//
final List<Pattern> patterns = new ArrayList<>();
if (StringUtils.isNotBlank(words)) {
for (String word : words.split(SeparatorConstants.NEWLINE)) {
word = word.strip();
if (!word.isEmpty()) {
final Pattern pattern = Pattern.compile(word);
patterns.add(pattern);
}
}
}
if (!patterns.isEmpty()) {
// Use a set to hold the words.
// If a word is found multiple times, there's no point adding multiple nodes.
//
final Set<String> matched = new HashSet<>();
//
for (int transactionPosition = 0; transactionPosition < transactionCount; transactionPosition++) {
final int transactionId = wg.getTransaction(transactionPosition);
final boolean selectedTx = wg.getBooleanValue(transactionSelectedAttributeId, transactionId);
if (selectedOnly && !selectedTx) {
continue;
}
final String content = wg.getStringValue(transactionContentAttributeId, transactionId);
/*
Does the transaction have content?
*/
if (StringUtils.isBlank(content)) {
continue;
}
/*
Ignore other "referenced" transactions because that's not useful
*/
if (wg.getObjectValue(transactionTypeAttributeId, transactionId) != null && wg.getObjectValue(transactionTypeAttributeId, transactionId).equals(AnalyticConcept.TransactionType.REFERENCED)) {
continue;
}
patterns.stream().map(pattern -> pattern.matcher(content)).forEach(matcher -> {
while (matcher.find()) {
if (matcher.groupCount() == 0) {
// The regex doesn't have an explicit capture group, so capture the lot.
//
final String g = matcher.group();
matched.add(toLowerCase ? g.toLowerCase() : g);
} else {
//
for (int i = 1; i <= matcher.groupCount(); i++) {
final String g = matcher.group(i);
matched.add(toLowerCase ? g.toLowerCase() : g);
}
}
}
});
//
if (!matched.isEmpty()) {
/*
Retrieving information needed to create new transactions
*/
final int sourceVertexId = wg.getTransactionSourceVertex(transactionId);
final int destinationVertexId = wg.getTransactionDestinationVertex(transactionId);
final ZonedDateTime datetime = wg.getObjectValue(transactionDatetimeAttributeId, transactionId);
matched.forEach(word -> {
final int newVertexId = wg.addVertex();
wg.setStringValue(vertexIdentifierAttributeId, newVertexId, word);
wg.setObjectValue(vertexTypeAttributeId, newVertexId, AnalyticConcept.VertexType.WORD);
final int newTransactionId = outgoing ? wg.addTransaction(sourceVertexId, newVertexId, true) : wg.addTransaction(newVertexId, destinationVertexId, true);
wg.setObjectValue(transactionDatetimeAttributeId, newTransactionId, datetime);
wg.setObjectValue(transactionTypeAttributeId, newTransactionId, AnalyticConcept.TransactionType.REFERENCED);
wg.setStringValue(transactionContentAttributeId, newTransactionId, content);
});
}
}
}
// End of regexOnly.
} else {
// The original logic.
final List<Pattern> patterns = patternsFromWords(words, useRegex, wholeWordOnly);
/*
Iterating over all the transactions in the graph
*/
final List<String> foundWords = new ArrayList<>();
for (int transactionPosition = 0; transactionPosition < transactionCount; transactionPosition++) {
foundWords.clear();
final int transactionId = wg.getTransaction(transactionPosition);
final boolean selectedTx = wg.getBooleanValue(transactionSelectedAttributeId, transactionId);
if (selectedOnly && !selectedTx) {
continue;
}
String content = wg.getStringValue(transactionContentAttributeId, transactionId);
/*
Does the transaction have content?
*/
if (StringUtils.isBlank(content)) {
continue;
}
/*
Ignore other "referenced" transactions because that's not useful
*/
if (wg.getObjectValue(transactionTypeAttributeId, transactionId) != null && wg.getObjectValue(transactionTypeAttributeId, transactionId).equals(AnalyticConcept.TransactionType.REFERENCED)) {
continue;
}
/*
Retrieving information needed to create new transactions
*/
final int sourceVertexId = wg.getTransactionSourceVertex(transactionId);
final int destinationVertexId = wg.getTransactionDestinationVertex(transactionId);
final ZonedDateTime datetime = wg.getObjectValue(transactionDatetimeAttributeId, transactionId);
final HashSet<String> typesExtracted = new HashSet<>();
/*
Extracting Schema Types
*/
if (types) {
final List<ExtractedVertexType> extractedTypes = SchemaVertexTypeUtilities.extractVertexTypes(content);
final Map<String, SchemaVertexType> identifiers = new HashMap<>();
extractedTypes.forEach(extractedType -> identifiers.put(extractedType.getIdentifier(), extractedType.getType()));
for (String identifier : identifiers.keySet()) {
final int newVertexId = wg.addVertex();
wg.setStringValue(vertexIdentifierAttributeId, newVertexId, identifier);
wg.setObjectValue(vertexTypeAttributeId, newVertexId, identifiers.get(identifier));
final int newTransactionId = outgoing ? wg.addTransaction(sourceVertexId, newVertexId, true) : wg.addTransaction(newVertexId, destinationVertexId, true);
wg.setObjectValue(transactionDatetimeAttributeId, newTransactionId, datetime);
wg.setObjectValue(transactionTypeAttributeId, newTransactionId, AnalyticConcept.TransactionType.REFERENCED);
wg.setStringValue(transactionContentAttributeId, newTransactionId, content);
typesExtracted.add(identifier.toLowerCase());
}
}
if (StringUtils.isBlank(words)) {
/*
Extracting all words of the specified length if no word list has been provided
*/
for (String word : content.split(" ")) {
if (toLowerCase) {
word = word.toLowerCase();
}
if (removeSpecialChars) {
word = word.replaceAll("\\W", "");
}
if (word.length() < wordLength) {
continue;
}
foundWords.add(word);
}
} else {
patterns.stream().map(pattern -> pattern.matcher(content)).forEach(matcher -> {
while (matcher.find()) {
final String g = matcher.group();
foundWords.add(toLowerCase ? g.toLowerCase() : g);
}
});
}
/*
Add words to graph
*/
for (String word : foundWords) {
if (types && typesExtracted.contains(word.toLowerCase())) {
continue;
}
final int newVertexId = wg.addVertex();
wg.setStringValue(vertexIdentifierAttributeId, newVertexId, word);
wg.setObjectValue(vertexTypeAttributeId, newVertexId, AnalyticConcept.VertexType.WORD);
final int newTransactionId = outgoing ? wg.addTransaction(sourceVertexId, newVertexId, true) : wg.addTransaction(newVertexId, destinationVertexId, true);
wg.setObjectValue(transactionDatetimeAttributeId, newTransactionId, datetime);
wg.setObjectValue(transactionTypeAttributeId, newTransactionId, AnalyticConcept.TransactionType.REFERENCED);
wg.setStringValue(transactionContentAttributeId, newTransactionId, content);
}
}
}
PluginExecutor.startWith(VisualSchemaPluginRegistry.COMPLETE_SCHEMA).followedBy(InteractiveGraphPluginRegistry.RESET_VIEW).executeNow(wg);
interaction.setProgress(1, 0, "Completed successfully", true);
}
use of au.gov.asd.tac.constellation.plugins.PluginInteraction in project constellation by constellation-app.
the class SplitNodesPlugin method edit.
@Override
public void edit(final GraphWriteMethods graph, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException, PluginException {
final Map<String, PluginParameter<?>> splitParameters = parameters.getParameters();
final String character = splitParameters.get(SPLIT_PARAMETER_ID) != null && splitParameters.get(SPLIT_PARAMETER_ID).getStringValue() != null ? splitParameters.get(SPLIT_PARAMETER_ID).getStringValue() : "";
final ParameterValue transactionTypeChoice = splitParameters.get(TRANSACTION_TYPE_PARAMETER_ID).getSingleChoice();
final String linkType = transactionTypeChoice != null ? transactionTypeChoice.toString() : AnalyticConcept.TransactionType.CORRELATION.getName();
final boolean allOccurrences = splitParameters.get(ALL_OCCURRENCES_PARAMETER_ID).getBooleanValue();
final boolean splitIntoSameLevel = splitParameters.get(DUPLICATE_TRANSACTIONS_PARAMETER_ID).getBooleanValue();
final int vertexSelectedAttributeId = VisualConcept.VertexAttribute.SELECTED.ensure(graph);
final int vertexIdentifierAttributeId = VisualConcept.VertexAttribute.IDENTIFIER.ensure(graph);
final List<Integer> newVertices = new ArrayList<>();
final int graphVertexCount = graph.getVertexCount();
for (int position = 0; position < graphVertexCount; position++) {
final int currentVertexId = graph.getVertex(position);
if (graph.getBooleanValue(vertexSelectedAttributeId, currentVertexId)) {
final String identifier = graph.getStringValue(vertexIdentifierAttributeId, currentVertexId);
if (identifier != null && identifier.contains(character) && identifier.indexOf(character) < identifier.length() - character.length()) {
String leftNodeIdentifier = "";
if (allOccurrences) {
final String[] substrings = Arrays.stream(identifier.split(character)).filter(value -> value != null && value.length() > 0).toArray(size -> new String[size]);
if (substrings.length <= 0) {
continue;
}
leftNodeIdentifier = substrings[0];
for (int i = 1; i < substrings.length; i++) {
newVertices.add(createNewNode(graph, position, substrings[i], linkType, splitIntoSameLevel));
}
} else {
final int i = identifier.indexOf(character);
leftNodeIdentifier = identifier.substring(0, i);
if (StringUtils.isNotBlank(leftNodeIdentifier)) {
newVertices.add(createNewNode(graph, position, identifier.substring(i + 1), linkType, splitIntoSameLevel));
} else {
leftNodeIdentifier = identifier.substring(i + 1);
}
}
// Rename the selected node
if (StringUtils.isNotBlank(leftNodeIdentifier)) {
graph.setStringValue(vertexIdentifierAttributeId, currentVertexId, leftNodeIdentifier);
newVertices.add(currentVertexId);
}
}
}
}
if (!newVertices.isEmpty()) {
// Reset the view
graph.validateKey(GraphElementType.VERTEX, true);
graph.validateKey(GraphElementType.TRANSACTION, true);
final PluginExecutor arrangement = completionArrangement();
if (arrangement != null) {
// run the arrangement
final VertexListInclusionGraph vlGraph = new VertexListInclusionGraph(graph, AbstractInclusionGraph.Connections.NONE, newVertices);
arrangement.executeNow(vlGraph.getInclusionGraph());
vlGraph.retrieveCoords();
}
if (splitParameters.get(COMPLETE_WITH_SCHEMA_OPTION_ID).getBooleanValue()) {
PluginExecution.withPlugin(VisualSchemaPluginRegistry.COMPLETE_SCHEMA).executeNow(graph);
}
PluginExecutor.startWith(InteractiveGraphPluginRegistry.RESET_VIEW).executeNow(graph);
}
}
use of au.gov.asd.tac.constellation.plugins.PluginInteraction in project constellation by constellation-app.
the class WorkflowQueryPlugin method execute.
@Override
protected void execute(final PluginGraphs pluginGraphs, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException, PluginException {
final Graph graph = pluginGraphs.getGraph();
final ReadableGraph readableGraph = graph.getReadableGraph();
// buildId batches
try {
queryBatches = GraphRecordStoreUtilities.getSelectedVerticesBatches(readableGraph, parameters.getIntegerValue(BATCH_SIZE_PARAMETER_ID));
} finally {
readableGraph.release();
}
pluginGraphs.waitAtGate(1);
// create a service for executing jobs, limiting concurrent executions to the max concurrent plugins parameter.
final int maxConcurrentPlugins = parameters.getIntegerValue(MAX_CONCURRENT_PLUGINS_PARAMETER_ID);
final ExecutorService workflowExecutor = Executors.newFixedThreadPool(maxConcurrentPlugins);
// schedule a job for each batch, where the job is to execute the defined workflow
final List<Future<?>> workerPlugins = new ArrayList<>();
final List<PluginException> exceptions = new ArrayList<>();
if (queryBatches.isEmpty()) {
queryBatches.add(new GraphRecordStore());
}
// run plugin once for every batch record store
queryBatches.forEach(batch -> {
final StoreGraph batchGraph = new StoreGraph(graph.getSchema() != null ? graph.getSchema().getFactory().createSchema() : null);
batchGraph.getSchema().newGraph(batchGraph);
CopyGraphUtilities.copyGraphTypeElements(readableGraph, batchGraph);
GraphRecordStoreUtilities.addRecordStoreToGraph(batchGraph, batch, true, true, null);
final WorkerQueryPlugin worker = new WorkerQueryPlugin(getWorkflow(), batchGraph, exceptions, getErrorHandlingPlugin(), addPartialResults());
workerPlugins.add(workflowExecutor.submit(() -> {
Thread.currentThread().setName(THREAD_POOL_NAME);
try {
PluginExecution.withPlugin(worker).withParameters(parameters).executeNow(graph);
} catch (InterruptedException | PluginException ex) {
throw new RuntimeException(ex);
}
}));
});
final int[] workerFailCount = { 0 };
for (Future<?> worker : workerPlugins) {
try {
worker.get();
} catch (InterruptedException ex) {
workerPlugins.forEach(workerToInterrupt -> workerToInterrupt.cancel(true));
throw ex;
} catch (ExecutionException ex) {
workerFailCount[0]++;
}
}
workflowExecutor.shutdown();
// if there were any errors, collect them and display them to the user
if (!exceptions.isEmpty()) {
final StringBuilder entireException = new StringBuilder();
entireException.append(workerFailCount[0]).append(" workers failed.").append(SeparatorConstants.NEWLINE);
exceptions.forEach(ex -> entireException.append(ex.getMessage()).append(SeparatorConstants.NEWLINE));
throw new PluginException(PluginNotificationLevel.ERROR, entireException.toString());
}
}
use of au.gov.asd.tac.constellation.plugins.PluginInteraction in project constellation by constellation-app.
the class SelectTopNPlugin method edit.
@Override
protected void edit(final GraphWriteMethods graph, final PluginInteraction interaction, final PluginParameters parameters) throws InterruptedException, PluginException {
final String mode = parameters.getParameters().get(MODE_PARAMETER_ID).getStringValue();
final String typeCategory = parameters.getParameters().get(TYPE_CATEGORY_PARAMETER_ID).getStringValue();
final List<String> subTypes = parameters.getParameters().get(TYPE_PARAMETER_ID).getMultiChoiceValue().getChoices();
final int limit = parameters.getParameters().get(LIMIT_PARAMETER_ID).getIntegerValue();
if (mode == null || (!mode.equals(NODE) && !mode.equals(TRANSACTION))) {
throw new PluginException(PluginNotificationLevel.ERROR, "Invalid mode value provided");
}
if (typeCategory == null) {
throw new PluginException(PluginNotificationLevel.ERROR, "Select a type category");
}
if (subTypes.isEmpty()) {
throw new PluginException(PluginNotificationLevel.ERROR, "Select some types to perform the calculation");
}
final int vertexLabelAttribute = VisualConcept.VertexAttribute.LABEL.get(graph);
if (vertexLabelAttribute == Graph.NOT_FOUND) {
throw new PluginException(PluginNotificationLevel.ERROR, String.format(MISSING_PROPERTY_FORMAT, VisualConcept.VertexAttribute.LABEL.getName()));
}
final int vertexSelectedAttribute = VisualConcept.VertexAttribute.SELECTED.get(graph);
if (vertexSelectedAttribute == Graph.NOT_FOUND) {
throw new PluginException(PluginNotificationLevel.ERROR, String.format(MISSING_PROPERTY_FORMAT, VisualConcept.VertexAttribute.SELECTED.getName()));
}
final int vertexTypeAttribute = AnalyticConcept.VertexAttribute.TYPE.get(graph);
if (vertexTypeAttribute == Graph.NOT_FOUND) {
throw new PluginException(PluginNotificationLevel.ERROR, String.format(MISSING_PROPERTY_FORMAT, AnalyticConcept.VertexAttribute.TYPE.getName()));
}
final int transactionTypeAttribute = AnalyticConcept.TransactionAttribute.TYPE.get(graph);
if (transactionTypeAttribute == Graph.NOT_FOUND) {
throw new PluginException(PluginNotificationLevel.ERROR, String.format(MISSING_PROPERTY_FORMAT, AnalyticConcept.TransactionAttribute.TYPE.getName()));
}
// make a set of the highlighted nodes
final Set<Integer> selectedNodes = new HashSet<>();
final int vertexCount = graph.getVertexCount();
for (int position = 0; position < vertexCount; position++) {
final int vxId = graph.getVertex(position);
if (graph.getBooleanValue(vertexSelectedAttribute, vxId)) {
selectedNodes.add(vxId);
}
}
if (selectedNodes.isEmpty()) {
throw new PluginException(PluginNotificationLevel.ERROR, "Select at least 1 node");
}
// calculate the occurrences of destination vertices
int txId;
int sourceVxId;
int destinationVxId;
int targetVxId;
int step = 0;
SchemaVertexType destinationVertexType;
SchemaTransactionType transactionType;
final Map<Integer, Integer> occurrences = new HashMap<>();
for (final Integer vxId : selectedNodes) {
final String label = graph.getStringValue(vertexLabelAttribute, vxId);
interaction.setProgress(++step, selectedNodes.size(), String.format("Calculating top %s for %s", limit, label), true);
final int transactionCount = graph.getVertexTransactionCount(vxId);
for (int position = 0; position < transactionCount; position++) {
txId = graph.getVertexTransaction(vxId, position);
sourceVxId = graph.getTransactionSourceVertex(txId);
destinationVxId = graph.getTransactionDestinationVertex(txId);
targetVxId = vxId == sourceVxId ? destinationVxId : sourceVxId;
switch(mode) {
case NODE:
destinationVertexType = graph.getObjectValue(vertexTypeAttribute, targetVxId);
if (destinationVertexType != null && subTypes.contains(destinationVertexType.getName())) {
if (!occurrences.containsKey(targetVxId)) {
occurrences.put(targetVxId, 0);
}
occurrences.put(targetVxId, occurrences.get(targetVxId) + 1);
}
break;
case TRANSACTION:
transactionType = graph.getObjectValue(transactionTypeAttribute, txId);
if (transactionType != null && subTypes.contains(transactionType.getName())) {
if (!occurrences.containsKey(targetVxId)) {
occurrences.put(targetVxId, 0);
}
occurrences.put(targetVxId, occurrences.get(targetVxId) + 1);
}
break;
default:
break;
}
}
// make a map sorted by the count in descending order
final LinkedHashMap<Integer, Integer> sortedMap = occurrences.entrySet().stream().sorted(Map.Entry.comparingByValue(Collections.reverseOrder())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
sortedMap.keySet().stream().limit(limit).forEach(id -> graph.setBooleanValue(vertexSelectedAttribute, id, true));
interaction.setProgress(1, 0, "Selected " + sortedMap.size() + " nodes.", true);
}
interaction.setProgress(1, 0, "Completed successfully", true);
}
use of au.gov.asd.tac.constellation.plugins.PluginInteraction in project constellation by constellation-app.
the class ExtractTypesFromTextPluginNGTest method testQuery.
/**
* Test of query method, of class ExtractTypesFromTextPlugin.
*
* @throws java.lang.Exception
*/
@Test
public void testQuery() throws Exception {
RecordStore query = new GraphRecordStore();
ExtractTypesFromTextPlugin instance = new ExtractTypesFromTextPlugin();
PluginInteraction interaction = new TextPluginInteraction();
PluginParameters parameters = instance.createParameters();
parameters.getParameters().get(ExtractTypesFromTextPlugin.TEXT_PARAMETER_ID).setStringValue("Email Person Communication");
RecordStore expResult = new GraphRecordStore();
RecordStore result = instance.query(query, interaction, parameters);
assertEquals(result, expResult);
}
Aggregations