Skip to content

Commit

Permalink
2 files diff editor, working with deltas + ui
Browse files Browse the repository at this point in the history
  • Loading branch information
1azyman committed Apr 19, 2024
1 parent 45656a0 commit 0ce9da4
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ public void actionPerformed(@NotNull AnActionEvent evt) {
// ex.printStackTrace();
// }

DiffSource left = new DiffSource("Current object", currentObjectFile, DiffSourceType.LOCAL);
DiffSource right = new DiffSource("Previous object", previousInitialFile, DiffSourceType.LOCAL);
DiffSource left = new DiffSource("System configuration", currentObjectFile, DiffSourceType.LOCAL);
DiffSource right = new DiffSource("System configuration", previousInitialFile, DiffSourceType.REMOTE);

DiffProcessor processor = new DiffProcessor(project, left, right);
processor.initialize();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

import com.evolveum.midpoint.prism.ModificationType;
import com.evolveum.midpoint.prism.PrismValue;
import com.evolveum.midpoint.prism.delta.ItemDelta;

public record DeltaItem(ModificationType modificationType, PrismValue value) {
public record DeltaItem(ItemDelta<?, ?> parent, ModificationType modificationType, PrismValue value) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
import com.intellij.openapi.project.Project;
import com.intellij.ui.JBSplitter;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBPanel;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NotNull;

Expand Down Expand Up @@ -44,18 +46,28 @@ private void initLayout() {

JBSplitter splitter = new JBSplitter(true, 0.5f);

deltaTree = createDeltaTable();
splitter.setFirstComponent(ScrollPaneFactory.createScrollPane(deltaTree));
JBPanel deltaPanel = createDeltaTablePanel();
splitter.setFirstComponent(deltaPanel);

JComponent diffEditor = createTextDiff();
splitter.setSecondComponent(diffEditor);
add(splitter, BorderLayout.CENTER);
}

private ObjectDeltaTree createDeltaTable() {
ObjectDeltaTree tree = new ObjectDeltaTree(new ObjectDeltaTreeModel(delta));
private JBPanel createDeltaTablePanel() {
deltaTree = new ObjectDeltaTree(new ObjectDeltaTreeModel(delta));
deltaTree.addTreeSelectionListener(e -> onTreeSelectionChanged(getSelectedNodes()));

return tree;
JBPanel treePanel = new JBPanel(new BorderLayout());
treePanel.setBorder(JBUI.Borders.customLineBottom(JBUI.CurrentTheme.Editor.BORDER_COLOR));

JBLabel label = new JBLabel("Review changes loaded from remote object:");
label.setBorder(JBUI.Borders.emptyLeft(12));
treePanel.add(label, BorderLayout.NORTH); // todo fix

treePanel.add(ScrollPaneFactory.createScrollPane(this.deltaTree), BorderLayout.CENTER);

return treePanel;
}

protected abstract JComponent createTextDiff();
Expand All @@ -75,6 +87,10 @@ private JComponent initMainToolbar(JComponent parent) {
return toolbar.getComponent();
}

protected void onTreeSelectionChanged(@NotNull List<DefaultMutableTreeNode> selected) {
// intentionally left empty
}

protected @NotNull List<AnAction> createToolbarActions() {
return List.of();
}
Expand All @@ -90,7 +106,7 @@ private void collapseAllPerformed() {
if (deltaTree == null) {
return;
}
TreeUtil.collapseAll(deltaTree, 1);
TreeUtil.collapseAll(deltaTree, 2);
}

public @NotNull List<DefaultMutableTreeNode> getSelectedNodes() {
Expand All @@ -107,8 +123,6 @@ public void removeNodes(@NotNull List<DefaultMutableTreeNode> nodes) {
return;
}

// todo remove also nodes that don't have children

ObjectDeltaTreeModel<O> model = (ObjectDeltaTreeModel<O>) deltaTree.getModel();
nodes.forEach(n -> model.removeNodeFromParent(n));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ public class DiffProcessor<O extends ObjectType> {

private ObjectDelta<O> delta;

private DiffPanel panel;
private PrismObject<O> leftObjectPreview;
private LightVirtualFile leftPreviewFile;
private CacheDiffRequestChainProcessor diffProcessor;

private DiffPanel<O> panel;

private ParameterizedEquivalenceStrategy equivalenceStrategy = EquivalenceStrategy.REAL_VALUE_CONSIDER_DIFFERENT_IDS_NATURAL_KEYS;

Expand All @@ -63,20 +67,22 @@ public DiffProcessor(
public void initialize() {
try {
leftObject = parseObject(leftSource);
leftObjectPreview = leftObject.clone();

rightObject = parseObject(rightSource);

delta = leftObject.diff(rightObject, equivalenceStrategy);

String leftTextContent = ClientUtils.serialize(MidPointUtils.DEFAULT_PRISM_CONTEXT, leftObject);
String leftTextContent = ClientUtils.serialize(MidPointUtils.DEFAULT_PRISM_CONTEXT, leftObjectPreview);
String rightTextContent = ClientUtils.serialize(MidPointUtils.DEFAULT_PRISM_CONTEXT, rightObject);
LightVirtualFile left = new LightVirtualFile(buildTextDiffFileName(leftSource, true), leftTextContent);
leftPreviewFile = new LightVirtualFile(buildTextDiffFileName(leftSource, true), leftTextContent);
LightVirtualFile right = new LightVirtualFile(buildTextDiffFileName(rightSource, false), rightTextContent);

DiffRequest request = DiffRequestFactory.getInstance().createFromFiles(project, left, right);
DiffRequest request = DiffRequestFactory.getInstance().createFromFiles(project, leftPreviewFile, right);

DiffRequestChain chain = new SimpleDiffRequestChain(request);

CacheDiffRequestChainProcessor processor = new CacheDiffRequestChainProcessor(project, chain) {
diffProcessor = new CacheDiffRequestChainProcessor(project, chain) {

@Override
protected @org.jetbrains.annotations.NotNull List<AnAction> getNavigationActions() {
Expand All @@ -89,25 +95,51 @@ public void initialize() {
return list;
}
};
processor.updateRequest();
diffProcessor.updateRequest();

panel = new DiffPanel(project, delta) {
panel = new DiffPanel<>(project, delta) {

@Override
protected JComponent createTextDiff() {
return processor.getComponent();
return diffProcessor.getComponent();
}

@Override
protected @NotNull List<AnAction> createToolbarActions() {
return DiffProcessor.this.createToolbarActions();
}

@Override
protected void onTreeSelectionChanged(@NotNull List<DefaultMutableTreeNode> selected) {
DiffProcessor.this.onTreeSelectionChanged(selected);
}
};
} catch (Exception ex) {
throw new RuntimeException("Couldn't parse object", ex);
}
}

private void onTreeSelectionChanged(List<DefaultMutableTreeNode> selected) {
leftObjectPreview = leftObject.clone();

try {
applyDeltaNodesToObject(leftObjectPreview, selected);

updateLeftPreviewFile();
} catch (Exception ex) {
ex.printStackTrace(); // todo fix
}

// todo implement
}

private void updateLeftPreviewFile() throws IOException, SchemaException {
String leftTextContent = ClientUtils.serialize(MidPointUtils.DEFAULT_PRISM_CONTEXT, leftObjectPreview);
leftPreviewFile.setBinaryContent(leftTextContent.getBytes());

diffProcessor.updateRequest(true);
}

private List<AnAction> createToolbarActions() {
List<AnAction> actions = new ArrayList<>();

Expand Down Expand Up @@ -209,28 +241,38 @@ private void acceptPerformed() {
List<DefaultMutableTreeNode> selected = panel.getSelectedNodes();

// todo implement - apply partial delta
applyDeltaNodesToObject(leftObject, selected);

for (DefaultMutableTreeNode node : selected) {
Object userObject = node.getUserObject();
if (userObject instanceof ObjectDelta<?> od) {

} else if (userObject instanceof ItemDelta<?, ?> id) {
ObjectDelta<O> delta = leftObject.createModifyDelta();
delta.addModification(id.clone());

delta.applyTo(leftObject);
} else if (userObject instanceof DeltaItem) {
panel.removeNodes(selected);

}
}

panel.removeNodes(selected);
} catch (Exception ex) {
// todo fix
ex.printStackTrace();
}
}

private void applyDeltaNodesToObject(PrismObject<O> object, List<DefaultMutableTreeNode> nodes)
throws SchemaException {

// todo implement
for (DefaultMutableTreeNode node : nodes) {
Object userObject = node.getUserObject();
if (userObject instanceof ObjectDelta<?> od) {
delta.applyTo(object);
} else if (userObject instanceof ItemDelta<?, ?> id) {
ObjectDelta<O> delta = leftObjectPreview.createModifyDelta();
delta.addModification(id.clone());

delta.applyTo(object);
} else if (userObject instanceof DeltaItem di) {
//
// ObjectDelta<O> delta = leftObject.createModifyDelta();
// delta.createm
}
}
}

private void ignorePerformed() {
panel.removeNodes(panel.getSelectedNodes());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,14 @@ public class ObjectDeltaTree<O extends ObjectType> extends Tree {
private static final ColorKey MODIFIED = ColorKey.createColorKey("FILESTATUS_MODIFIED");

public ObjectDeltaTree(@NotNull ObjectDeltaTreeModel<O> model) {
super(model); // todo implement
super(model);

setup();
}

private void setup() {
setRootVisible(false);

setCellRenderer(new LabelBasedRenderer.Tree() {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

public class ObjectDeltaTreeModel<O extends ObjectType> extends AbstractTreeModel {

public static final Object ROOT_ALL = "All";
private static final Object NODE_ROOT = "";

private ObjectDelta<O> delta;

Expand Down Expand Up @@ -50,29 +50,33 @@ public int getIndexOfChild(Object parent, Object child) {
}

public void setDelta(@NotNull ObjectDelta<O> delta) {
DefaultMutableTreeNode root = new DefaultMutableTreeNode(delta);
DefaultMutableTreeNode root = new DefaultMutableTreeNode(NODE_ROOT);

DefaultMutableTreeNode all = new DefaultMutableTreeNode(delta);
root.add(all);

Collection<? extends ItemDelta<?, ?>> modifications = delta.getModifications();
for (ItemDelta<?, ?> modification : modifications) {
DefaultMutableTreeNode itemDeltaNode = new DefaultMutableTreeNode(modification);
root.add(itemDeltaNode);
all.add(itemDeltaNode);

addValues(itemDeltaNode, ModificationType.ADD, modification.getValuesToAdd());
addValues(itemDeltaNode, ModificationType.DELETE, modification.getValuesToDelete());
addValues(itemDeltaNode, ModificationType.REPLACE, modification.getValuesToReplace());
addValues(itemDeltaNode, modification, ModificationType.ADD, modification.getValuesToAdd());
addValues(itemDeltaNode, modification, ModificationType.DELETE, modification.getValuesToDelete());
addValues(itemDeltaNode, modification, ModificationType.REPLACE, modification.getValuesToReplace());
}

this.root = root;
}

private void addValues(
DefaultMutableTreeNode parent, ModificationType modificationType,
DefaultMutableTreeNode parent, ItemDelta<?, ?> itemDelta, ModificationType modificationType,
Collection<? extends PrismValue> values) {

if (values == null) {
return;
}

values.forEach(v -> parent.add(new DefaultMutableTreeNode(new DeltaItem(modificationType, v))));
values.forEach(v -> parent.add(new DefaultMutableTreeNode(new DeltaItem(itemDelta, modificationType, v))));
}


Expand All @@ -89,5 +93,9 @@ public void removeNodeFromParent(DefaultMutableTreeNode node) {
parent.remove(node);

treeNodesRemoved(path, indices, children);

if (parent.isLeaf()) {
removeNodeFromParent(parent);
}
}
}

0 comments on commit 0ce9da4

Please sign in to comment.