use of ru.fix.completable.reactor.api.ReactorGraphModel in project completable-reactor by ru-fix.
the class EditorPanelFactory method create.
public static JFXPanel create(Project project, String graphModel) {
JFXPanel swingFxPanel = new JFXPanel();
GraphViewer graphViewer = new GraphViewer();
graphViewer.setShortcut(ShortcutType.GOTO_SERIALIZATION_POINT, new Shortcut(true, KeyCode.B));
graphViewer.registerListener(new GraphViewer.ActionListener() {
@Override
public void goToSource(@NotNull ReactorGraphModel.Source source) {
ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().runReadAction(() -> {
PsiFile foundFile = null;
if (source.fileName != null) {
foundFile = Arrays.stream(PsiShortNamesCache.getInstance(project).getFilesByName(source.fileName)).findAny().orElse(null);
} else if (source.className != null) {
ProjectAndLibrariesScope searchScope = new ProjectAndLibrariesScope(project);
PsiClass payloadPsiClass = JavaPsiFacade.getInstance(project).findClass(source.className, searchScope);
if (payloadPsiClass != null) {
foundFile = payloadPsiClass.getContainingFile();
}
}
if (foundFile == null) {
log.warn("Can not find file for source: " + source);
return;
}
OpenFileDescriptor descriptor = new OpenFileDescriptor(project, foundFile.getVirtualFile(), source.fileNameLine != null ? source.fileNameLine - 1 : 0, 0);
descriptor.navigate(true);
}));
}
@Override
public void goToSubgraph(String subgraphPayloadClass) {
ApplicationManager.getApplication().invokeLater(() -> ApplicationManager.getApplication().runReadAction(() -> {
PsiFile foundFile = null;
if (subgraphPayloadClass != null) {
foundFile = Arrays.stream(PsiShortNamesCache.getInstance(project).getFilesByName(subgraphPayloadClass + ".rg")).findAny().orElse(null);
}
if (foundFile == null) {
log.warn("Can not find file for subgraph: " + subgraphPayloadClass);
return;
}
OpenFileDescriptor descriptor = new OpenFileDescriptor(project, foundFile.getVirtualFile());
descriptor.navigate(true);
}));
}
@Override
public void coordinatesChanged(List<GraphViewer.CoordinateItem> coordinateItems) {
ReactorGraphModel graphModel = graphViewer.getGraphModel();
final ReactorGraphModel.Source codeBlockFrom = graphModel.coordinatesSource;
if (codeBlockFrom == null) {
log.warn("Coordinates source start location not specified in model.");
return;
}
ApplicationManager.getApplication().invokeLater(() -> {
ApplicationManager.getApplication().runReadAction(() -> {
PsiFile[] foundFiles = PsiShortNamesCache.getInstance(project).getFilesByName(codeBlockFrom.fileName);
if (foundFiles.length == 0) {
log.warn("No file with name " + codeBlockFrom.fileName + " found");
return;
}
if (foundFiles.length > 1) {
log.warn("Found more than one file with name " + codeBlockFrom.fileName);
}
PsiFile foundFile = foundFiles[0];
Document document = PsiDocumentManager.getInstance(project).getDocument(foundFile);
TextRange textRange = new TextRange(document.getLineStartOffset(codeBlockFrom.fileNameLine - 1), document.getLineEndOffset(document.getLineCount() - 1));
String codeBlock = document.getText(textRange);
String newCodeBlock = codeUpdater.updateCoordinates(codeBlock, coordinateItems);
WriteCommandAction.runWriteCommandAction(project, () -> document.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), newCodeBlock));
});
});
}
});
// Because of https://bugs.openjdk.java.net/browse/JDK-8090517, it is important to disable implicit exit.
Platform.setImplicitExit(false);
Platform.runLater(() -> {
try {
graphViewer.openGraph(graphModel);
swingFxPanel.setScene(graphViewer.getScene());
} catch (Exception exc) {
log.error("Failed to open graph.", exc);
}
});
return swingFxPanel;
}
use of ru.fix.completable.reactor.api.ReactorGraphModel in project completable-reactor by ru-fix.
the class ProcessorsHaveIncomingFlowsValidator method validateGraph.
@Override
public void validateGraph(ReactorGraphModel graph) throws ValidationException {
val processorsWithIncomingTransitions = graph.getMergePoints().stream().flatMap(mergePoint -> mergePoint.getTransitions().stream()).map(Transition::getHandleByProcessingItem).filter(Objects::nonNull).collect(Collectors.toSet());
processorsWithIncomingTransitions.addAll(graph.getStartPoint().getProcessingItems());
graph.getMergePoints().stream().flatMap(mergePoint -> mergePoint.getTransitions().stream()).map(Transition::getHandleByProcessingItem).filter(Objects::nonNull).forEach(processorsWithIncomingTransitions::add);
val processorWithoutIncomingTransitions = Stream.concat(graph.getProcessors().stream().map(Processor::getIdentity), graph.getSubgraphs().stream().map(Subgraph::getIdentity)).filter(processor -> !processorsWithIncomingTransitions.contains(processor)).findAny();
if (processorWithoutIncomingTransitions.isPresent()) {
throw new ValidationException(String.format("ProcessingItem %s does not have incoming transitions.", processorWithoutIncomingTransitions.get()));
}
}
use of ru.fix.completable.reactor.api.ReactorGraphModel in project completable-reactor by ru-fix.
the class GraphViewer method recursiveBuldTree.
/**
* рекурсивно строим дерево
*
* @param graph
* @param parentNode
* @param identity
*/
private void recursiveBuldTree(ReactorGraphModel graph, TreeNode parentNode, ReactorGraphModel.Identity identity) {
ReactorGraphModel.Processor processor = findProcessor(graph.processors, identity);
if (processor != null) {
val node = parentNode.addChild(processor);
ReactorGraphModel.MergePoint mergePoint = findChildMergePoints(graph, processor.getIdentity());
if (mergePoint != null) {
val mergeNode = node.addChild(mergePoint);
for (val proc : findChildProcessorByMergePoint(graph, mergePoint)) {
recursiveBuldTree(graph, mergeNode, proc.getIdentity());
}
}
}
}
use of ru.fix.completable.reactor.api.ReactorGraphModel in project completable-reactor by ru-fix.
the class CRReactorGraph method serialize.
@Override
public ReactorGraphModel serialize() {
ReactorGraphModel model = new ReactorGraphModel();
model.payload = serializePayload();
model.coordinatesSource = this.coordinatesSource;
model.buildGraphSource = this.buildGraphSource;
processingItems.entrySet().stream().sorted(Comparator.comparing(entry -> serialize(entry.getKey()))).forEach(entry -> {
switch(entry.getValue().getProcessingItemType()) {
case PROCESSOR:
val processor = entry.getValue().serializeProcessor();
processor.setIdentity(entry.getKey().getIdentity());
model.processors.add(processor);
break;
case SUBGRAPH:
val subgraph = entry.getValue().serializeSubgraph();
subgraph.setIdentity(entry.getKey().getIdentity());
model.subgraphs.add(subgraph);
break;
case MERGE_POINT:
break;
default:
throw new IllegalStateException("Invalid type: " + entry.getValue().getProcessingItemType());
}
});
model.startPoint = startPoint.serialize();
this.mergePoints.stream().map(MergePoint::serialize).forEach(model.mergePoints::add);
return model;
}
Aggregations