/*
* Copyright 2010 The WicketForge-Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package wicketforge.action;
import com.intellij.lang.properties.PropertiesImplUtil;
import com.intellij.lang.properties.psi.PropertiesFile;
import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.actionSystem.DataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.editor.CaretModel;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorModificationUtil;
import com.intellij.openapi.editor.SelectionModel;
import com.intellij.openapi.editor.actionSystem.EditorAction;
import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
import com.intellij.openapi.editor.actionSystem.EditorWriteActionHandler;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.xml.XmlFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import wicketforge.action.ui.ExtractPropertiesDialog;
import wicketforge.search.ClassIndex;
import wicketforge.util.WicketFileUtil;
import wicketforge.util.WicketPsiUtil;
/**
* Extract text from java/markup to a properties file.
*/
public class ExtractPropertiesAction extends EditorAction {
public ExtractPropertiesAction() {
super(DEFAULTHANDLER);
}
private static EditorActionHandler DEFAULTHANDLER = new EditorWriteActionHandler() {
@Override
public void executeWriteAction(final Editor editor, DataContext dataContext) {
final Project project = editor.getProject();
if (project == null) {
return;
}
final PsiFile psiFile = DataKeys.PSI_FILE.getData(dataContext);
if (psiFile == null) {
return;
}
PsiDirectory psiDirectory = psiFile.getContainingDirectory();
if (psiDirectory == null) {
return;
}
int offset = editor.getCaretModel().getOffset();
if (offset <= 0) {
return;
}
final PsiElement psiElement = psiFile.findElementAt(offset);
if (psiElement == null) {
return;
}
final PsiClass psiClass;
String selectedText = null;
if (StdFileTypes.JAVA.equals(psiFile.getFileType())) {
psiClass = WicketPsiUtil.getParentWicketClass(psiElement);
// text to extract from String
if (psiElement.getParent() instanceof PsiLiteralExpression) {
selectedText = (String) ((PsiLiteralExpression) psiElement.getParent()).getValue();
}
if (selectedText == null) {
Messages.showErrorDialog(project, "No string to extract", "Extract Text");
return;
}
} else if (StdFileTypes.HTML.equals(psiFile.getFileType())) {
psiClass = ClassIndex.getAssociatedClass(psiFile);
// text to extract from selection
selectedText = editor.getSelectionModel().getSelectedText();
if (selectedText == null) {
Messages.showErrorDialog(project, "No selected text to extract", "Extract Text");
return;
}
} else {
return;
}
if (psiClass == null) {
return;
}
ExtractPropertiesDialog.ActionRunnable actionRunnable = new ExtractPropertiesDialog.ActionRunnable() {
@Override
public boolean run(@Nullable final Object selectedItem, @NotNull final PsiDirectory destinationDirectory, final @NotNull String key, final @NotNull String value) {
return ApplicationManager.getApplication().runWriteAction(new Computable<Boolean>() {
@Override
public Boolean compute() {
final PropertiesFile propertiesFile;
if (selectedItem instanceof ExtractPropertiesDialog.NewPropertiesFileInfo) {
// create new properties file
ExtractPropertiesDialog.NewPropertiesFileInfo newPropertiesFileInfo = (ExtractPropertiesDialog.NewPropertiesFileInfo) selectedItem;
PsiElement element = WicketFileUtil.createFileFromTemplate(newPropertiesFileInfo.getName(), destinationDirectory, newPropertiesFileInfo.getPropertiesType().getTemplateName());
if (element == null) {
Messages.showErrorDialog(project, "Could not create properties file.", "Extract Text");
return false;
}
propertiesFile = PropertiesImplUtil.getPropertiesFile((PsiFile) element);
} else if (selectedItem instanceof PropertiesFile) {
// use existing properties file
propertiesFile = (PropertiesFile) selectedItem;
} else {
throw new IllegalArgumentException("Unsupported type " + selectedItem);
}
if (propertiesFile != null) {
CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() {
@Override
public void run() {
// add
propertiesFile.addProperty(key, value);
if (psiFile instanceof XmlFile) {
// replace in html with wicket:message
String startTag = String.format("<wicket:message key=\"%s\">", key);
String endTag = "</wicket:message>";
CaretModel caret = editor.getCaretModel();
SelectionModel selection = editor.getSelectionModel();
int start = selection.getSelectionStart();
int end = selection.getSelectionEnd();
selection.removeSelection();
caret.moveToOffset(start);
EditorModificationUtil.insertStringAtCaret(editor, startTag);
// move the caret to the end of the selection
caret.moveToOffset(startTag.length() + end);
EditorModificationUtil.insertStringAtCaret(editor, endTag);
} else if (psiFile instanceof PsiJavaFile) {
// replace in java with getString(...)
final PsiExpression expression = JavaPsiFacade.getElementFactory(psiClass.getProject()).createExpressionFromText("getString(\"" + key + "\")", psiClass);
psiElement.getParent().replace(expression);
}
}
});
}
return true;
}
});
}
};
ExtractPropertiesDialog dialog = new ExtractPropertiesDialog(project, actionRunnable, "Extract Text", psiClass, psiDirectory, selectedText);
dialog.show();
}
};
}