blob: 9b280aec69689fbb4e400b1126aad74490a97605 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2010 BSI Business Systems Integration AG.
* 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:
* BSI Business Systems Integration AG - initial API and implementation
******************************************************************************/
package org.eclipse.scout.nls.sdk.simple.ui.wizard;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaModel;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.JavaPlugin;
import org.eclipse.jdt.internal.ui.wizards.NewWizardMessages;
import org.eclipse.jdt.internal.ui.wizards.TypedElementSelectionValidator;
import org.eclipse.jdt.internal.ui.wizards.TypedViewerFilter;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jdt.ui.JavaElementSorter;
import org.eclipse.jdt.ui.StandardJavaElementContentProvider;
import org.eclipse.jdt.ui.wizards.NewTypeWizardPage;
import org.eclipse.jface.bindings.keys.KeyStroke;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.scout.commons.OptimisticLock;
import org.eclipse.scout.nls.sdk.internal.NlsCore;
import org.eclipse.scout.nls.sdk.internal.jdt.IResourceFilter;
import org.eclipse.scout.nls.sdk.internal.jdt.NlsJdtUtility;
import org.eclipse.scout.nls.sdk.internal.ui.FieldValidator;
import org.eclipse.scout.nls.sdk.internal.ui.NlsUi;
import org.eclipse.scout.nls.sdk.internal.ui.TextButtonField;
import org.eclipse.scout.nls.sdk.internal.ui.TextField;
import org.eclipse.scout.nls.sdk.internal.ui.dialog.ResourceDialog;
import org.eclipse.scout.nls.sdk.internal.ui.fields.IInputChangedListener;
import org.eclipse.scout.nls.sdk.internal.ui.fields.TextProposalField;
import org.eclipse.scout.nls.sdk.internal.ui.formatter.IInputValidator;
import org.eclipse.scout.nls.sdk.simple.internal.NlsSdkSimple;
import org.eclipse.scout.nls.sdk.simple.operations.NewNlsFileOperationDesc;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.dialogs.ElementTreeSelectionDialog;
@SuppressWarnings({"restriction", "deprecation"})
public class NewNlsFileWizardPage2 extends NewTypeWizardPage {
private Composite m_rootPane;
private TextButtonField m_containerField;
private TextProposalField m_package;
private TextField<String> m_className;
private TextProposalField m_translationFolderField;
private TextField<String> m_translationFileName;
private final FieldValidator m_fieldValidator;
private final P_RootContainerModifyListener m_containerFieldModifyListener;
private final NewNlsFileOperationDesc m_desc;
private final OptimisticLock m_lock = new OptimisticLock();
private final PackageProposalModel m_packageProposalModel;
public NewNlsFileWizardPage2(String pageName, NewNlsFileOperationDesc desc) {
super(true, pageName);
setTitle("Create a new NLS class");
setDescription("This class will be referenced to get a translated text.");
m_desc = desc;
m_fieldValidator = new FieldValidator();
m_containerFieldModifyListener = new P_RootContainerModifyListener();
m_packageProposalModel = new PackageProposalModel();
setPageComplete(false);
}
@Override
public void createControl(Composite parent) {
m_rootPane = new Composite(parent, SWT.NONE);
attachGridData(createServiceGroup(m_rootPane));
attachGridData(createTranslationGroup(m_rootPane));
// layout
m_rootPane.setLayout(new GridLayout(1, false));
initUi();
}
private void initUi() {
m_desc.addPropertyChangeListener(new P_DescPropertyChangedListener());
for (Entry<String, Object> entry : m_desc.getPropertiesMap().entrySet()) {
handlePropertyChanged(entry.getKey(), null, entry.getValue());
}
}
protected Control createServiceGroup(Composite parent) {
Group group = new Group(parent, SWT.NONE);
group.setText("Texts Class");
m_containerField = new TextButtonField(group);
m_fieldValidator.addField(m_containerField);
// m_containerField.setInputFormatter(new P_RootPackageFormatter());
// m_containerField.setTextEnabled(false);
m_containerField.setLabelText("Source Folder");
m_containerField.setButtonText("Browse");
m_containerField.addTextModifyListener(m_containerFieldModifyListener);
m_containerField.addButtonSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
IPackageFragmentRoot frag = chooseContainer();
setPackageFragmentRoot(frag, false);
if (frag == null) {
m_desc.setSourceContainer(null);
}
else {
m_desc.setSourceContainer(frag.getPath());
}
}
});
KeyStroke stoke = KeyStroke.getInstance(SWT.CONTROL, ' ');
m_package = new TextProposalField(group, m_packageProposalModel, stoke);
m_package.setLabelText("Package");
m_package.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
m_desc.setPackage(m_package.getText());
}
});
m_package.setLabelProvider(m_packageProposalModel);
NlsUi.decorate(m_package, false);
m_fieldValidator.addField(m_package);
m_className = new TextField<String>(group);
m_fieldValidator.addField(m_className);
m_className.setLabelText("Class Name");
m_className.addInputChangedListener(new IInputChangedListener<String>() {
@Override
public void inputChanged(String input) {
m_desc.setClassName(input);
}
});
m_className.setInputValidator(new IInputValidator() {
private String m_regexp = "\\b[A-Za-z][a-zA-Z0-9_]{0,200}\\b";
@Override
public IStatus isValid(String value) {
if (value.matches(m_regexp)) {
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
});
group.setLayout(new GridLayout(1, true));
attachGridData(m_containerField);
attachGridData(m_package);
attachGridData(m_className);
return group;
}
private Control createTranslationGroup(Composite parent) {
Group group = new Group(parent, SWT.NONE);
group.setText("Translation File(s)");
ResourceProposalModel model = new ResourceProposalModel();
List<IProject> projectList = new ArrayList<IProject>();
if (m_desc.getPlugin() != null) {
try {
projectList = NlsSdkSimple.getProjectGroup(m_desc.getPlugin());
}
catch (FileNotFoundException e) {
NlsCore.logWarning(e);
}
catch (CoreException e) {
NlsCore.logWarning(e);
}
}
model.setResourceFilter(new IResourceFilter() {
@Override
public boolean accept(IProject project, IResource resource) {
if (resource instanceof IFolder) {
IFolder folder = (IFolder) resource;
IJavaProject jp = JavaCore.create(project);
try {
if (jp.getOutputLocation().toOSString().equals(folder.getFullPath().toOSString())) {
return false;
}
}
catch (JavaModelException e) {
NlsCore.logWarning(e);
}
if (folder.getProjectRelativePath().toOSString().equals("META-INF")) {
return false;
}
return true;
}
return false;
}
});
model.setProjects(projectList.toArray(new IProject[projectList.size()]));
KeyStroke stoke = KeyStroke.getInstance(SWT.CONTROL, ' ');
m_translationFolderField = new TextProposalField(group, model, stoke);
m_translationFolderField.setLabelText("Translations Folder");
m_translationFolderField.setLabelProvider(model);
m_translationFolderField.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
m_desc.setTranslationFolder(m_translationFolderField.getText());
}
});
NlsUi.decorate(m_translationFolderField, false);
m_translationFileName = new TextField<String>(group, TextField.VALIDATE_ON_MODIFY);
m_fieldValidator.addField(m_translationFileName);
m_translationFileName.setLabelText("Translation File Prefix");
m_translationFileName.setToolTipText("e.g. messages for messages[_language].properties");
m_translationFileName.addInputChangedListener(new IInputChangedListener<String>() {
@Override
public void inputChanged(String input) {
m_desc.setTranlationFileName(input);
}
});
m_translationFileName.setInputValidator(new IInputValidator() {
private String m_regexp = "\\b[A-Za-z][a-zA-Z0-9_]{0,200}\\b";
@Override
public IStatus isValid(String value) {
if (value.matches(m_regexp)) {
return Status.OK_STATUS;
}
return Status.CANCEL_STATUS;
}
});
// layout
group.setLayout(new GridLayout(1, true));
attachGridData(m_translationFolderField);
attachGridData(m_translationFileName);
return group;
}
protected IFolder chooseTranslationFolder() {
ResourceDialog dialog = new ResourceDialog(getShell(), "Choose Folder", m_desc.getPlugin());
dialog.setInitialExpansion(new IResource[]{m_desc.getPlugin()});
dialog.setInitialSelection(new IResource[]{m_desc.getPlugin()});
dialog.addViewerFilter(new ViewerFilter() {
@Override
public Object[] filter(Viewer viewer, Object parent, Object[] elements) {
List<Object> elList = new LinkedList<Object>();
for (Object e : elements) {
if (e instanceof IContainer) {
if (parent instanceof IProject) {
IJavaProject jp = JavaCore.create((IProject) parent);
try {
if (!((IContainer) e).getProjectRelativePath().lastSegment().equals(
jp.getOutputLocation().lastSegment())) {
elList.add(e);
}
}
catch (JavaModelException e1) {
NlsCore.logWarning(e1);
}
}
else {
elList.add(e);
}
}
}
return elList.toArray();
}
@Override
public boolean select(Viewer viewer, Object parentElement, Object element) {
return element instanceof IFolder;
}
});
if (dialog.open() == Window.OK) {
IResource selection = dialog.getFirstResult();
if (selection instanceof IFolder) {
return (IFolder) selection;
}
}
return null;
}
@Override
protected IPackageFragmentRoot chooseContainer() {
IJavaElement initElement = getPackageFragmentRoot();
Class<?>[] acceptedClasses = new Class[]{IPackageFragmentRoot.class, IJavaProject.class};
TypedElementSelectionValidator validator = new TypedElementSelectionValidator(acceptedClasses, false) {
@Override
public boolean isSelectedValid(Object element) {
try {
if (element instanceof IJavaProject) {
IJavaProject jproject = (IJavaProject) element;
IPath path = jproject.getProject().getFullPath();
return (jproject.findPackageFragmentRoot(path) != null);
}
else if (element instanceof IPackageFragmentRoot) {
return (((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE);
}
return true;
}
catch (JavaModelException e) {
JavaPlugin.log(e.getStatus()); // just log, no UI in validation
}
return false;
}
};
acceptedClasses = new Class[]{IJavaModel.class, IPackageFragmentRoot.class, IJavaProject.class};
ViewerFilter filter = new TypedViewerFilter(acceptedClasses) {
@Override
public boolean select(Viewer viewer, Object parent, Object element) {
if (element instanceof IPackageFragmentRoot) {
try {
return (((IPackageFragmentRoot) element).getKind() == IPackageFragmentRoot.K_SOURCE);
}
catch (JavaModelException e) {
JavaPlugin.log(e.getStatus()); // just log, no UI in validation
return false;
}
}
return super.select(viewer, parent, element);
}
};
StandardJavaElementContentProvider provider = new StandardJavaElementContentProvider();
ILabelProvider labelProvider = new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_DEFAULT);
ElementTreeSelectionDialog dialog = new ElementTreeSelectionDialog(getShell(), labelProvider, provider);
dialog.setValidator(validator);
dialog.setSorter(new JavaElementSorter());
dialog.setTitle(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_title);
dialog.setMessage(NewWizardMessages.NewContainerWizardPage_ChooseSourceContainerDialog_description);
dialog.addFilter(filter);
dialog.setInput(JavaCore.create(m_desc.getPlugin()));
dialog.setInitialSelection(initElement);
dialog.setHelpAvailable(false);
if (dialog.open() == Window.OK) {
Object element = dialog.getFirstResult();
if (element instanceof IJavaProject) {
IJavaProject jproject = (IJavaProject) element;
return jproject.getPackageFragmentRoot(jproject.getProject());
}
else if (element instanceof IPackageFragmentRoot) {
return (IPackageFragmentRoot) element;
}
return null;
}
return null;
}
@Override
public Control getControl() {
return m_rootPane;
}
@Override
public void setVisible(boolean visible) {
if (m_rootPane != null && !m_rootPane.isDisposed()) {
m_rootPane.setVisible(visible);
}
}
private void revalidate() {
// enable disable
m_fieldValidator.reset();
if (m_desc.getSourceContainer() == null) {
m_fieldValidator.setDisabled(m_package);
}
m_fieldValidator.apply();
// messages
setMessage(null);
if (m_desc.getSourceContainer() == null) {
setMessage("The source container must be specified.", WizardPage.WARNING);
setPageComplete(false);
return;
}
if (m_desc.getPackage() == null) {
setMessage("The package must be specified.", WizardPage.WARNING);
setPageComplete(false);
return;
}
if (m_desc.getClassName() == null) {
setMessage("The class name must be specified.", WizardPage.WARNING);
setPageComplete(false);
return;
}
if (m_desc.getTranslationFolder() == null) {
setMessage("The translation folder must be specified.", WizardPage.WARNING);
setPageComplete(false);
return;
}
if (m_desc.getTranlationFileName() == null) {
setMessage("The translation file name must be specified.", WizardPage.WARNING);
setPageComplete(false);
return;
}
setPageComplete(true);
}
private void attachGridData(Control c) {
GridData data = new GridData();
data.horizontalAlignment = SWT.FILL;
data.grabExcessHorizontalSpace = true;
c.setLayoutData(data);
}
protected void handlePropertyChanged(String name, Object oldValue, Object newValue) {
if (name.equals(NewNlsFileOperationDesc.PROP_PLUGIN)) {
m_containerFieldModifyListener.setPlugin((IProject) newValue);
m_packageProposalModel.setProject((IProject) newValue);
}
if (name.equals(NewNlsFileOperationDesc.PROP_SRC_CONTAINER)) {
try {
if (m_lock.acquire()) {
IPath path = (IPath) newValue;
if (path == null) {
m_containerField.setText("");
m_desc.setSourceContainer(null);
}
else {
m_containerField.setText(path.lastSegment());
m_desc.setSourceContainer(path);
}
}
}
finally {
m_lock.release();
}
}
revalidate();
}
private class P_DescPropertyChangedListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
handlePropertyChanged(evt.getPropertyName(), evt.getOldValue(), evt.getNewValue());
}
}
private class P_RootContainerModifyListener implements ModifyListener {
private HashMap<String, IClasspathEntry> m_map = new HashMap<String, IClasspathEntry>();
private P_RootContainerModifyListener() {
}
public void setPlugin(IProject project) {
if (project == null) {
return;
}
m_map.clear();
IJavaProject jp = JavaCore.create(project);
try {
for (IClasspathEntry entry : NlsJdtUtility.getSourceLocations(jp)) {
m_map.put(entry.getPath().toPortableString(), entry);
}
}
catch (JavaModelException e) {
NlsCore.logWarning(e);
}
}
@Override
public void modifyText(ModifyEvent e) {
if (m_lock.acquire()) {
try {
String input = m_containerField.getText();
for (IClasspathEntry entry : m_map.values()) {
if (entry.getPath().lastSegment().equals(input)) {
m_desc.setSourceContainer(entry.getPath());
}
else {
setMessage("invalid source container", WizardPage.WARNING);
}
}
}
finally {
m_lock.release();
}
}
}
}
}