blob: 47e8ba413b1c67153bf49e080a1192b97d335674 [file] [log] [blame]
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
* Copyright 2004, 2008 Fraunhofer Gesellschaft, Munich, Germany,
* for its Fraunhofer Institute for Computer Architecture and Software
* Technology (FIRST), Berlin, Germany and Technical University Berlin,
* Germany.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Please visit http://www.eclipse.org/objectteams for updates and contact.
*
* Contributors:
* Fraunhofer FIRST - Initial API and implementation
* Technical University Berlin - Initial API and implementation
**********************************************************************/
package org.eclipse.objectteams.otdt.internal.ui.wizards.listeners;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaConventions;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.internal.ui.dialogs.FilteredTypesSelectionDialog;
import org.eclipse.jdt.internal.ui.dialogs.StatusInfo;
import org.eclipse.jdt.internal.ui.wizards.dialogfields.DialogField;
import org.eclipse.jface.window.Window;
import org.eclipse.jdt.internal.corext.util.Messages;
import org.eclipse.objectteams.otdt.core.IOTType;
import org.eclipse.objectteams.otdt.core.IRoleType;
import org.eclipse.objectteams.otdt.core.OTModelManager;
import org.eclipse.objectteams.otdt.internal.core.OTJavaElement;
import org.eclipse.objectteams.otdt.internal.ui.wizards.NewRoleWizardPage;
import org.eclipse.objectteams.otdt.internal.ui.wizards.NewTypeWizardPage;
import org.eclipse.objectteams.otdt.internal.ui.wizards.OTNewWizardMessages;
import org.eclipse.objectteams.otdt.ui.OTDTUIPlugin;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
/**
* The main listener class for org.eclipse.objectteams.otdt.internal.ui.wizards.NewRoleWizardPage.
* It listens to changes of the entry fields and clicks on the browse buttons
* of the observed NewRoleWizardPage.
*
* @author kaschja
* @version $Id: NewRoleWizardPageListener.java 23435 2010-02-04 00:14:38Z stephan $
*/
public class NewRoleWizardPageListener extends NewTypeWizardPageListener
{
protected static final int BASE = 20;
private IStatus _baseStatus = new StatusInfo();
// cache this info (hierarchy operation is expensive)
private IType[] fSuperTeams = null;
public NewRoleWizardPageListener(NewTypeWizardPage observedPage)
{
super(observedPage);
}
protected int getChangedElement(DialogField field)
{
if (getObservedPage() instanceof NewRoleWizardPage)
{
NewRoleWizardPage page = (NewRoleWizardPage) getObservedPage();
if (field == page.getBaseClassDialogField())
{
return BASE;
}
}
return super.getChangedElement(field);
}
protected void performReviews(int change)
{
super.performReviews(change);
if ((change == CONTAINER)
|| (change == PACKAGE)
|| (change == ENCLOSINGTYPE)
|| (change == BASE)
|| (change == NAME) )
{
_baseStatus = validateBaseClass();
handleImplicitSuperclassDialogField();
}
}
protected void handleChangeControlPressed(DialogField field)
{
if (!(getObservedPage() instanceof NewRoleWizardPage) )
{
return;
}
NewRoleWizardPage page = (NewRoleWizardPage) getObservedPage();
if (field == page.getBaseClassDialogField())
{
IType type = chooseBaseType();
if (type != null)
{
String str = type.getFullyQualifiedName('.');
page.setBaseClassName(str);
}
}
else
{
super.handleChangeControlPressed(field);
}
}
protected IStatus validateTypeName()
{
// FIXME(SH): admit parameterized name!
IStatus superStatus = super.validateTypeName();
if (superStatus.getSeverity() == IStatus.ERROR)
{
return superStatus;
}
NewRoleWizardPage page = (NewRoleWizardPage) getObservedPage();
String enclosingTypeName = page.getEnclosingTypeName();
// strip package name off of enclosing type
enclosingTypeName = enclosingTypeName.substring(enclosingTypeName.lastIndexOf('.') + 1);
String simpleRoleName = page.getTypeName();
if (simpleRoleName.equals(enclosingTypeName))
{
StatusInfo status = new StatusInfo();
status.setError(OTNewWizardMessages.NewRole_role_hides_team);
return status;
}
return superStatus;
}
protected IType chooseEnclosingType()
{
IPackageFragmentRoot root= getObservedPage().getPackageFragmentRoot();
if (root == null)
return null;
return chooseTeam( root,
getObservedPage().getShell(),
getObservedPage().getWizard().getContainer(),
org.eclipse.objectteams.otdt.internal.ui.wizards.OTNewWizardMessages.NewRoleWizardPage_ChooseEnclosingTypeDialog_title,
org.eclipse.objectteams.otdt.internal.ui.wizards.OTNewWizardMessages.NewRoleWizardPage_ChooseEnclosingTypeDialog_description,
Signature.getSimpleName(getObservedPage().getEnclosingTypeName()));
}
protected IType chooseSuperType()
{
IPackageFragmentRoot root = getObservedPage().getPackageFragmentRoot();
if (root == null)
{
return null;
}
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { root.getJavaProject() });
FilteredTypesSelectionDialog dialog = new FilteredTypesSelectionDialog(
getObservedPage().getShell(),
false,
getObservedPage().getWizard().getContainer(),
scope,
IJavaSearchConstants.CLASS);
dialog.setTitle(OTNewWizardMessages.NewRoleWizardPage_SuperclassDialog_title);
dialog.setMessage(OTNewWizardMessages.NewRoleWizardPage_SuperclassDialog_message);
dialog.setInitialPattern(getObservedPage().getSuperTypeName());
if (dialog.open() == Window.OK)
{
return (IType) dialog.getFirstResult();
}
return null;
}
private IType chooseBaseType()
{
IPackageFragmentRoot root = getObservedPage().getPackageFragmentRoot();
if (root == null)
{
return null;
}
IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[] { root.getJavaProject() });
FilteredTypesSelectionDialog dialog = new FilteredTypesSelectionDialog(getObservedPage().getShell(),
false,
getObservedPage().getWizard().getContainer(),
scope,
IJavaSearchConstants.TYPE)
{
IStatus status; // duplicate private field
@Override protected void updateStatus(IStatus status) {
this.status = status;
super.updateStatus(status);
}
@Override
protected void okPressed() {
// super version is too strict, replace warning with OK in order to pass
if (status.getCode() == IStatus.WARNING)
updateStatus(StatusInfo.OK_STATUS);
super.okPressed();
}
};
dialog.setTitle(OTNewWizardMessages.NewRoleWizardPage_BaseclassDialog_title);
dialog.setMessage(OTNewWizardMessages.NewRoleWizardPage_BaseclassDialog_message);
dialog.setInitialPattern( ((NewRoleWizardPage)getObservedPage()).getBaseClassName());
dialog.setValidator(new ISelectionStatusValidator()
{
public IStatus validate(Object[] selection) {
if ( selection != null && selection.length > 0
&& selection[0] instanceof IType)
return validateBaseClassName(
getObservedPage().getEnclosingType(),
((IType)selection[0]).getElementName());
return StatusInfo.OK_STATUS;
};
});
if (dialog.open() == FilteredTypesSelectionDialog.OK)
{
return (IType) dialog.getFirstResult();
}
return null;
}
protected void handleEnclosingTypeDialogFieldIsEmpty(StatusInfo status)
{
status.setError(org.eclipse.jdt.internal.ui.wizards.NewWizardMessages.NewTypeWizardPage_error_EnclosingTypeEnterName);
}
@Override
protected IStatus validateEnclosingType() {
IStatus status = super.validateEnclosingType();
if (status.isOK())
cacheSuperTeams();
return status;
}
private void cacheSuperTeams() {
try {
IType enclosingType = this.getObservedPage().getEnclosingType();
ITypeHierarchy hierarchy = enclosingType.newSupertypeHierarchy(null);
fSuperTeams = hierarchy.getAllSuperclasses(enclosingType);
}
catch (JavaModelException ex) {
OTDTUIPlugin.logException("Problems creating supertype hierarchy", ex); //$NON-NLS-1$
}
}
// ------ validation --------
public IStatus[] getRelevantStates(boolean ignoreFirstField)
{
if (ignoreFirstField)
return new IStatus[]
{
getObservedPage().getContainerStatus(),
_packageStatus,
_enclosingTeamStatus,
// not this one: _typeNameStatus,
_baseStatus,
_modifierStatus,
_superTypeStatus,
_superInterfacesStatus,
};
else
// status of all used components
return new IStatus[]
{
getObservedPage().getContainerStatus(),
_packageStatus,
_enclosingTeamStatus,
_typeNameStatus,
_baseStatus,
_modifierStatus,
_superTypeStatus,
_superInterfacesStatus,
};
}
private void handleImplicitSuperclassDialogField()
{
if (!(getObservedPage() instanceof NewRoleWizardPage))
return;
NewRoleWizardPage page = (NewRoleWizardPage) getObservedPage();
page.setImplicitSuperclassName(""); //$NON-NLS-1$
if (hasTypeNameError()) // don't proceed if there is an error already
return;
IType enclosingTeam = page.getEnclosingType();
if (enclosingTeam != null)
{
if (fSuperTeams == null)
cacheSuperTeams();
for (int idx = 0; idx < fSuperTeams.length; idx++)
{
IType memberType = fSuperTeams[idx].getType(page.getTypeName());
IOTType otType = OTModelManager.getOTElement(memberType);
if (otType != null && otType instanceof IRoleType)
{
String fullQualName = memberType.getFullyQualifiedName('.');
page.setImplicitSuperclassName(fullQualName);
return;
}
}
}
}
private boolean hasTypeNameError()
{
IStatus[] stati = new IStatus[] {
getObservedPage().getContainerStatus(),
_packageStatus,
_enclosingTeamStatus,
_typeNameStatus
};
return hasErrorStatus(stati);
}
private IStatus validateBaseClass()
{
NewRoleWizardPage page = (NewRoleWizardPage) getObservedPage();
String baseclassName = page.getBaseClassName();
if (baseclassName.length() == 0)
return StatusInfo.OK_STATUS; // a Role without a playedBy relation is just fine
IType enclosingType = getObservedPage().getEnclosingType();
String[][] baseType = null;
try {
if (enclosingType != null)
baseType = enclosingType.resolveType(baseclassName);
} catch (JavaModelException e) { /* nop */ }
IStatus validJava = StatusInfo.OK_STATUS;
if (baseType == null) { // check valid base class name only if base class doesn't yet exist
String compliance = JavaCore.VERSION_1_8;
if (enclosingType != null) {
IJavaProject javaProject = enclosingType.getJavaProject();
compliance = javaProject.getOption(JavaCore.COMPILER_COMPLIANCE, true);
}
// ERRORS:
validJava = JavaConventions.validateJavaTypeName(baseclassName, compliance, compliance);
if (validJava.getSeverity() == IStatus.ERROR)
return new StatusInfo(IStatus.ERROR,
Messages.format(org.eclipse.jdt.internal.ui.wizards.NewWizardMessages.NewTypeWizardPage_error_InvalidTypeName,
validJava.getMessage()));
}
// check shadowing (ERROR):
IStatus status = validateBaseClassName(enclosingType, baseclassName);
if (!status.isOK())
return status;
// WARNINGS:
if (validJava.getSeverity() == IStatus.WARNING)
return new StatusInfo(IStatus.WARNING,
Messages.format(org.eclipse.jdt.internal.ui.wizards.NewWizardMessages.NewTypeWizardPage_warning_TypeNameDiscouraged,
validJava.getMessage()));
return StatusInfo.OK_STATUS;
}
IStatus validateBaseClassName(IType enclosingType, String name) {
IStatus warning = null;
while (enclosingType != null) {
if (name.equals(enclosingType.getElementName()) && warning == null) {
warning = new StatusInfo(StatusInfo.WARNING,
Messages.format(
OTNewWizardMessages.NewRole_base_class_equals_enclosing,
new Object[] {name, getObservedPage().getTypeName()}));
}
try {
for (IJavaElement member : enclosingType.getChildren()) {
if ( member.getElementType() == OTJavaElement.ROLE
&& member.getElementName().equals(name))
return new StatusInfo(StatusInfo.ERROR,
Messages.format(
OTNewWizardMessages.NewRole_base_class_equals_member,
name));
}
} catch (JavaModelException e) { /* nop */ }
enclosingType = enclosingType.getDeclaringType();
}
return warning != null ? warning : StatusInfo.OK_STATUS;
}
}