package com.redhat.ceylon.eclipse.code.refactor;
/*******************************************************************************
* Copyright (c) 2005, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
import static com.redhat.ceylon.eclipse.ui.CeylonPlugin.PLUGIN_ID;
import java.util.List;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.link.LinkedPosition;
import org.eclipse.jface.text.link.LinkedPositionGroup;
import org.eclipse.ltk.core.refactoring.RefactoringStatus;
import org.eclipse.ltk.ui.refactoring.RefactoringWizard;
import com.redhat.ceylon.compiler.typechecker.tree.Tree;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.Identifier;
import com.redhat.ceylon.compiler.typechecker.tree.Tree.ImportModule;
import com.redhat.ceylon.compiler.typechecker.tree.Visitor;
import com.redhat.ceylon.eclipse.code.editor.CeylonEditor;
public class ChangeVersionLinkedMode extends RefactorLinkedMode {
private final Tree.ImportPath module;
private final Tree.QuotedLiteral version;
private final ChangeVersionRefactoring refactoring;
protected LinkedPosition versionPosition;
protected LinkedPositionGroup linkedPositionGroup;
private final class LinkedPositionsVisitor
extends Visitor {
private final int adjust;
private final IDocument document;
private final LinkedPositionGroup linkedPositionGroup;
int i=1;
private LinkedPositionsVisitor(int adjust, IDocument document,
LinkedPositionGroup linkedPositionGroup) {
this.adjust = adjust;
this.document = document;
this.linkedPositionGroup = linkedPositionGroup;
}
@Override
public void visit(ImportModule that) {
super.visit(that);
addLinkedPosition(document, that.getVersion(),
that.getImportPath());
}
boolean eq(Tree.ImportPath x, Tree.ImportPath y) {
List<Identifier> xids = x.getIdentifiers();
List<Identifier> yids = y.getIdentifiers();
if (xids.size()!=yids.size()) {
return false;
}
for (int i=0; i<xids.size(); i++) {
if (!xids.get(0).equals(yids.get(i))) {
return false;
}
}
return true;
}
private void addLinkedPosition(final IDocument document,
Tree.QuotedLiteral version, Tree.ImportPath path) {
if (version!=null && path!=null && eq(module, path)) {
try {
int pos = version.getStartIndex()+adjust+1;
int len = version.getText().length()-2;
linkedPositionGroup.addPosition(new LinkedPosition(document,
pos, len, i++));
}
catch (BadLocationException e) {
e.printStackTrace();
}
}
}
}
public ChangeVersionLinkedMode(Tree.QuotedLiteral version,
Tree.ImportPath module, CeylonEditor editor) {
super(editor);
this.module = module;
this.version = version;
this.refactoring = new ChangeVersionRefactoring(editor);
}
@Override
protected String getName() {
String quoted = version.getText();
return quoted.substring(1, quoted.length()-1);
}
@Override
protected void setName(String version) {
refactoring.setNewVersion(version);
}
@Override
protected String getActionName() {
return PLUGIN_ID + ".action.changeVersion";
}
@Override
public String getHintTemplate() {
return "Enter new version for " + refactoring.getCount() +
" occurrences of \"" + getName() + "\" {0}";
}
private void addLinkedPositions(final IDocument document, Tree.CompilationUnit rootNode,
final int adjust, final LinkedPositionGroup linkedPositionGroup)
throws BadLocationException {
versionPosition = new LinkedPosition(document,
version.getStartIndex()+1,
getInitialName().length(), 0);
linkedPositionGroup.addPosition(versionPosition);
rootNode.visit(new LinkedPositionsVisitor(adjust, document, linkedPositionGroup));
}
private boolean isEnabled() {
return !getNewNameFromNamePosition().isEmpty();
}
@Override
protected boolean canStart() {
return refactoring.getEnabled();
}
@Override
protected boolean forceSave() {
return true;
}
@Override
protected int getSaveMode() {
return refactoring.getSaveMode();
}
@Override
public void done() {
if (isEnabled()) {
try {
setName(getNewNameFromNamePosition());
revertChanges();
if (isShowPreview()) {
openPreview();
}
else {
new RefactoringExecutionHelper(refactoring,
RefactoringStatus.WARNING,
RefactoringSaveHelper.SAVE_CEYLON_REFACTORING,
editor.getSite().getShell(),
editor.getSite().getWorkbenchWindow())
.perform(false, true);
}
}
catch (Exception e) {
e.printStackTrace();
}
super.done();
}
else {
super.cancel();
}
}
@Override
protected void openPreview() {
new ChangeVersionRefactoringAction(editor) {
@Override
public Refactoring createRefactoring() {
return ChangeVersionLinkedMode.this.refactoring;
}
@Override
public RefactoringWizard createWizard(Refactoring refactoring) {
return new ChangeVersionWizard((AbstractRefactoring) refactoring) {
@Override
protected void addUserInputPages() {}
};
}
}.run();
}
@Override
protected void openDialog() {
new ChangeVersionRefactoringAction(editor) {
@Override
public AbstractRefactoring createRefactoring() {
return ChangeVersionLinkedMode.this.refactoring;
}
}.run();
}
@Override
protected String getNewNameFromNamePosition() {
try {
return versionPosition.getContent();
}
catch (BadLocationException e) {
return getInitialName();
}
}
@Override
protected void setupLinkedPositions(final IDocument document, final int adjust)
throws BadLocationException {
linkedPositionGroup = new LinkedPositionGroup();
addLinkedPositions(document,
editor.getParseController().getLastCompilationUnit(),
adjust, linkedPositionGroup);
linkedModeModel.addGroup(linkedPositionGroup);
}
}