mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-07 00:05:53 +02:00
Fix for 83556
The MBS now validates the configuration names more carefully. It checks for duplicates in a case-insenstive way. It also looks for invalid whitespaces at the start of a config name. It also disallows names containing \/:*?"<> Also corrected a file that had a local variable called "enum" which is now a "sort-of" reserved keyword in Java 1.5
This commit is contained in:
parent
66d9c39ea6
commit
d5994ef1b5
4 changed files with 152 additions and 59 deletions
|
@ -101,8 +101,9 @@ NewConfiguration.label.name=Name:
|
|||
NewConfiguration.label.group=Copy settings from
|
||||
NewConfiguration.label.copy=Default configuration:
|
||||
NewConfiguration.label.clone=Existing configuration:
|
||||
NewConfiguration.error.title=Error
|
||||
NewConfiguration.error.duplicateName=A configuration named "{0}" already exists.
|
||||
NewConfiguration.error.caseName=A configuration name that differs only in case to "{0}" exists.
|
||||
NewConfiguration.error.invalidName=The name "{0}" is invalid.
|
||||
|
||||
# ----------- Target/Config management dialog -----------------
|
||||
ManageConfig.label.configs=Manage configurations
|
||||
|
|
|
@ -220,9 +220,9 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
option.getId());
|
||||
if (enumCommand.indexOf(DEFAULT_SEPERATOR) != -1)
|
||||
enumCommand = option.getSelectedEnum();
|
||||
String enum = option.getEnumCommand(enumCommand);
|
||||
if (enum.length() > 0) {
|
||||
buf.append(enum);
|
||||
String enumeration = option.getEnumCommand(enumCommand);
|
||||
if (enumeration.length() > 0) {
|
||||
buf.append(enumeration);
|
||||
}
|
||||
break;
|
||||
case IOption.STRING :
|
||||
|
@ -339,18 +339,18 @@ public class BuildToolSettingsPage extends BuildSettingsPage {
|
|||
}
|
||||
break;
|
||||
case IOption.ENUMERATED :
|
||||
String enum = ""; //$NON-NLS-1$
|
||||
String enumeration = ""; //$NON-NLS-1$
|
||||
String[] enumValues = opt.getApplicableValues();
|
||||
for (int i = 0; i < enumValues.length; i++) {
|
||||
if (opt.getEnumCommand(enumValues[i]).equals(
|
||||
optionValue)) {
|
||||
enum = enumValues[i];
|
||||
enumeration = enumValues[i];
|
||||
optionValueExist = true;
|
||||
}
|
||||
}
|
||||
if (!enum.equals("")) //$NON-NLS-1$
|
||||
if (!enumeration.equals("")) //$NON-NLS-1$
|
||||
getToolSettingsPreferenceStore()
|
||||
.setValue(opt.getId(), enum);
|
||||
.setValue(opt.getId(), enumeration);
|
||||
break;
|
||||
case IOption.STRING_LIST :
|
||||
case IOption.INCLUDE_PATH :
|
||||
|
|
|
@ -57,8 +57,10 @@ public class ManageConfigDialog extends Dialog {
|
|||
private SortedMap existingConfigs;
|
||||
// The target the configs belong to
|
||||
private IManagedProject managedProject;
|
||||
// Map of new configurations chosen by the user
|
||||
private SortedMap newConfigs;
|
||||
/** All new configs added by the user but not yet part of target */
|
||||
private SortedMap newAddedConfigs;
|
||||
/** All new configs removed by the user but not yet part of target */
|
||||
private SortedMap removedNewConfigs;
|
||||
// The title of the dialog.
|
||||
private String title = ""; //$NON-NLS-1$
|
||||
|
||||
|
@ -269,12 +271,33 @@ public class ManageConfigDialog extends Dialog {
|
|||
* @return Map
|
||||
*/
|
||||
public SortedMap getNewConfigs() {
|
||||
if (newConfigs == null) {
|
||||
newConfigs = new TreeMap();
|
||||
if (newAddedConfigs == null) {
|
||||
newAddedConfigs = new TreeMap();
|
||||
}
|
||||
return newConfigs;
|
||||
return newAddedConfigs;
|
||||
}
|
||||
|
||||
// Answers a list of new configuration names that have been added--
|
||||
// or added and removed--by the user, but that have not yet been added
|
||||
// to the target
|
||||
private ArrayList getNewConfigNames() {
|
||||
ArrayList names = new ArrayList();
|
||||
names.addAll(getNewConfigs().keySet());
|
||||
names.addAll(getRemovedNewConfigs().keySet());
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
// This data structure hangs on to a new configuration that is added
|
||||
// by the user, then removed before it is added to the target. This is
|
||||
// a required bookeeping step because the user may change their minds and
|
||||
// restore the deleted configuration.
|
||||
private SortedMap getRemovedNewConfigs() {
|
||||
if (removedNewConfigs == null) {
|
||||
removedNewConfigs = new TreeMap();
|
||||
}
|
||||
return removedNewConfigs;
|
||||
}
|
||||
/*
|
||||
* @return the <code>IProject</code> associated with the managed project
|
||||
*/
|
||||
|
@ -286,8 +309,10 @@ public class ManageConfigDialog extends Dialog {
|
|||
* Event handler for the add button
|
||||
*/
|
||||
protected void handleNewPressed() {
|
||||
// Pop-up a dialog to properly handle the request
|
||||
NewConfigurationDialog dialog = new NewConfigurationDialog(getShell(),
|
||||
managedProject,
|
||||
getNewConfigNames(),
|
||||
ManagedBuilderUIMessages.getResourceString(CONF_DLG));
|
||||
if (dialog.open() == NewConfigurationDialog.OK) {
|
||||
// Get the new name and configuration to base the new config on
|
||||
|
@ -309,18 +334,18 @@ public class ManageConfigDialog extends Dialog {
|
|||
int selectionIndex = currentConfigList.getSelectionIndex();
|
||||
if (selectionIndex != -1){
|
||||
String selectedConfigName = currentConfigList.getItem(selectionIndex);
|
||||
String selectedConfigId = null;
|
||||
|
||||
// If this is a newly added config, remove it from that map
|
||||
// If this is a newly added config, remove it from the new map
|
||||
// and add it to a special map to support the restore use case
|
||||
if (getNewConfigs().containsKey(selectedConfigName)) {
|
||||
IConfiguration selectedConfig = (IConfiguration) getNewConfigs().get(selectedConfigName);
|
||||
selectedConfigId = selectedConfig.getId();
|
||||
getRemovedNewConfigs().put(selectedConfigName, selectedConfig);
|
||||
getNewConfigs().remove(selectedConfigName);
|
||||
} else {
|
||||
// If it is not a new item, the ID is in the existing list
|
||||
selectedConfigId = (String) getExistingConfigs().get(selectedConfigName);
|
||||
String selectedConfigId = (String) getExistingConfigs().get(selectedConfigName);
|
||||
getDeletedConfigs().put(selectedConfigName, selectedConfigId);
|
||||
}
|
||||
getDeletedConfigs().put(selectedConfigName, selectedConfigId);
|
||||
|
||||
// Clean up the UI lists
|
||||
currentConfigList.remove(selectionIndex);
|
||||
|
@ -337,21 +362,20 @@ public class ManageConfigDialog extends Dialog {
|
|||
protected void handleRestorePressed() {
|
||||
// Determine which configuration was selected
|
||||
int selectionIndex = deletedConfigList.getSelectionIndex();
|
||||
// Move the selected element from the deleted list to the current list
|
||||
// Move the selected element from the correct deleted list to the current list
|
||||
if (selectionIndex != -1){
|
||||
// Get the name of the item to delete
|
||||
String selectedConfigName = deletedConfigList.getItem(selectionIndex);
|
||||
String selectedConfigId = (String) getDeletedConfigs().get(selectedConfigName);
|
||||
|
||||
// If this was a new config (it won't be in the existing list) then add it back there
|
||||
if (!getExistingConfigs().containsKey(selectedConfigName)) {
|
||||
IConfiguration restoredConfig = managedProject.getConfiguration(selectedConfigId);
|
||||
// The deleted config may be one of the existing configs or one of the
|
||||
// new configs that have not been added to the target yet
|
||||
if (getRemovedNewConfigs().containsKey(selectedConfigName)) {
|
||||
IConfiguration restoredConfig = managedProject.getConfiguration(selectedConfigName);
|
||||
getNewConfigs().put(selectedConfigName, restoredConfig);
|
||||
getRemovedNewConfigs().remove(selectedConfigName);
|
||||
} else {
|
||||
getDeletedConfigs().remove(selectedConfigName);
|
||||
}
|
||||
|
||||
// Remove it from the deleted map
|
||||
getDeletedConfigs().remove(selectedConfigName);
|
||||
|
||||
// Clean up the UI
|
||||
deletedConfigList.remove(selectionIndex);
|
||||
deletedConfigList.setSelection(selectionIndex - 1);
|
||||
|
|
|
@ -12,11 +12,13 @@ package org.eclipse.cdt.managedbuilder.ui.properties;
|
|||
|
||||
import org.eclipse.cdt.managedbuilder.core.IProjectType;
|
||||
import org.eclipse.cdt.managedbuilder.core.IManagedProject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import org.eclipse.cdt.internal.ui.dialogs.StatusDialog;
|
||||
import org.eclipse.cdt.internal.ui.dialogs.StatusInfo;
|
||||
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
|
||||
import org.eclipse.cdt.managedbuilder.internal.ui.ManagedBuilderUIMessages;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.jface.dialogs.MessageDialog;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.ModifyEvent;
|
||||
import org.eclipse.swt.events.ModifyListener;
|
||||
|
@ -34,7 +36,7 @@ import org.eclipse.swt.widgets.Label;
|
|||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
public class NewConfigurationDialog extends Dialog {
|
||||
public class NewConfigurationDialog extends StatusDialog {
|
||||
// String constants
|
||||
private static final String PREFIX = "NewConfiguration"; //$NON-NLS-1$
|
||||
private static final String LABEL = PREFIX + ".label"; //$NON-NLS-1$
|
||||
|
@ -43,37 +45,45 @@ public class NewConfigurationDialog extends Dialog {
|
|||
private static final String GROUP = LABEL + ".group"; //$NON-NLS-1$
|
||||
private static final String COPY = LABEL + ".copy"; //$NON-NLS-1$
|
||||
private static final String CLONE = LABEL + ".clone"; //$NON-NLS-1$
|
||||
private static final String TITLE = ERROR + ".title"; //$NON-NLS-1$
|
||||
private static final String DUPLICATE = ERROR + ".duplicateName"; //$NON-NLS-1$
|
||||
private static final String CASE = ERROR + ".caseName"; //$NON-NLS-1$
|
||||
private static final String INVALID = ERROR + ".invalidName"; //$NON-NLS-1$
|
||||
|
||||
// Widgets
|
||||
private Button btnClone;
|
||||
private Button btnCopy;
|
||||
private Button btnOk;
|
||||
private Text configName;
|
||||
private Combo copyConfigSelector;
|
||||
private Combo cloneConfigSelector;
|
||||
|
||||
// Bookeeping
|
||||
private boolean clone;
|
||||
/** Default configurations defined in the toolchain description */
|
||||
private IConfiguration[] defaultConfigs;
|
||||
/** Configurations defined in the target */
|
||||
private IConfiguration[] definedConfigs;
|
||||
private IConfiguration parentConfig;
|
||||
private IManagedProject managedProject;
|
||||
private String newName;
|
||||
private String title = ""; //$NON-NLS-1$
|
||||
/** A list containing config names that have been defined but not added to the target */
|
||||
final private ArrayList reservedNames;
|
||||
final private String title;
|
||||
|
||||
|
||||
/**
|
||||
* @param parentShell
|
||||
* @param managedTarget
|
||||
* @param nameList A list of names that have been added by the user but have not yet been added to the target
|
||||
* @param title The title of the dialog
|
||||
*/
|
||||
protected NewConfigurationDialog(Shell parentShell, IManagedProject managedProject, String title) {
|
||||
protected NewConfigurationDialog(Shell parentShell, IManagedProject managedProject, ArrayList nameList, String title) {
|
||||
super(parentShell);
|
||||
this.title = title;
|
||||
setShellStyle(getShellStyle()|SWT.RESIZE);
|
||||
newName = new String();
|
||||
parentConfig = null;
|
||||
this.managedProject = managedProject;
|
||||
reservedNames = nameList;
|
||||
|
||||
// The default behaviour is to clone the settings
|
||||
clone = true;
|
||||
|
@ -133,13 +143,12 @@ public class NewConfigurationDialog extends Dialog {
|
|||
* @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
|
||||
*/
|
||||
protected void createButtonsForButtonBar(Composite parent) {
|
||||
btnOk = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
|
||||
createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
|
||||
super.createButtonsForButtonBar(parent);
|
||||
configName.setFocus();
|
||||
if (configName != null) {
|
||||
configName.setText(newName);
|
||||
}
|
||||
updateButtonState();
|
||||
validateState();
|
||||
}
|
||||
|
||||
protected Control createDialogArea(Composite parent) {
|
||||
|
@ -163,7 +172,7 @@ public class NewConfigurationDialog extends Dialog {
|
|||
configName.setLayoutData(gd);
|
||||
configName.addModifyListener(new ModifyListener() {
|
||||
public void modifyText(ModifyEvent e) {
|
||||
updateButtonState();
|
||||
validateState();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -201,7 +210,7 @@ public class NewConfigurationDialog extends Dialog {
|
|||
copyConfigSelector.setLayoutData(gd);
|
||||
copyConfigSelector.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
updateButtonState();
|
||||
validateState();
|
||||
}
|
||||
});
|
||||
copyConfigSelector.setEnabled(false);
|
||||
|
@ -225,7 +234,7 @@ public class NewConfigurationDialog extends Dialog {
|
|||
cloneConfigSelector.setLayoutData(gd);
|
||||
cloneConfigSelector.addSelectionListener(new SelectionAdapter() {
|
||||
public void widgetSelected(SelectionEvent e) {
|
||||
updateButtonState();
|
||||
validateState();
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -286,25 +295,40 @@ public class NewConfigurationDialog extends Dialog {
|
|||
*/
|
||||
protected boolean isDuplicateName(String newName) {
|
||||
// Return true if there is already a config of that name defined
|
||||
IConfiguration [] configs = managedProject.getConfigurations();
|
||||
for (int index = 0; index < configs.length; index++) {
|
||||
IConfiguration configuration = configs[index];
|
||||
for (int index = 0; index < definedConfigs.length; index++) {
|
||||
IConfiguration configuration = definedConfigs[index];
|
||||
if (configuration.getName().equals(newName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (reservedNames.contains(newName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* Enable the OK button if there is a valid name in the text widget
|
||||
* and there is a valid selection in the base configuration combo
|
||||
* Answers <code>true</code> if the name entered by the user differs
|
||||
* only in case from an existing name.
|
||||
*
|
||||
* @param newName
|
||||
* @return
|
||||
*/
|
||||
private void updateButtonState() {
|
||||
if (btnOk != null) {
|
||||
int selectionIndex = copyConfigSelector.getSelectionIndex();
|
||||
btnOk.setEnabled(validateName() && selectionIndex != -1);
|
||||
protected boolean isSimilarName(String newName) {
|
||||
// Return true if there is already a config of that name defined on the target
|
||||
for (int index = 0; index < definedConfigs.length; index++) {
|
||||
IConfiguration configuration = definedConfigs[index];
|
||||
if (configuration.getName().equalsIgnoreCase(newName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Iterator iter = reservedNames.listIterator();
|
||||
while (iter.hasNext()) {
|
||||
if (((IConfiguration)iter.next()).getName().equalsIgnoreCase(newName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -316,17 +340,61 @@ public class NewConfigurationDialog extends Dialog {
|
|||
copyConfigSelector.setEnabled(!clone);
|
||||
}
|
||||
|
||||
private boolean validateName() {
|
||||
String currentName = configName.getText().trim();
|
||||
int nameLength = currentName.length();
|
||||
// Make sure the name is not a duplicate
|
||||
if (isDuplicateName(currentName)) {
|
||||
MessageDialog.openError(getShell(),
|
||||
ManagedBuilderUIMessages.getResourceString(TITLE),
|
||||
ManagedBuilderUIMessages.getFormattedString(DUPLICATE, currentName)); //$NON-NLS-1$
|
||||
/* (non-Javadoc)
|
||||
* Checks the argument for leading whitespaces and invalid directory name characters.
|
||||
* @param name
|
||||
* @return <I>true</i> is the name is a valid directory name with no whitespaces
|
||||
*/
|
||||
private boolean validateName(String name) {
|
||||
// Iterate over the name checking for bad characters
|
||||
char[] chars = name.toCharArray();
|
||||
// No whitespaces at the start of a name
|
||||
if (Character.isWhitespace(chars[0])) {
|
||||
return false;
|
||||
}
|
||||
// TODO make sure there are no invalid chars in name
|
||||
return (nameLength > 0);
|
||||
for (int index = 0; index < chars.length; ++index) {
|
||||
// Config name must be a valid dir name too, so we ban "\ / : * ? " < >" in the names
|
||||
if (!Character.isLetterOrDigit(chars[index])) {
|
||||
switch (chars[index]) {
|
||||
case '/':
|
||||
case '\\':
|
||||
case ':':
|
||||
case '*':
|
||||
case '?':
|
||||
case '\"':
|
||||
case '<':
|
||||
case '>':
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* (non-Javadoc)
|
||||
* Update the status message and button state based on the input selected
|
||||
* by the user
|
||||
*
|
||||
*/
|
||||
private void validateState() {
|
||||
StatusInfo status= new StatusInfo();
|
||||
String currentName = configName.getText();
|
||||
int nameLength = currentName.length();
|
||||
// Make sure the name is not a duplicate
|
||||
if (nameLength == 0) {
|
||||
// Not an error
|
||||
status.setError(""); //$NON-NLS-1$
|
||||
} else if (isDuplicateName(currentName)) {
|
||||
status.setError(ManagedBuilderUIMessages.getFormattedString(DUPLICATE, currentName));
|
||||
} else if (isSimilarName(currentName)) {
|
||||
status.setError(ManagedBuilderUIMessages.getFormattedString(CASE, currentName));
|
||||
} else if (!validateName(currentName)) {
|
||||
// TODO Create a decent I18N string to describe this problem
|
||||
status.setError(ManagedBuilderUIMessages.getFormattedString(INVALID, currentName)); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
updateStatus(status);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue