/*****************************************************************************
* Copyright (c) 2010 CEA LIST.
*
*
* 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:
* Vincent Lorenzo (CEA LIST) vincent.lorenzo@cea.fr - Initial API and implementation
*
*****************************************************************************/
package org.eclipse.papyrus.uml.diagram.common.ui.dialogs;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.jface.dialogs.IInputValidator;
import org.eclipse.papyrus.uml.diagram.common.Messages;
import org.eclipse.papyrus.uml.diagram.common.util.Util;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.uml2.common.util.UML2Util;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Enumeration;
import org.eclipse.uml2.uml.EnumerationLiteral;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Profile;
import org.eclipse.uml2.uml.Property;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.Type;
/**
* this class provides editor for different types of properties
*/
public class PropertyEditors {
/**
* Editor's Titles
*/
/** IntegerEditor Title */
public static final String IntegerEditor_Title = Messages.PropertyEditors_IntegerTitle;
/** UnlimitedNaturalEditor Title */
public static final String UnlimitedNaturalEditor_Title = Messages.PropertyEditors_UnlimitedNaturalTitle;
/** StringEditor Title */
public static final String StringEditor_Title = Messages.PropertyEditors_StringTitle;
/** BooleanEditor Title */
public static final String BooleanEditor_Title = Messages.PropertyEditors_BooleanTitle;
/** EnumerationEditor Title */
public static final String EnumerationLiteralEditor_Title = Messages.PropertyEditors_EnumerationLiteralTitle;
/** StereotypeEditor Title */
private static final String StereotypeEditor_Title = Messages.PropertyEditors_StereotypeTitle;
/** MetaclassEditor Title */
private static final String MetaclassEditor_Title = Messages.PropertyEditors_MetaclassTitle;
/** DataTypeEditor Title */
private static final String DataTypeEditor_Title = Messages.PropertyEditors_DataTypeTitle;
/*
* Messages for editors
*/
/** the "Value" String */
public static final String Value = Messages.PropertyEditors_Value;
/** the "Choice" String */
public static final String Choice = Messages.PropertyEditors_Choice;
/*
* warning messages
*/
/** warning message for the integer validator */
public static final String IntegerValidator_WarningMessage = Messages.PropertyEditors_IntegerWarning;
/** warning message for the unlimited natural validator */
public static final String UnlimitedNaturalValidator_WarningMessage = Messages.PropertyEditors_UnlimitedNaturalWarning;
/** warning message for metaclass editor */
public static final String MetaclassEditor_WarningMessage = Messages.PropertyEditors_NoFoundElementMetaclass;
/** warning message for stereotype editor */
public static final String StereotypeEditor_WarningMessage = Messages.PropertyEditors_NoFoundElementStereotype;
/** prefix for the uml elements */
public static final String UML_PREFIX = "org.eclipse.uml2.uml."; //$NON-NLS-1$
/** the UML elements who aren't NamedElement */
static String unNamedElements[] = new String[]{ "ActivityGroup", "Clause", "Comment", "ExceptionHandler", "Image", "LinkEndData", "MultiplicityElement", "ParameterableElement", "QualifierValue", "Relationship", "Slot", "TemplateableElement", "TemplateParameter", "TemplateParameterSubstitution", "TemplateableParameterSubsitution", }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$ //$NON-NLS-13$ //$NON-NLS-14$ //$NON-NLS-15$
// TODO : we doesn't know edit a property if the initial value is a property
// need implements this functionality is editors
/**
* Editor for the Type Integer.
*
* @param property
* : the property to edit
* @param oldValue
* : the property value to modify (can be null)
*
* @return String : null if nothing is written
*
*/
public static String IntegerEditor(Property property, Object oldValue) {
String value = null;
String initialValue = findInitialValue(property, oldValue);
InputDialogMessage dialog = new InputDialogMessage(new Shell(), IntegerEditor_Title, Value, initialValue, new IntegerValidator());
if(dialog.open() != InputDialogMessage.CANCEL) {
if(!"".equals(dialog.getValue())) { //$NON-NLS-1$
value = dialog.getValue();
}
} else {
value = oldValue.toString();
}
return value;
}
/**
*
* @param property
* (the property to edit)
* @param oldValue
* (can be null)
* @return the inital value for the property
*/
private static String findInitialValue(Property property, Object oldValue) {
String initialValue = null;
if(oldValue != null) {
initialValue = oldValue.toString();
} else if(property.isSetDefault()) {
initialValue = property.getDefault();
}
return initialValue;
}
/**
* Editor for the Type UnlimitedNatural.
*
* @param property
* : the property to edit
* @param oldValue
* : the property value to modify (can be null)
*
* @return String : null if nothing is written
*
*/
public static String UnlimitedNaturalEditor(Property property, Object oldValue) {
String value = null;
String initialValue = findInitialValue(property, oldValue);
InputDialogMessage dialog = new InputDialogMessage(new Shell(), UnlimitedNaturalEditor_Title, Value, initialValue, new UnlimitedNaturalValidator());
if(dialog.open() != InputDialogMessage.CANCEL) {
if(!"".equals(dialog.getValue())) { //$NON-NLS-1$
value = dialog.getValue();
}
} else {
if(value != null) {
value = oldValue.toString();
}
}
return value;
}
/**
* Editor for the Type String.
*
* @param property
* : the property to edit
* @param oldValue
* : the property value to modify (can be null)
*
* @return String : null if nothing written
*/
public static String StringEditor(Property property, Object oldValue) {
String value = null;
String initialValue = findInitialValue(property, oldValue);
InputDialogMessage dialog = new InputDialogMessage(new Shell(), StringEditor_Title, Value, initialValue, null);
if(dialog.open() != InputDialogMessage.CANCEL) {
value = new String(dialog.getValue());
if(value.equals("")) { //$NON-NLS-1$
value = null;
}
} else {
if(oldValue != null) {
return oldValue.toString();
}
}
return value;
}
/**
* Editor for the type DataType
*
* @param property
* : the property to edit
* @param oldValue
* : the property value to modify (can be null)
* @return
*/
public static String DataTypeEditor(Property property, Object oldValue) {
String value = null;
String initialValue = null;
if(oldValue != null) { // we are modifying an existing value
initialValue = oldValue.toString();
} else if(property.isSetDefault()) {
initialValue = property.getDefault();
}
InputDialogMessage dialog = new InputDialogMessage(new Shell(), DataTypeEditor_Title, Value, initialValue, null);
if(dialog.open() != InputDialogMessage.CANCEL) {
if(!"".equals(dialog.getValue())) { //$NON-NLS-1$
value = dialog.getValue();
}
} else {
if(oldValue != null) {
value = oldValue.toString();
}
}
return value;
}
/**
* Editor for the Type Boolean.
*
* @param property
* : the property to edit
* @param oldValue
* : the property value to modify (can be null)
*
* @return boolean : null if nothing is selected
*
*/
public static String BooleanEditor(Property property, Object oldValue) {
String[] listOfChoice;
String value = null;
if(property.getLower() > 0) {
listOfChoice = new String[]{ Boolean.FALSE.toString(), Boolean.TRUE.toString() };
} else {
listOfChoice = new String[]{ "", Boolean.FALSE.toString(), Boolean.TRUE.toString() }; //$NON-NLS-1$
}
String initialValue = findInitialValue(property, oldValue);
ComboInputDialog dialog = new ComboInputDialog(new Shell(), BooleanEditor_Title, Choice, initialValue, listOfChoice);
if(dialog.open() != ComboInputDialog.CANCEL) {
int selection = dialog.getIndexOfSelection();
if(listOfChoice[selection] != "") { //$NON-NLS-1$
value = listOfChoice[selection];
}
} else if(oldValue != null) {
value = oldValue.toString();
}
return value;
}
/**
* Editor for the Type EnumerationLiteral.
*
* @param property
* : the property to edit
* @param oldValue
* : the property value to modify (can be null)
*
* @return EnumerationLiteral : null if nothing is selected
*
*/
public static String EnumerationEditor(Property property, Object oldValue) {
EList<EnumerationLiteral> literals = ((Enumeration)property.getType()).getOwnedLiterals();
String initialValue = findInitialValue(property, oldValue);
String value = null;
String[] listOfChoice;
if(property.getLower() > 0) {
listOfChoice = new String[literals.size()];
for(int i = 0; i < listOfChoice.length; i++) {
listOfChoice[i] = literals.get(i).getName();
}
} else {
listOfChoice = new String[literals.size() + 1];
listOfChoice[0] = ""; //$NON-NLS-1$
for(int i = 1; i < listOfChoice.length; i++) {
listOfChoice[i] = literals.get(i - 1).getName();
}
}
ComboInputDialog dialog = new ComboInputDialog(new Shell(), EnumerationLiteralEditor_Title, Choice, initialValue, listOfChoice);
if(dialog.open() != ComboInputDialog.CANCEL) {
int selection = dialog.getIndexOfSelection();
if(listOfChoice[selection] != "") { //$NON-NLS-1$
value = listOfChoice[selection].toString();
}
} else if(oldValue != null) {
value = oldValue.toString();
}
return value;
}
/**
* Editor for the type Class, when the property is composite
*
* @param property
* @param oldValue
* @return
*/
public static String CompositeClassEditor(Property property, Object oldValue) {
// TODO
// we cannot do it!
return oldValue.toString();
}
/**
* Editor for the type DataType
*
* @param property
* @param oldValue
* @param appliedProfiles
* @return
*/
public static String StereotypeEditor(Property property, Object oldValue, List<Profile> appliedProfiles) {
Type type = property.getType();
String returnedValue = null;
ArrayList<Object> stereotypedElement = new ArrayList<Object>();
String initialValue = findInitialValue(property, oldValue);
String[] proposals = null;
if(type != null) {
/*
* we research all the elements stereotyped with type!
*/
for(Profile profile : appliedProfiles) {
stereotypedElement.addAll(Util.getInstancesFilteredByType(profile, null, (Stereotype)type));
}
if(property.getLower() > 0) {
proposals = new String[stereotypedElement.size()];
for(int i = 0; i < stereotypedElement.size(); i++) {
if((stereotypedElement.get(i)) instanceof NamedElement) {
proposals[i] = ((NamedElement)stereotypedElement.get(i)).getQualifiedName();
} else {
// TODO need a solution!
// String label =
// ((Element)stereotypedElement.get(i)).toString();
// proposals[i + 1] = label;
// //we don't obtain the ID from the XMI!
// UML2Util.getXMIIdentifier((InternalEObject)(((Element)stereotypedElement.get(i))));
}
}
} else {
proposals = new String[stereotypedElement.size() + 1];
proposals[0] = ""; //$NON-NLS-1$
for(int i = 1; i < proposals.length; i++) {
if((stereotypedElement.get(i - 1)) instanceof NamedElement) {
proposals[i] = ((NamedElement)stereotypedElement.get(i - 1)).getQualifiedName();
} else {
// TODO need a solution!
// String label =
// ((Element)stereotypedElement.get(i)).toString();
// proposals[i + 1] = label;
// //we don't obtain the ID from the XMI!
// UML2Util.getXMIIdentifier((InternalEObject)(((Element)stereotypedElement.get(i))));
}
}
}
ComboDialogWithMessage dialog = new ComboDialogWithMessage(new Shell(), StereotypeEditor_Title, Choice, initialValue, proposals, StereotypeEditor_WarningMessage);
if(dialog.open() != ComboInputDialog.CANCEL) {
int selection = dialog.getIndexOfSelection();
if(proposals[selection] != "") { //$NON-NLS-1$
returnedValue = dialog.getValue();
}
} else if(oldValue != null) {
returnedValue = oldValue.toString();
}
}
return returnedValue;
}
/**
* Editor for the type Metaclass
*
* @param property
* @param oldValue
* @param appliedProfiles
* @return
*/
public static String MetaclassEditor(Property property, Object oldValue, List<Profile> appliedProfiles) {
/*
* 1/ find the interesting elements 2/ check if they are problematic 3/
* create the proposals
*/
Type type = property.getType();
String returnedValue = null;
ArrayList<String> problematicMetaclasses = new ArrayList<String>(Arrays.asList(unNamedElements));
if(type != null && !problematicMetaclasses.contains(((org.eclipse.uml2.uml.Class)type).getName())) {
String[] proposals;
ArrayList<Object> metaclassElement = new ArrayList<Object>();
String initialValue = findInitialValue(property, oldValue);
/*
* we research all the representation of the metaclass
*/
String metaclassName = ((org.eclipse.uml2.uml.Class)type).getName();
// Try to retrieve type of the metaclass
java.lang.Class metaType = null;
try {
metaType = java.lang.Class.forName("org.eclipse.uml2.uml." + metaclassName); //$NON-NLS-1$
} catch (Exception e) {
e.printStackTrace();
}
for(Profile profile : appliedProfiles) {
metaclassElement.addAll(Util.getInstancesFilteredByType(profile, metaType, null));
}
/*
* we create the list of proposals
*/
if(property.getLower() == 0) {
proposals = new String[metaclassElement.size() + 1];
proposals[0] = ""; //$NON-NLS-1$
for(int i = 0; i < metaclassElement.size(); i++) {
if(metaclassElement.get(i) instanceof NamedElement) {
proposals[i + 1] = ((NamedElement)metaclassElement.get(i)).getQualifiedName();
} else {
// TODO need a solution!
String label = ((Element)metaclassElement.get(i)).toString();
proposals[i + 1] = label;
// we don't obtain the ID from the XMI!
UML2Util.getXMIIdentifier((InternalEObject)(((Element)metaclassElement.get(i))));
}
}
} else {
proposals = new String[metaclassElement.size()];
for(int i = 0; i < metaclassElement.size(); i++) {
if(metaclassElement.get(i) instanceof NamedElement) {
proposals[i] = ((NamedElement)metaclassElement.get(i)).getQualifiedName();
} else {
// TODO need a solution!
String label = ((Element)metaclassElement.get(i)).toString();
proposals[i] = label;
// We don't obtain the ID from the XMI
UML2Util.getXMIIdentifier((InternalEObject)(((Element)metaclassElement.get(i))));
}
}
}
/*
* the message dialog
*/
ComboDialogWithMessage dialog = new ComboDialogWithMessage(new Shell(), MetaclassEditor_Title, Choice, initialValue, proposals, MetaclassEditor_WarningMessage);
if(dialog.open() != ComboInputDialog.CANCEL) {
int selection = dialog.getIndexOfSelection();
if(proposals[selection] != "") { //$NON-NLS-1$
returnedValue = dialog.getValue();
}
} else if(oldValue != null) {
returnedValue = oldValue.toString();
}
}
return returnedValue;
}
/**
* Validator for the IntegerEditor
*/
public static class IntegerValidator implements IInputValidator {
/**
* @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String)
*
* @param newText
* @return null if the newText is valid an error message when newText is
* invalid
*/
public String isValid(String newText) {
if(newText != null && newText != "") { //$NON-NLS-1$
for(int iter = 0; iter < newText.length(); iter++) {
if(!Character.isDigit(newText.charAt(iter))) {
if(iter == 0) {
if((newText.charAt(iter) == '-')) { // the first
// character
// can be
// '-'
continue;
}
}
return IntegerValidator_WarningMessage;
}
}
}
return null;// it's OK
}
}
/**
* Validator for the UnlimitedNaturalEditor
*/
public static class UnlimitedNaturalValidator implements IInputValidator {
/**
* @see org.eclipse.jface.dialogs.IInputValidator#isValid(java.lang.String)
*
* @param newText
* @return null if the newText is valid an error message when newText is
* invalid
*/
public String isValid(String newText) {
if(newText != null && newText != "") { //$NON-NLS-1$
for(int iter = 0; iter < newText.length(); iter++) {
if(!Character.isDigit(newText.charAt(iter))) {
if(newText.length() == 1 && newText.charAt(0) == '*') { // '*'
// means
// the
// infinity
break;
}
return UnlimitedNaturalValidator_WarningMessage;
}
}
}
return null;// it's OK
}
}
}