blob: 9dc4c275cbd088ef2f85d8fe2e68da9be4470198 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2006, 2010 Soyatec (http://www.soyatec.com) 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:
* Soyatec - initial API and implementation
*******************************************************************************/
package org.eclipse.xwt.tools.ui.designer.wizards;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.xwt.IConstants;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWizard;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.xwt.tools.ui.designer.commands.AddNewChildCommand;
import org.eclipse.xwt.tools.ui.designer.commands.DeleteCommand;
import org.eclipse.xwt.tools.ui.designer.core.util.DisplayUtil;
import org.eclipse.xwt.tools.ui.designer.editor.XWTDesigner;
import org.eclipse.xwt.tools.ui.designer.parts.WidgetEditPart;
import org.eclipse.xwt.tools.ui.designer.wizards.contents.ProperyContents;
import org.eclipse.xwt.tools.ui.designer.wizards.contents.SourceContents;
import org.eclipse.xwt.tools.ui.designer.wizards.models.TextValueEntry;
import org.eclipse.xwt.tools.ui.designer.wizards.models.TextValueModel;
import org.eclipse.xwt.tools.ui.designer.wizards.pages.ExternalizeStringsWizardPage;
import org.eclipse.xwt.tools.ui.xaml.XamlAttribute;
import org.eclipse.xwt.tools.ui.xaml.XamlElement;
import org.eclipse.xwt.tools.ui.xaml.XamlFactory;
import org.eclipse.xwt.tools.ui.xaml.XamlNode;
/**
* @author xrchen (xiaoru.chen@soyatec.com)
*/
public class ExternalizeStringsWizard extends Wizard implements INewWizard {
private ExternalizeStringsWizardPage externalizeStringsWizardPage;
private ISelection selection;
private TextValueModel textValueEntrys;
private XWTDesigner designer;
private String classPerfixName;
private String classFilePath;
private String className;
private String propertyFilePath;
private String propertyName;
private TextValueModel checkedItems;
private boolean openFlag;
private CompoundCommand commandList;
/**
* Constructor for ExternalizeStringsWizard.
*/
public ExternalizeStringsWizard(TextValueModel textValueEntrys, XWTDesigner designer) {
super();
this.textValueEntrys = textValueEntrys;
this.designer = designer;
setNeedsProgressMonitor(true);
}
/**
* Adding the page to the wizard.
*/
public void addPages() {
setWindowTitle("Externalize Strings");
externalizeStringsWizardPage = new ExternalizeStringsWizardPage(selection, textValueEntrys);
addPage(externalizeStringsWizardPage);
getDefaultAccessorContents();
}
private void getDefaultAccessorContents() {
IFile inputFile = designer.getFile();
IContainer container = inputFile.getParent();
IJavaElement javaElement = JavaCore.create(container);
IPackageFragmentRoot defaultRoot = null;
if (javaElement != null && javaElement.exists()) {
IJavaProject javaProject = JavaCore.create(inputFile.getProject());
try {
IPackageFragmentRoot fragmentRoot[] = javaProject.getAllPackageFragmentRoots();
for (int i = 0; i < fragmentRoot.length; i++) {
if (fragmentRoot[i].getKind() == IPackageFragmentRoot.K_SOURCE) {
defaultRoot = fragmentRoot[i];
for (IJavaElement element : defaultRoot.getChildren()) {
if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT) {
javaElement = element;
}
}
break;
}
}
} catch (JavaModelException e) {
e.printStackTrace();
}
}
if (javaElement == null || !(javaElement instanceof IPackageFragment)) {
String projectName = inputFile.getProject().getName();
externalizeStringsWizardPage.setErrorMessage("The project " + projectName + " has not source folder.");
return;
}
externalizeStringsWizardPage.setDefaultRoot(defaultRoot);
externalizeStringsWizardPage.setDefaultFolder(defaultRoot.getResource().getFullPath().toString());
externalizeStringsWizardPage.setDefaultPackage(javaElement.getElementName());
}
/**
* This method is called when 'Finish' button is pressed in the wizard. We will create an operation and run it using wizard as execution context.
*/
public boolean performFinish() {
classFilePath = externalizeStringsWizardPage.getInfo().getClassFilePath();
className = externalizeStringsWizardPage.getInfo().getClassName() + ".java";
propertyFilePath = externalizeStringsWizardPage.getInfo().getPropertyFilePath();
propertyName = externalizeStringsWizardPage.getInfo().getPropertyName() + ".properties";
try {
doFinish(new NullProgressMonitor());
} catch (CoreException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
return false;
} catch (returnWizardPage e) {
return false;
}
return true;
}
/**
* Show a dialog to ask user whether to open the created files.
*
* @throws returnWizardPage
*/
private void showOpenFileDialog() throws returnWizardPage {
String dialogMessage = "Do you want to open " + externalizeStringsWizardPage.getInfo().getClassName() + ".java and " + externalizeStringsWizardPage.getInfo().getPropertyName() + ".properties after finish?";
String[] dialogButtonLabels = { "Open", "Cancel" };
MessageDialog messageDialog = new MessageDialog(getShell(), "Open created files", null, dialogMessage, MessageDialog.QUESTION, dialogButtonLabels, 1);
messageDialog.open();
if (messageDialog.getReturnCode() == 0) {
openFlag = true;
} else if (messageDialog.getReturnCode() == -1) {
throw new returnWizardPage();
} else {
openFlag = false;
}
}
/**
* The worker method. It will find the container, create the file if missing or just replace its nameMap, and open the editor on the newly created file.
*
* @param monitor
* @throws CoreException
* @throws IOException
* @throws returnWizardPage
*/
private void doFinish(IProgressMonitor monitor) throws CoreException, IOException, returnWizardPage {
String propertyPerfixName = propertyName.substring(0, propertyName.length() - 11);
classPerfixName = className.substring(0, className.length() - 5);
checkedItems = externalizeStringsWizardPage.getCheckedItems();
showOpenFileDialog();
// create a property file
createFile(propertyFilePath, propertyName, propertyPerfixName, false, monitor);
// create a class file
createFile(classFilePath, className, propertyPerfixName, true, monitor);
// externalize string
final Command changTextCmd = changText();
DisplayUtil.asyncExec(new Runnable() {
public void run() {
RootEditPart rootEditPart = designer.getGraphicalViewer().getRootEditPart();
rootEditPart.getViewer().getEditDomain().getCommandStack().execute(changTextCmd);
}
});
monitor.worked(1);
}
/**
* Create a file with file path and file name.
*
* @param containerName
* @param fileName
* @param isClassFile
* @param monitor
* @throws CoreException
* @throws returnWizardPage
*/
private void createFile(String containerName, String fileName, String propertyfileName, boolean isClassFile, IProgressMonitor monitor) throws CoreException, returnWizardPage {
monitor.beginTask("Creating " + fileName, 2);
final IFile file = ExternalizeStringsCommon.getIFile(containerName, fileName);
try {
InputStream stream;
if (!isClassFile) {
stream = openPropertyContentStream(checkedItems);
} else {
if (file.exists()) {
// Get the nameMap of the exist file.
StringBuffer historyContent = ExternalizeStringsCommon
.getHistoryContents(file);
// Create inputStream with exist files nameMap.
stream = openSourceContentStream(checkedItems, containerName, fileName, propertyfileName, historyContent);
} else {
// Create a new inputStream.
stream = openSourceContentStream(checkedItems, containerName, fileName, propertyfileName, null);
}
}
if (file.exists()) {
if (isClassFile) {
file.setContents(stream, true, true, monitor);
} else {
file.appendContents(stream, true, true, monitor);
}
} else {
file.create(stream, true, monitor);
}
stream.close();
// build class file
IProject project = file.getProject();
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
project.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, monitor);
} catch (IOException e) {
e.printStackTrace();
}
if (openFlag) {
getShell().getDisplay().asyncExec(new Runnable() {
public void run() {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
IDE.openEditor(page, file, true);
} catch (PartInitException e) {
e.printStackTrace();
}
}
});
}
}
/**
* Initialize source file nameMap with a text.
*/
private InputStream openSourceContentStream(TextValueModel checkedItems, String containerName, String fileName, String porpertyfileName, StringBuffer historyContent) {
IPackageFragmentRoot classRoot = externalizeStringsWizardPage.getInfo().getClassRoot();
SourceContents sourceContents = new SourceContents(checkedItems, containerName, propertyFilePath, fileName, porpertyfileName, historyContent, classRoot);
String contents = sourceContents.getSourceContents();
return new ByteArrayInputStream(contents.getBytes());
}
/**
* Initialize property file nameMap with a text.
*/
private InputStream openPropertyContentStream(TextValueModel checkedItems) {
ProperyContents properyContents = new ProperyContents(checkedItems);
String contents = properyContents.getPropertyContents();
return new ByteArrayInputStream(contents.getBytes());
}
/**
* We will accept the selection in the workbench to see if we can initialize from it.
*
* @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
*/
public void init(IWorkbench workbench, IStructuredSelection selection) {
this.selection = selection;
}
/**
* Externalize string.
*/
private Command changText() {
commandList = new CompoundCommand();
RootEditPart rootEditPart = designer.getGraphicalViewer().getRootEditPart();
EditPart contents = rootEditPart.getContents();
Object textValueEntry[] = externalizeStringsWizardPage.getCheckedItems().elements();
for (int i = 0; i < textValueEntry.length; i++) {
if (textValueEntry[i] instanceof TextValueEntry) {
String value = ((TextValueEntry) textValueEntry[i]).getValue();
String key = ((TextValueEntry) textValueEntry[i]).getKey();
externalizeText(contents, value, key, "text");
externalizeText(contents, value, key, "toolTipText");
}
}
return commandList.unwrap();
}
/**
* Change the parent editPart text value to the key.
*
* @param editPart
* @param value
* @param key
*/
private void externalizeText(EditPart editPart, String value, String key, String type) {
if (editPart instanceof WidgetEditPart) {
XamlNode node = ((WidgetEditPart) editPart).getCastModel();
XamlAttribute attribute = node.getAttribute(type, IConstants.XWT_NAMESPACE);
if (attribute != null) {
if (value.equals(attribute.getValue())) {
commandList.add(new DeleteCommand(attribute));
attribute = null;
if (attribute == null) {
attribute = XamlFactory.eINSTANCE.createAttribute(type, IConstants.XWT_NAMESPACE);
}
attribute.setUseFlatValue(true);
XamlElement child = attribute.getChild("Static", IConstants.XWT_X_NAMESPACE);
if (child == null) {
child = XamlFactory.eINSTANCE.createElement("Static", IConstants.XWT_X_NAMESPACE);
}
String classPakage = externalizeStringsWizardPage.getInfo().getSourcePackage();
XamlElement childElement = child.getChild(classPerfixName + "." + key, IConstants.XAML_CLR_NAMESPACE_PROTO + classPakage);
if (childElement != null) {
child.getChildNodes().remove(childElement);
}
childElement = XamlFactory.eINSTANCE.createElement(classPerfixName + "." + key, IConstants.XAML_CLR_NAMESPACE_PROTO + classPakage);
commandList.add(new AddNewChildCommand(child, childElement));
commandList.add(new AddNewChildCommand(attribute, child));
if (!node.getAttributes().contains(attribute)) {
commandList.add(new AddNewChildCommand(node, attribute));
}
}
}
if (editPart.getChildren().size() > 0) {
externalizeChildren(editPart, value, key, type);
}
} else if (editPart.getChildren().size() > 0) {
externalizeChildren(editPart, value, key, type);
}
}
/**
* Change the editPart's children text value to the key.
*
* @param editPart
*/
private void externalizeChildren(EditPart editPart, String value, String key, String type) {
List child = editPart.getChildren();
for (int i = 0; i < child.size(); i++) {
if (child.get(i) instanceof EditPart) {
externalizeText((EditPart) child.get(i), value, key, type);
}
}
}
}
/**
* Create a exception to cancel externalize.
*
* @author chenxiaoru
*
*/
class returnWizardPage extends Exception {
/**
* serialVersionUID
*/
private static final long serialVersionUID = -4274509502796514787L;
returnWizardPage() {
super("Return the wizard page");
}
}