| //------------------------------------------------------------------------------ |
| // Copyright (c) 2005, 2006 IBM Corporation 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: |
| // IBM Corporation - initial implementation |
| //------------------------------------------------------------------------------ |
| package org.eclipse.epf.library.ui.util; |
| |
| import java.io.File; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.command.CompoundCommand; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EAttribute; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EReference; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.InternalEObject; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.edit.command.RemoveCommand; |
| import org.eclipse.emf.edit.command.SetCommand; |
| import org.eclipse.epf.common.ui.util.MsgBox; |
| import org.eclipse.epf.common.utils.StrUtil; |
| import org.eclipse.epf.library.LibraryResources; |
| import org.eclipse.epf.library.LibraryService; |
| import org.eclipse.epf.library.LibraryServiceUtil; |
| import org.eclipse.epf.library.edit.LibraryEditResources; |
| import org.eclipse.epf.library.edit.command.IResourceAwareCommand; |
| import org.eclipse.epf.library.edit.command.NestedCommandExcecutor; |
| import org.eclipse.epf.library.edit.util.ExtensionManager; |
| import org.eclipse.epf.library.edit.util.IOppositeFeatureLoader; |
| import org.eclipse.epf.library.edit.util.Messenger; |
| import org.eclipse.epf.library.edit.util.TngUtil; |
| import org.eclipse.epf.library.edit.validation.IValidator; |
| import org.eclipse.epf.library.edit.validation.IValidatorFactory; |
| import org.eclipse.epf.library.ui.LibraryUIPlugin; |
| import org.eclipse.epf.library.util.ContentResourceScanner; |
| import org.eclipse.epf.library.util.LibraryUtil; |
| import org.eclipse.epf.library.util.ResourceHelper; |
| import org.eclipse.epf.persistence.util.PersistenceUtil; |
| import org.eclipse.epf.services.ILibraryPersister; |
| import org.eclipse.epf.services.Services; |
| import org.eclipse.epf.uma.Activity; |
| import org.eclipse.epf.uma.BreakdownElementDescription; |
| import org.eclipse.epf.uma.ContentDescription; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.NamedElement; |
| import org.eclipse.epf.uma.UmaFactory; |
| import org.eclipse.epf.uma.UmaPackage; |
| import org.eclipse.epf.uma.util.AssociationHelper; |
| import org.eclipse.epf.uma.util.ContentDescriptionFactory; |
| import org.eclipse.epf.uma.util.UmaUtil; |
| import org.eclipse.jface.dialogs.IInputValidator; |
| import org.eclipse.jface.dialogs.InputDialog; |
| import org.eclipse.jface.window.Window; |
| import org.eclipse.osgi.util.NLS; |
| |
| /** |
| * @author Phong Nguyen Le |
| * @since 1.0 |
| */ |
| public class TypeConverter { |
| private static final Comparator activityFeatureComparator = new Comparator() { |
| |
| public int compare(Object arg0, Object arg1) { |
| if(arg0 == UmaPackage.Literals.BREAKDOWN_ELEMENT__SUPER_ACTIVITIES) { |
| return -1; |
| } |
| return 0; |
| } |
| |
| }; |
| |
| /** |
| * Converts the specified object to a object of new type specified by <code>newType</code> while still |
| * preserving as many attributes and relationships as possible |
| * |
| * @param object |
| * @param newType |
| * @param oldFeatureToNewFeatureMap map of feature of <code>object</code> to feature of <code>newType</code> |
| * @return new object of type <code>newType</code> |
| */ |
| public static final EObject convert(EObject object, EClass newType, |
| Map oldFeatureToNewFeatureMap, Comparator featureComparator, Set modifiedResources) |
| { |
| TypeConversionCommand cmd = createTypeConversionCommand(object, newType, oldFeatureToNewFeatureMap, featureComparator); |
| Collection<Resource> resources = cmd.getModifiedResources(); |
| if(!resources.isEmpty()) { |
| Resource[] resourceArray = new Resource[resources.size()]; |
| resources.toArray(resourceArray); |
| IStatus status = Services.getAccessController().checkModify(resourceArray, ExtensionManager.getDefaultUserInteractionHandler().getUIContext()); |
| if(!status.isOK()) { |
| Messenger.INSTANCE.showError(LibraryResources.convertActivityError_title, null, status); |
| return null; |
| } |
| } |
| try { |
| cmd.execute(); |
| modifiedResources.addAll(cmd.getModifiedResources()); |
| return (EObject) cmd.getResult().iterator().next(); |
| } |
| finally { |
| cmd.dispose(); |
| } |
| } |
| |
| private static class ResourceCopyTask { |
| ContentResourceScanner scanner; |
| MethodElement owner; |
| String content; |
| String contentPath; |
| |
| /** |
| * @param scanner |
| * @param owner |
| * @param content |
| * @param contentPath |
| */ |
| public ResourceCopyTask(ContentResourceScanner scanner, MethodElement owner, String content, String contentPath) { |
| super(); |
| this.scanner = scanner; |
| this.owner = owner; |
| this.content = content; |
| this.contentPath = contentPath; |
| } |
| |
| } |
| |
| public static class TypeConversionCommand extends CompoundCommand implements IResourceAwareCommand { |
| |
| private Collection<?> result; |
| private EObject object; |
| private HashSet<Resource> modifiedResources; |
| private boolean gotModifiedResources; |
| private List<ResourceCopyTask> resourceCopyTasks; |
| private Resource resource; |
| private Collection illegalReferencers; |
| private NestedCommandExcecutor nestedCommandExcecutor; |
| |
| /** |
| * @param object |
| */ |
| public TypeConversionCommand(EObject object) { |
| this.object = object; |
| modifiedResources = new HashSet<Resource>(); |
| resource = object.eResource(); |
| if(resource != null) { |
| modifiedResources.add(resource); |
| } |
| resourceCopyTasks = new ArrayList<ResourceCopyTask>(); |
| nestedCommandExcecutor = new NestedCommandExcecutor(this); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.emf.common.command.CompoundCommand#dispose() |
| */ |
| public void dispose() { |
| if(illegalReferencers != null) { |
| illegalReferencers.clear(); |
| } |
| if(modifiedResources != null) { |
| modifiedResources.clear(); |
| } |
| if(resourceCopyTasks != null) { |
| resourceCopyTasks.clear(); |
| } |
| if(nestedCommandExcecutor != null) { |
| nestedCommandExcecutor.dispose(); |
| } |
| super.dispose(); |
| } |
| |
| /** |
| * Gets referencers that become illegal after the type conversion |
| * |
| * @return |
| */ |
| public Collection getIllegalReferencers() { |
| if(illegalReferencers == null) { |
| getModifiedResources(); |
| } |
| return illegalReferencers; |
| } |
| |
| public void copyResources() { |
| if(!resourceCopyTasks.isEmpty()) { |
| for (ResourceCopyTask t : resourceCopyTasks) { |
| File newResourcePath = new File(ResourceHelper.getAbsoluteElementResourcePath(t.owner)); |
| t.scanner.setTargetRootPath(newResourcePath); |
| if(t.content != null) { |
| t.scanner.resolveResources(t.owner, t.content, t.contentPath); |
| } |
| else { |
| for (EAttribute attribute : t.owner.eClass().getEAllAttributes()) { |
| Object value = t.owner.eGet(attribute); |
| if(value instanceof String) { |
| t.scanner.resolveResources(t.owner, (String) value, t.contentPath); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.epf.library.edit.command.IResourceAwareCommand#getModifiedResources() |
| */ |
| public Collection<Resource> getModifiedResources() { |
| if(!gotModifiedResources) { |
| illegalReferencers = new HashSet(); |
| for (Iterator iter = commandList.iterator(); iter.hasNext();) { |
| Command cmd = (Command) iter.next(); |
| if(cmd instanceof RemoveCommand) { |
| RemoveCommand removeCommand = (RemoveCommand) cmd; |
| EObject owner = removeCommand.getOwner(); |
| Resource ownerResource = owner.eResource(); |
| if(ownerResource != null && ownerResource != resource) { |
| modifiedResources.add(ownerResource); |
| } |
| if(ownerResource != null && owner != object && !UmaUtil.isContainedBy(owner, object)) { |
| illegalReferencers.add(owner); |
| } |
| } |
| else if(cmd instanceof SetCommand) { |
| SetCommand setCommand = (SetCommand) cmd; |
| EObject owner = setCommand.getOwner(); |
| Resource ownerResource = owner.eResource(); |
| if(ownerResource != null && ownerResource != resource && setCommand.getValue() instanceof EObject) { |
| EObject value = (EObject) setCommand.getValue(); |
| if(value != object || !UmaUtil.isContainedBy(value, object)) { |
| modifiedResources.add(ownerResource); |
| } |
| } |
| if(ownerResource != null && owner != object && !UmaUtil.isContainedBy(owner, object) |
| && setCommand.getValue() == setCommand.getFeature().getDefaultValue()) { |
| illegalReferencers.add(owner); |
| } |
| } |
| } |
| |
| for (Object obj: illegalReferencers) { |
| if (obj instanceof MethodElement) { |
| Resource res = ((MethodElement) obj).eResource(); |
| if (res != null) { |
| modifiedResources.add(res); |
| } |
| } |
| } |
| |
| gotModifiedResources = true; |
| } |
| modifiedResources.addAll(nestedCommandExcecutor.getModifiedResources()); |
| return modifiedResources; |
| } |
| |
| private void setResult(Collection<?> result) { |
| this.result = result; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.emf.common.command.CompoundCommand#getResult() |
| */ |
| public Collection<?> getResult() { |
| return result; |
| } |
| |
| @Override |
| public void execute() { |
| super.execute(); |
| nestedCommandExcecutor.executeNestedCommands(); |
| } |
| |
| @Override |
| public void undo() { |
| nestedCommandExcecutor.undoNestedCommands(); |
| super.undo(); |
| } |
| |
| private List<Command> commandList() { |
| return commandList; |
| } |
| } |
| |
| /** |
| * |
| * @param object EObject |
| * @param newType EClass |
| * @param oldFeatureToNewFeatureMap Map |
| * @param featureComparator Comparator |
| * @return TypeConversionCommand |
| */ |
| public static final TypeConversionCommand createTypeConversionCommand(EObject object, EClass newType, |
| Map oldFeatureToNewFeatureMap, Comparator featureComparator) { |
| return createTypeConversionCommand(object, newType, oldFeatureToNewFeatureMap, featureComparator, false, false); |
| } |
| |
| /** |
| * |
| * @param object EObject |
| * @param newType EClass |
| * @param oldFeatureToNewFeatureMap Map |
| * @param featureComparator Comparator |
| * @param removeIncomingReferences boolean |
| * @param removeVariability boolean |
| * @return TypeConversionCommand |
| */ |
| public static final TypeConversionCommand createTypeConversionCommand(EObject object, EClass newType, |
| Map oldFeatureToNewFeatureMap, Comparator featureComparator, |
| boolean removeIncomingReferences, boolean removeVariability) { |
| TypeConversionCommand cmd = new TypeConversionCommand(object); |
| EObject newObject = prepareConvert(object, newType, oldFeatureToNewFeatureMap, featureComparator, removeIncomingReferences, removeVariability, cmd); |
| |
| // replace object with newObject in the object's container |
| // |
| EObject container = object.eContainer(); |
| if(container != null) { |
| EReference ref = object.eContainmentFeature(); |
| if(ref.isMany()) { |
| List list = (List) container.eGet(ref); |
| int index = list.indexOf(object); |
| cmd.commandList().add(0, new SetCommand(null, container, ref, newObject, index)); |
| } |
| else { |
| cmd.commandList().add(0, new SetCommand(null, container, ref, newObject)); |
| } |
| } |
| |
| cmd.setResult(Collections.singletonList(newObject)); |
| |
| return cmd; |
| } |
| |
| private static ContentResourceScanner createScanner(EObject object) { |
| if(object instanceof ContentDescription && !(object instanceof BreakdownElementDescription)) { |
| File oldResourcePath = new File(ResourceHelper.getFolderAbsolutePath((MethodElement) object)); |
| String rootContentpath = ResourceHelper.getElementPath((MethodElement)object); |
| ContentResourceScanner scanner = new ContentResourceScanner(oldResourcePath, null, rootContentpath, null); |
| return scanner; |
| } |
| return null; |
| } |
| |
| /** |
| * Prepares a compound command to do a type conversion |
| * |
| * @param object |
| * @param newType |
| * @param oldFeatureToNewFeatureMap |
| * @param featureComparator used to sort the feature list of object to convert before copying/moving |
| * feature values to new object. |
| * @param removeIncomingReferences if true will remove all incoming references |
| * @param compoundCommand |
| * @return EObject |
| */ |
| public static final EObject prepareConvert(EObject object, EClass newType, Map oldFeatureToNewFeatureMap, |
| Comparator featureComparator, boolean removeIncomingReferences, boolean removeVariability, |
| TypeConversionCommand compoundCommand) { |
| return prepareConvert(object, newType, oldFeatureToNewFeatureMap, |
| featureComparator, removeIncomingReferences, removeVariability, |
| compoundCommand, 0); |
| } |
| |
| private static final EObject prepareConvert(EObject object, EClass newType, Map oldFeatureToNewFeatureMap, |
| Comparator featureComparator, boolean removeIncomingReferences, boolean removeVariability, |
| TypeConversionCommand compoundCommand, int level) { |
| EObject newObject = UmaFactory.eINSTANCE.create(newType); |
| |
| if(object instanceof MethodElement) { |
| // Handle incoming references. |
| // If removeIncommingReferences is false, redirect all incoming references of object to newObject |
| // If removeIncommingReferences is true, remove all of them. |
| // |
| |
| MethodElement me = (MethodElement) object; |
| Collection oppositeFeatures = me.getOppositeFeatures(); |
| if(!oppositeFeatures.isEmpty()) { |
| |
| // load opposite features |
| // |
| Collection collection = Collections.singletonList(object); |
| for (Iterator iter = ExtensionManager.getOppositeFeatureLoaders().iterator(); iter |
| .hasNext();) { |
| IOppositeFeatureLoader loader = (IOppositeFeatureLoader) iter.next(); |
| loader.loadOppositeFeatures(collection); |
| } |
| |
| if (level == 0) { |
| LibraryUtil.loadAll(LibraryService.getInstance().getCurrentMethodLibrary()); |
| } |
| |
| Map referencerToFeatureListMap = AssociationHelper.getReferenceMap(me); |
| for (Iterator iter = referencerToFeatureListMap.entrySet().iterator(); iter |
| .hasNext();) { |
| Map.Entry entry = (Map.Entry) iter.next(); |
| EObject referencer = (EObject) entry.getKey(); |
| for (Iterator iterator = ((Collection)entry.getValue()).iterator(); iterator |
| .hasNext();) { |
| EReference feature = (EReference) iterator.next(); |
| if(!removeIncomingReferences && feature.getEType().isInstance(newObject)) { |
| // new type is compatible, reference can be preserved |
| // |
| if(feature.isMany()) { |
| List list = (List) referencer.eGet(feature); |
| int index = list.indexOf(object); |
| compoundCommand.append(new SetCommand(null, referencer, feature, newObject, index)); |
| } |
| else { |
| compoundCommand.append(new SetCommand(null, referencer, feature, newObject)); |
| } |
| } |
| else { |
| // new type is not compatible, reference must be removed |
| // |
| if(feature.isMany()) { |
| compoundCommand.append(new RemoveCommand(null, referencer, feature, object)); |
| } |
| else { |
| compoundCommand.append(new SetCommand(null, referencer, feature, feature.getDefaultValue())); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // copy all the features |
| // |
| List newObjectFeatures = newType.getEAllStructuralFeatures(); |
| List objectFeatures = new ArrayList(object.eClass().getEAllStructuralFeatures()); |
| if(removeVariability) { |
| objectFeatures.remove(UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_BASED_ON_ELEMENT); |
| objectFeatures.remove(UmaPackage.Literals.VARIABILITY_ELEMENT__VARIABILITY_TYPE); |
| } |
| if(featureComparator != null) { |
| Collections.sort(objectFeatures, featureComparator); |
| } |
| ContentResourceScanner scanner = createScanner(object); |
| for (Iterator iter = objectFeatures.iterator(); iter.hasNext();) { |
| EStructuralFeature feature = (EStructuralFeature) iter.next(); |
| if(!newObjectFeatures.contains(feature)) { |
| if(oldFeatureToNewFeatureMap != null) { |
| Object f = oldFeatureToNewFeatureMap.get(feature); |
| if(f != null && newObjectFeatures.contains(f)) { |
| feature = (EStructuralFeature) f; |
| } |
| else { |
| feature = null; |
| } |
| } |
| else { |
| feature = null; |
| } |
| } |
| if(feature != null && feature.isChangeable()) { |
| boolean featureHandled = false; |
| if(feature instanceof EReference) { |
| EReference ref = (EReference) feature; |
| if(ref == UmaPackage.Literals.DESCRIBABLE_ELEMENT__PRESENTATION) { |
| if(ContentDescriptionFactory.hasPresentation((MethodElement) object)) { |
| ContentDescription content = (ContentDescription) object.eGet(ref); |
| EClass contentDescType = ContentDescriptionFactory.getContentDescriptionType(newType); |
| if(contentDescType != null && contentDescType != content.eClass()) { |
| EObject newContent = prepareConvert(content, contentDescType, null, null, removeIncomingReferences, removeVariability, compoundCommand, level + 1); |
| |
| // remove old content |
| // |
| EObject container = content.eContainer(); |
| if(container != null) { |
| compoundCommand.append(new SetCommand(null, object, ref, null)); |
| Resource resource = content.eResource(); |
| if(resource != null) { |
| compoundCommand.modifiedResources.add(content.eResource()); |
| } |
| } |
| |
| content = (ContentDescription) newContent; |
| } |
| else { |
| compoundCommand.resourceCopyTasks.add(new ResourceCopyTask(createScanner(content), content, null, "")); //$NON-NLS-1$ |
| } |
| compoundCommand.append(new SetCommand(null, newObject, ref, content)); |
| } |
| featureHandled = true; |
| } |
| else if(!ref.isContainment() && ref.getEOpposite() != null) { |
| // Reference is bi-directional. If opposite reference is a list, replace object |
| // with new object at the same position in the list. |
| // |
| EReference oppositeRef = ref.getEOpposite(); |
| if(oppositeRef.isMany()) { |
| Object value = object.eGet(ref); |
| if(value != null) { |
| if(ref.isMany()) { |
| for (Iterator iterator = ((Collection)value) |
| .iterator(); iterator.hasNext();) { |
| EObject otherEnd = (EObject) iterator.next(); |
| List list = (List) otherEnd.eGet(oppositeRef); |
| int index = list.indexOf(object); |
| compoundCommand.append(new SetCommand(null, otherEnd, oppositeRef, newObject, index)); |
| } |
| } |
| else { |
| EObject otherEnd = (EObject) value; |
| List list = (List) otherEnd.eGet(oppositeRef); |
| int index = list.indexOf(object); |
| compoundCommand.append(new SetCommand(null, otherEnd, oppositeRef, newObject, index)); } |
| } |
| featureHandled = true; |
| } |
| } |
| } |
| if(!featureHandled) { |
| Object value = object.eGet(feature); |
| if (feature == UmaPackage.Literals.NAMED_ELEMENT__NAME) { |
| // validate name |
| String newName = checkName(object, newType); |
| if (newName != null) { |
| value = newName; |
| } |
| } |
| if(scanner != null && value instanceof String && object instanceof MethodElement) { |
| String str = (String) value; |
| if(!StrUtil.isBlank(str)) { |
| compoundCommand.resourceCopyTasks.add(new ResourceCopyTask(scanner, (MethodElement)object, str, "")); //$NON-NLS-1$ |
| } |
| } |
| compoundCommand.append(new SetCommand(null, newObject, feature, value)); |
| } |
| } |
| } |
| |
| return newObject; |
| } |
| |
| /** |
| * Converts an activity to new type. |
| * |
| * @param oldActivity Activity |
| * @param newType EClass |
| * @return Activity |
| */ |
| public static Activity convertActivity(Activity oldActivity, EClass newType) { |
| // activity is already this type |
| // |
| if (newType == oldActivity.eClass()) { |
| return null; |
| } |
| |
| HashSet<Resource> modifiedResources = new HashSet<Resource>(); |
| Activity newActivity = (Activity) TypeConverter.convert(oldActivity, newType, null, activityFeatureComparator, modifiedResources); |
| |
| // make oldActivity a proxy so reference to it can be resolved to newActivity |
| // |
| URI uri = PersistenceUtil.getProxyURI(newActivity); |
| ((InternalEObject)oldActivity).eSetProxyURI(uri); |
| |
| // save modified resources |
| // |
| if (!modifiedResources.isEmpty()) { |
| ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister(); |
| try { |
| for (Resource res : modifiedResources) { |
| persister.save(res); |
| } |
| persister.commit(); |
| |
| } catch (Exception e) { |
| LibraryUIPlugin |
| .getDefault() |
| .getMsgDialog() |
| .displayError( |
| LibraryResources.convertActivityError_title, |
| NLS |
| .bind( |
| LibraryResources.saveConvertedActivityError_msg, |
| newActivity.getName()), |
| LibraryResources.error_reason, e); |
| |
| persister.rollback(); |
| } |
| } |
| |
| return newActivity; |
| } |
| |
| /** |
| * |
| * @param typeID int |
| * @return EClass |
| */ |
| public static EClass getActivityType(int typeID) { |
| switch (typeID) { |
| case UmaPackage.ACTIVITY: |
| return UmaPackage.Literals.ACTIVITY; |
| case UmaPackage.ITERATION: |
| return UmaPackage.Literals.ITERATION; |
| case UmaPackage.PHASE: |
| return UmaPackage.Literals.PHASE; |
| default: |
| return null; |
| } |
| } |
| |
| |
| /** |
| * @param oldGuidance |
| * @param newGuidance |
| * @return |
| */ |
| private static String checkName(EObject object, EClass newType) { |
| // TODO Auto-generated method stub |
| if (object instanceof NamedElement) { |
| NamedElement e = (NamedElement)object; |
| final IValidator validator = IValidatorFactory.INSTANCE.createNameValidator(e.eContainer(), e, newType); |
| String msg = validator.isValid(e.getName()); |
| if(msg != null) { |
| String featureTxt = TngUtil.getFeatureText(UmaPackage.eINSTANCE |
| .getNamedElement_Name()); |
| String title = LibraryEditResources.resolveNameConflictDialog_title; |
| String dlgMsg = NLS.bind( |
| LibraryEditResources.resolveNameConflictDialog_text, |
| StrUtil.toLower(featureTxt), e.getName()); |
| String currentValue = (String) e.eGet(UmaPackage.eINSTANCE |
| .getNamedElement_Name()); |
| |
| IInputValidator inputValidator = new IInputValidator() { |
| public String isValid(String newText) { |
| return validator.isValid(newText); |
| } |
| }; |
| |
| InputDialog inputDlg = new InputDialog( |
| MsgBox.getDefaultShell(), title, dlgMsg, currentValue, |
| inputValidator); |
| if (inputDlg.open() == Window.CANCEL) { |
| throw new OperationCanceledException(); |
| } |
| return inputDlg.getValue(); |
| } |
| } |
| return null; |
| } |
| |
| } |