package org.eclipse.iee.editor.text.edit; import org.eclipse.iee.core.document.text.Document; import org.eclipse.iee.core.document.text.ICompositeNode; import org.eclipse.iee.core.document.text.INode; import org.eclipse.iee.core.document.text.INodeVisitor; import org.eclipse.iee.core.document.text.ITextLocation; import org.eclipse.iee.core.document.text.OffsetTextLocation; import org.eclipse.iee.core.document.text.Span; import org.eclipse.iee.core.document.text.Text; public class ReplaceVisitor implements INodeVisitor<ReplaceCtx, CompositeCommand>{ private final class RemoveCommand implements IEditCommand { private final INode fNode; private final ITextLocation fMoveTo; private RemoveCommand(INode node, ITextLocation moveTo) { fNode = node; fMoveTo = moveTo; } @Override public void perform() { final ICompositeNode<INode> parent = (ICompositeNode<INode>) fNode.getParent(); parent.removeChild(fNode); } @Override public ITextLocation adjust(ITextLocation location) { if (location.getModel().hasParent(fNode)) { return fMoveTo; } return location; } } @Override public CompositeCommand visitText(Text text, ReplaceCtx ctx) { int from = ctx.getFrom().getOffset(); int to = ctx.getTo().getOffset(); if (ctx.isFrom(text)) { if (ctx.isTo(text)) { createReplacement(text, ctx, from, to, ctx.getText()); } else { createReplacement(text, ctx, from, text.getText().length(), ctx.getText()); } } else if (ctx.isTo(text)) { createReplacement(text, ctx, 0, to, ""); } else if (ctx.isStarted()) { createCommand(text, ctx); } if (ctx.isFrom(text)) { ctx.setStarted(true); } if (ctx.isTo(text) ) { ctx.setStarted(false); } return ctx.getCommand(); } private void createReplacement(Text text, ReplaceCtx ctx, int from, int to, String t) { if (t.length() > 0 || from != 0 || to != text.getText().length()) { ctx.append(new ReplaceText(text, from, to, ctx.getText())); } else { createCommand(text, ctx); } } @Override public CompositeCommand visitDocument(Document document, ReplaceCtx ctx) { traverse(document, ctx); return ctx.getCommand(); } @Override public CompositeCommand visitSpan(final Span span, final ReplaceCtx ctx) { if (ctx.isStarted() && !span.isOrContains(ctx.getTo().getModel())) { createCommand(span, ctx); } else { traverse(span, ctx); } return ctx.getCommand(); } private void createCommand(final INode node, final ReplaceCtx ctx) { ctx.append(new RemoveCommand(node, new OffsetTextLocation(ctx.getFrom().getModel(), ctx.getFrom().getOffset() + ctx.getText().length()))); } protected void traverse(ICompositeNode<?> composite, ReplaceCtx ctx) { boolean started = ctx.isStarted(); for (INode node : composite.getChildren()) { if (started) { node.accept(this, ctx); } else if (node.isOrContains(ctx.getFrom().getModel())) { started = true; node.accept(this, ctx); } if (node.isOrContains(ctx.getTo().getModel())) { started = false; } } } }