| //------------------------------------------------------------------------------ |
| // 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.authoring.ui.editors; |
| |
| import java.io.File; |
| import java.io.PrintWriter; |
| import java.io.StringWriter; |
| import java.lang.reflect.InvocationTargetException; |
| import java.text.MessageFormat; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.EventObject; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.core.resources.IFile; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IResourceChangeEvent; |
| import org.eclipse.core.resources.IResourceChangeListener; |
| import org.eclipse.core.resources.IResourceDelta; |
| import org.eclipse.core.resources.IResourceDeltaVisitor; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IExtension; |
| import org.eclipse.core.runtime.IExtensionPoint; |
| import org.eclipse.core.runtime.IExtensionRegistry; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.emf.common.command.Command; |
| import org.eclipse.emf.common.command.CommandStack; |
| import org.eclipse.emf.common.command.CommandStackListener; |
| import org.eclipse.emf.common.notify.Adapter; |
| import org.eclipse.emf.common.notify.impl.AdapterImpl; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EObject; |
| import org.eclipse.emf.ecore.EStructuralFeature; |
| import org.eclipse.emf.ecore.resource.Resource; |
| import org.eclipse.emf.ecore.resource.ResourceSet; |
| import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain; |
| import org.eclipse.emf.edit.domain.EditingDomain; |
| import org.eclipse.emf.edit.domain.IEditingDomainProvider; |
| import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; |
| import org.eclipse.epf.authoring.ui.AuthoringPerspective; |
| import org.eclipse.epf.authoring.ui.AuthoringUIPlugin; |
| import org.eclipse.epf.authoring.ui.AuthoringUIResources; |
| import org.eclipse.epf.authoring.ui.actions.LibraryValidateAction; |
| import org.eclipse.epf.authoring.ui.forms.IRefreshable; |
| import org.eclipse.epf.authoring.ui.internal.MethodElementEditorErrorTickUpdater; |
| import org.eclipse.epf.authoring.ui.providers.IMethodElementEditorPageProviderExtension; |
| import org.eclipse.epf.authoring.ui.providers.MethodElementEditorDefaultPageProvider; |
| import org.eclipse.epf.authoring.ui.providers.MethodElementLabelDecorator; |
| import org.eclipse.epf.authoring.ui.richtext.IMethodRichText; |
| import org.eclipse.epf.authoring.ui.util.LibraryValidationMarkerHelper; |
| import org.eclipse.epf.authoring.ui.views.ElementHTMLViewer; |
| import org.eclipse.epf.authoring.ui.views.LibraryView; |
| import org.eclipse.epf.authoring.ui.views.ViewHelper; |
| import org.eclipse.epf.common.ui.util.PerspectiveUtil; |
| import org.eclipse.epf.common.utils.StrUtil; |
| import org.eclipse.epf.library.ILibraryManager; |
| 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.TngAdapterFactory; |
| import org.eclipse.epf.library.edit.command.ActionManager; |
| import org.eclipse.epf.library.edit.command.FullyRevertibleCommandStack; |
| import org.eclipse.epf.library.edit.command.IActionManager; |
| import org.eclipse.epf.library.edit.command.IResourceAwareCommand; |
| import org.eclipse.epf.library.edit.ui.UserInteractionHelper; |
| import org.eclipse.epf.library.edit.util.ExtensionManager; |
| import org.eclipse.epf.library.edit.util.TngUtil; |
| import org.eclipse.epf.library.persistence.ILibraryResource; |
| import org.eclipse.epf.library.persistence.ILibraryResourceSet; |
| import org.eclipse.epf.library.persistence.synch.ISynchronizationHelper; |
| import org.eclipse.epf.library.services.SafeUpdateController; |
| import org.eclipse.epf.library.util.ResourceUtil; |
| import org.eclipse.epf.library.xmi.XMILibraryUtil; |
| import org.eclipse.epf.persistence.FileManager; |
| import org.eclipse.epf.persistence.MultiFileXMIResourceImpl; |
| import org.eclipse.epf.persistence.refresh.RefreshJob; |
| import org.eclipse.epf.persistence.util.LibrarySchedulingRule; |
| import org.eclipse.epf.persistence.util.PersistenceUtil; |
| import org.eclipse.epf.richtext.IRichText; |
| import org.eclipse.epf.services.ILibraryPersister; |
| import org.eclipse.epf.services.Services; |
| import org.eclipse.epf.services.ILibraryPersister.FailSafeMethodLibraryPersister; |
| import org.eclipse.epf.uma.ContentPackage; |
| import org.eclipse.epf.uma.MethodElement; |
| import org.eclipse.epf.uma.MethodLibrary; |
| import org.eclipse.epf.uma.MethodPlugin; |
| import org.eclipse.epf.uma.UmaPackage; |
| import org.eclipse.epf.uma.util.UmaUtil; |
| import org.eclipse.jface.dialogs.ProgressMonitorDialog; |
| import org.eclipse.jface.operation.IRunnableWithProgress; |
| import org.eclipse.jface.viewers.ILabelProvider; |
| import org.eclipse.jface.viewers.ISelection; |
| import org.eclipse.jface.viewers.ISelectionChangedListener; |
| import org.eclipse.jface.viewers.StructuredSelection; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.browser.Browser; |
| import org.eclipse.swt.custom.BusyIndicator; |
| import org.eclipse.swt.events.ModifyEvent; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Display; |
| import org.eclipse.swt.widgets.Text; |
| import org.eclipse.ui.IEditorInput; |
| import org.eclipse.ui.IEditorPart; |
| import org.eclipse.ui.IEditorSite; |
| import org.eclipse.ui.IPartListener; |
| import org.eclipse.ui.IPartService; |
| import org.eclipse.ui.IViewPart; |
| import org.eclipse.ui.IWindowListener; |
| import org.eclipse.ui.IWorkbenchPart; |
| import org.eclipse.ui.IWorkbenchWindow; |
| import org.eclipse.ui.PartInitException; |
| import org.eclipse.ui.PlatformUI; |
| import org.eclipse.ui.forms.editor.IFormPage; |
| import org.eclipse.ui.ide.IGotoMarker; |
| import org.eclipse.ui.part.FileEditorInput; |
| import org.eclipse.ui.part.MultiPageEditorPart; |
| import org.eclipse.ui.part.MultiPageSelectionProvider; |
| import org.eclipse.ui.views.properties.PropertySheet; |
| |
| /** |
| * The Method Element editor. |
| * |
| * @author Shilpa Toraskar |
| * @author Kelvin Low |
| * @author Phong Nguyen Le |
| * @since 1.0 |
| */ |
| public class MethodElementEditor extends AbstractBaseFormEditor implements |
| IGotoMarker, IEditingDomainProvider { |
| |
| protected static class ResourceInfo { |
| long modificationStamp; |
| long loadStamp; |
| boolean overwrite; |
| boolean adjustLocation; |
| |
| private Resource resource; |
| |
| ResourceInfo(Resource resource) { |
| this.resource = resource; |
| refresh(); |
| } |
| |
| public void refresh() { |
| modificationStamp = ISynchronizationHelper.INSTANCE.getModificationStamp(resource); |
| if(resource instanceof ILibraryResource) { |
| loadStamp = ((ILibraryResource)resource).getLoadStamp(); |
| } |
| else { |
| loadStamp = IResource.NULL_STAMP; |
| } |
| } |
| } |
| |
| /** |
| * The editor ID. |
| */ |
| public static final String EDITOR_ID = MethodElementEditor.class.getName(); |
| |
| protected int preview_page_index = -1; |
| |
| protected ElementHTMLViewer previewer = null; |
| |
| protected MethodElement elementObj = null; |
| |
| protected AdapterFactoryEditingDomain editingDomain; |
| |
| // The rich text control or editor whose content was last modified before |
| // the Save or Save All button key is selected. |
| protected IMethodRichText modifiedRichText = null; |
| |
| protected Adapter nameChangedListener = new AdapterImpl() { |
| public void notifyChanged(org.eclipse.emf.common.notify.Notification msg) { |
| switch (msg.getFeatureID(MethodElement.class)) { |
| case UmaPackage.METHOD_ELEMENT__NAME: |
| nameChanged(); |
| break; |
| } |
| } |
| }; |
| |
| protected Collection<ISelectionChangedListener> selectionChangedListeners = new ArrayList<ISelectionChangedListener>(); |
| |
| protected ISelection currentSelection = StructuredSelection.EMPTY; |
| |
| protected ActionManager actionMgr; |
| |
| private boolean dirty; |
| |
| private FailSafeMethodLibraryPersister persister; |
| |
| private Collection<Object> widgetsToRestoreValue = new HashSet<Object>(); |
| |
| private long changeTime = -1; |
| |
| public Object widgetToCheck; |
| |
| private Object currentFeatureEditor; |
| |
| private EStructuralFeature currentEditedFeature; |
| |
| protected ArrayList<Resource> removedResources = new ArrayList<Resource>(); |
| |
| protected ArrayList<Resource> changedResources = new ArrayList<Resource>(); |
| |
| protected MethodElementEditorErrorTickUpdater fMethodElementEditorErrorTickUpdater = null; |
| |
| /** |
| * Extension name |
| */ |
| public static final String METHOD_PAGE_PROVIDERS_EXTENSION_NAME = "MethodElementEditorPageProviders"; //$NON-NLS-1$ |
| protected static List<IMethodElementEditorPageProviderExtension> allPageProviders; |
| protected static IMethodElementEditorPageProviderExtension defaultPageProvider; |
| |
| /** |
| * Listens for workspace changes. |
| */ |
| protected IResourceChangeListener resourceChangeListener = new IResourceChangeListener() { |
| public void resourceChanged(IResourceChangeEvent event) { |
| System.out |
| .println("MethodElementEditor.resourceChanged(): event = " + event); //$NON-NLS-1$ |
| |
| if (elementObj.eIsProxy()) { |
| return; |
| } |
| |
| IResourceDelta delta = event.getDelta(); |
| try { |
| class ResourceDeltaVisitor implements IResourceDeltaVisitor { |
| protected Map URIToUsedResourceMap = getURIToUsedResourceMap(); |
| |
| protected Collection<Resource> changedResources = new ArrayList<Resource>(); |
| |
| protected Collection<Resource> removedResources = new ArrayList<Resource>(); |
| |
| public boolean visit(IResourceDelta delta) { |
| if (delta.getFlags() != IResourceDelta.MARKERS |
| && delta.getResource().getType() == IResource.FILE) { |
| if ((delta.getKind() & (IResourceDelta.CHANGED | IResourceDelta.REMOVED)) != 0) { |
| Resource resource = (Resource) URIToUsedResourceMap |
| .get(URI.createFileURI(delta |
| .getResource().getLocation() |
| .toString())); |
| if (resource != null) { |
| if ((delta.getKind() & IResourceDelta.REMOVED) != 0) { |
| removedResources.add(resource); |
| } else { |
| changedResources.add(resource); |
| } |
| } |
| } |
| } |
| |
| return true; |
| } |
| |
| public Collection<Resource> getChangedResources() { |
| return changedResources; |
| } |
| |
| public Collection<Resource> getRemovedResources() { |
| return removedResources; |
| } |
| } |
| |
| ResourceDeltaVisitor visitor = new ResourceDeltaVisitor(); |
| delta.accept(visitor); |
| |
| removedResources.addAll(visitor.getRemovedResources()); |
| if (!visitor.getRemovedResources().isEmpty() && !isDirty()) { |
| getSite().getShell().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| MethodElementEditor.this.dispose(); |
| } |
| }); |
| } |
| |
| changedResources.addAll(visitor.getChangedResources()); |
| } catch (CoreException e) { |
| AuthoringUIPlugin.getDefault().getLogger().logError(e); |
| } |
| } |
| }; |
| |
| class ActivationListener implements IPartListener, IWindowListener { |
| |
| /** Cache of the active workbench part. */ |
| private IWorkbenchPart fActivePart; |
| |
| /** Indicates whether activation handling is currently be done. */ |
| private boolean fIsHandlingActivation = false; |
| |
| /** |
| * The part service. |
| * |
| * @since 3.1 |
| */ |
| private IPartService fPartService; |
| |
| /** |
| * Creates this activation listener. |
| * |
| * @param partService |
| * the part service on which to add the part listener |
| * @since 3.1 |
| */ |
| public ActivationListener(IPartService partService) { |
| fPartService = partService; |
| fPartService.addPartListener(this); |
| PlatformUI.getWorkbench().addWindowListener(this); |
| } |
| |
| /** |
| * Disposes this activation listener. |
| * |
| * @since 3.1 |
| */ |
| public void dispose() { |
| fPartService.removePartListener(this); |
| PlatformUI.getWorkbench().removeWindowListener(this); |
| fPartService = null; |
| } |
| |
| /* |
| * @see IPartListener#partActivated(org.eclipse.ui.IWorkbenchPart) |
| */ |
| public void partActivated(IWorkbenchPart part) { |
| fActivePart = part; |
| handleActivation(); |
| } |
| |
| /* |
| * @see IPartListener#partBroughtToTop(org.eclipse.ui.IWorkbenchPart) |
| */ |
| public void partBroughtToTop(IWorkbenchPart part) { |
| } |
| |
| /* |
| * @see IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart) |
| */ |
| public void partClosed(IWorkbenchPart part) { |
| } |
| |
| /* |
| * @see IPartListener#partDeactivated(org.eclipse.ui.IWorkbenchPart) |
| */ |
| public void partDeactivated(IWorkbenchPart part) { |
| fActivePart = null; |
| } |
| |
| /* |
| * @see IPartListener#partOpened(org.eclipse.ui.IWorkbenchPart) |
| */ |
| public void partOpened(IWorkbenchPart part) { |
| if (part == MethodElementEditor.this) { |
| if (!isInputValid()) { |
| AuthoringUIPlugin |
| .getDefault() |
| .getMsgDialog() |
| .displayInfo( |
| AuthoringUIResources.editors_MethodElementEditor_invalidEditorTitle, |
| AuthoringUIResources.editors_MethodElementEditor_invalidEditorMsg); |
| MethodElementEditor.this.close(false); |
| return; |
| } |
| Collection<Resource> usedResources = getUsedResources(); |
| if (ResourceUtil.hasOutOfSynch(usedResources)) { |
| handleFileChanged(usedResources); |
| return; |
| } |
| setResourceInfos(usedResources); |
| } |
| } |
| |
| /** |
| * Handles the activation triggering a element state check in the |
| * editor. |
| */ |
| private void handleActivation() { |
| if (fIsHandlingActivation || MethodElementEditor.this.disposed) |
| return; |
| |
| if (fActivePart == MethodElementEditor.this) { |
| fIsHandlingActivation = true; |
| try { |
| handleActivate(fActivePart); |
| } finally { |
| fIsHandlingActivation = false; |
| } |
| } |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowActivated(org.eclipse.ui.IWorkbenchWindow) |
| * @since 3.1 |
| */ |
| public void windowActivated(IWorkbenchWindow window) { |
| if (window == getEditorSite().getWorkbenchWindow()) { |
| /* |
| * Workaround for problem described in |
| * http://dev.eclipse.org/bugs/show_bug.cgi?id=11731 Will be |
| * removed when SWT has solved the problem. |
| */ |
| window.getShell().getDisplay().asyncExec(new Runnable() { |
| public void run() { |
| handleActivation(); |
| } |
| }); |
| } |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowDeactivated(org.eclipse.ui.IWorkbenchWindow) |
| * @since 3.1 |
| */ |
| public void windowDeactivated(IWorkbenchWindow window) { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowClosed(org.eclipse.ui.IWorkbenchWindow) |
| * @since 3.1 |
| */ |
| public void windowClosed(IWorkbenchWindow window) { |
| } |
| |
| /* |
| * @see org.eclipse.ui.IWindowListener#windowOpened(org.eclipse.ui.IWorkbenchWindow) |
| * @since 3.1 |
| */ |
| public void windowOpened(IWorkbenchWindow window) { |
| } |
| } |
| |
| private ActivationListener activationListener; |
| |
| private boolean checkFileChangedRequired = false; |
| |
| protected HashSet<Resource> lastUsedResources; |
| |
| private boolean disposed; |
| |
| protected HashMap<Resource, ResourceInfo> resourceInfoMap; |
| |
| private IFile elementFile; |
| |
| /** |
| * Creates a new instance. |
| */ |
| public MethodElementEditor() { |
| super(); |
| |
| // moved the details out so that user can override the tick updator |
| // Jinhua Xi 3/15/2007 |
| createEditorErrorTickUpdater(); |
| createActionManager(); |
| } |
| |
| protected void createEditorErrorTickUpdater() { |
| |
| this.fMethodElementEditorErrorTickUpdater = new MethodElementEditorErrorTickUpdater(this); |
| } |
| |
| protected void createActionManager() { |
| actionMgr = new ActionManager() { |
| |
| protected FullyRevertibleCommandStack createCommandStack() { |
| return new FullyRevertibleCommandStack(this) { |
| public boolean doExecute(Command command) { |
| // Check modify first. |
| if (command instanceof IResourceAwareCommand) { |
| Collection modifiedResources = ((IResourceAwareCommand) command) |
| .getModifiedResources(); |
| if (modifiedResources != null |
| && !(modifiedResources.isEmpty())) { |
| IStatus status = UserInteractionHelper |
| .checkModify(modifiedResources, |
| getSite().getShell()); |
| if (!status.isOK()) { |
| MethodElementEditor.this |
| .handleError(status); |
| return false; |
| } |
| } |
| } else { |
| EObject owner = TngUtil.getOwner(command); |
| if (owner != null) { |
| IStatus status = TngUtil.checkEdit(owner, |
| getSite().getShell()); |
| if (!status.isOK()) { |
| AuthoringUIPlugin |
| .getDefault() |
| .getMsgDialog() |
| .display( |
| AuthoringUIResources.errorDialog_title, |
| AuthoringUIResources.editDialog_msgCannotEdit, |
| status); |
| return false; |
| } |
| } |
| } |
| |
| if (changeTime == -1) { |
| changeTime = System.currentTimeMillis(); |
| } |
| boolean ret = super.doExecute(command); |
| if (!ret && changeTime != -1) { |
| changeTime = -1; |
| } |
| return ret; |
| } |
| |
| }; |
| } |
| |
| public boolean doAction(int actionType, EObject object, |
| org.eclipse.emf.ecore.EStructuralFeature feature, |
| Object value, int index) { |
| final IStatus status = TngUtil |
| .checkEdit(object, getSite().getShell()); |
| if (status.isOK()) { |
| return super.doAction(actionType, object, feature, value, |
| index); |
| } else { |
| // this might be called from a non-UI thread |
| // so make sure the message dialog will be shown in a UI thread |
| // |
| SafeUpdateController.syncExec(new Runnable() { |
| |
| public void run() { |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| AuthoringUIResources.editDialog_title, |
| AuthoringUIResources.editDialog_msgCannotEdit, |
| status); |
| } |
| |
| }); |
| return false; |
| } |
| } |
| |
| protected void save(Resource resource) { |
| // don't save resource that is changed outside of this editor |
| // |
| if (changedResources.contains(resource)) { |
| return; |
| } |
| |
| boolean canSave; |
| if(resource.getURI().isFile()) { |
| File file = new File(resource.getURI().toFileString()); |
| canSave = file.lastModified() > changeTime; |
| } |
| else { |
| canSave = true; |
| } |
| try { |
| if(canSave) { |
| ILibraryPersister.FailSafeMethodLibraryPersister persister = getPersister(); |
| try { |
| persister.save(resource); |
| persister.commit(); |
| } catch (Exception e) { |
| AuthoringUIPlugin.getDefault().getLogger() |
| .logError(e); |
| try { |
| persister.rollback(); |
| } catch (Exception ex) { |
| ViewHelper |
| .reloadCurrentLibaryOnRollbackError(getEditorSite() |
| .getShell()); |
| } |
| } |
| } |
| } finally { |
| changeTime = -1; |
| } |
| } |
| }; |
| |
| actionMgr.getCommandStack().addCommandStackListener( |
| new CommandStackListener() { |
| public void commandStackChanged(EventObject event) { |
| Display.getDefault().asyncExec(new Runnable() { |
| public void run() { |
| firePropertyChange(IEditorPart.PROP_DIRTY); |
| } |
| }); |
| } |
| }); |
| |
| ILibraryManager manager = (ILibraryManager) LibraryService |
| .getInstance().getCurrentLibraryManager(); |
| if (manager != null) { |
| manager.startListeningTo(actionMgr.getCommandStack()); |
| } |
| } |
| |
| private void nameChanged() { |
| SafeUpdateController.asyncExec(new Runnable() { |
| |
| public void run() { |
| setPartName(); |
| if (pages != null) { |
| for (Iterator iter = pages.iterator(); iter.hasNext();) { |
| Object page = iter.next(); |
| |
| if (page instanceof IRefreshable) { |
| ((IRefreshable) page).refreshName(elementObj |
| .getName()); |
| } |
| } |
| } |
| } |
| |
| }); |
| } |
| |
| public IActionManager getActionManager() { |
| return actionMgr; |
| } |
| |
| /** |
| * @see org.eclipse.ui.forms.editor.FormEditor#init(IEditorSite, |
| * IEditorInput) |
| */ |
| public void init(IEditorSite site, IEditorInput input) |
| throws PartInitException { |
| setSite(site); |
| if (input instanceof FileEditorInput) { |
| // probably opened from Problems View |
| // create a MethodElementEditorInput |
| elementFile = ((FileEditorInput)input).getFile(); |
| MethodElement element = PersistenceUtil.getMethodElement( |
| elementFile, |
| LibraryService.getInstance().getCurrentLibraryManager(). |
| getEditingDomain().getResourceSet()); |
| if (element != null) { |
| input = new MethodElementEditorInput( |
| element); |
| } |
| } |
| setInput(input); |
| site.setSelectionProvider(new MultiPageSelectionProvider(this)); |
| activationListener = new ActivationListener(site.getWorkbenchWindow() |
| .getPartService()); |
| |
| ILabelProvider labelProvider = new AdapterFactoryLabelProvider( |
| TngAdapterFactory.INSTANCE |
| .getNavigatorView_ComposedAdapterFactory()); |
| Image titleImage = labelProvider.getImage(elementObj); |
| labelProvider.dispose(); |
| setTitleImage(titleImage); |
| |
| CommandStack commandStack = actionMgr.getCommandStack(); |
| editingDomain = new AdapterFactoryEditingDomain(TngAdapterFactory.INSTANCE |
| .getNavigatorView_ComposedAdapterFactory(), commandStack); |
| |
| } |
| |
| /** |
| * |
| * @see org.eclipse.ui.part.EditorPart#setInput(org.eclipse.ui.IEditorInput) |
| */ |
| protected void setInput(IEditorInput input) { |
| super.setInput(input); |
| |
| // Get method element object from Editor input. |
| // |
| MethodElementEditorInput methodElementInput = (MethodElementEditorInput) input; |
| elementObj = methodElementInput.getMethodElement(); |
| |
| setPartName(); |
| elementObj.eAdapters().add(nameChangedListener); |
| |
| if (fMethodElementEditorErrorTickUpdater != null) |
| fMethodElementEditorErrorTickUpdater.updateEditorImage(elementObj); |
| |
| } |
| |
| public MethodElement getMethodElement() |
| { |
| return elementObj; |
| } |
| |
| public void updateResourceInfos(Collection<Resource> resources) { |
| if(resourceInfoMap == null) { |
| resourceInfoMap = new HashMap<Resource, ResourceInfo>(); |
| } |
| for (Iterator iter = resources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| ResourceInfo info = resourceInfoMap.get(resource); |
| if(info == null) { |
| info = new ResourceInfo(resource); |
| resourceInfoMap.put(resource, info); |
| } |
| else { |
| info.refresh(); |
| } |
| } |
| checkFileChangedRequired = true; |
| } |
| |
| public void ovewriteResources(Collection<Resource> resources) { |
| for (Iterator iter = resources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| ResourceInfo info = resourceInfoMap.get(resource); |
| if(info != null) { |
| info.overwrite = true; |
| } |
| } |
| } |
| |
| public void setResourceInfos(Collection<Resource> resources) { |
| if(resourceInfoMap != null && !resourceInfoMap.isEmpty()) { |
| resourceInfoMap.clear(); |
| } |
| updateResourceInfos(resources); |
| } |
| |
| private long getLoadStamp(Resource resource) { |
| ResourceInfo info = resourceInfoMap.get(resource); |
| return info != null ? info.loadStamp : IResource.NULL_STAMP; |
| } |
| |
| /** |
| * Checks if there is any resource in the given <code>usedResources</code> |
| * that has been reloaded since last update of load time stamps by this |
| * editor |
| * |
| * @param usedResource |
| * @return |
| */ |
| private boolean checkReloaded(Collection usedResources) { |
| ResourceSet resourceSet = getResourceSet(usedResources); |
| boolean xmi = resourceSet instanceof ILibraryResourceSet |
| && ((ILibraryResourceSet)resourceSet).getPersistenceType().equals(Services.XMI_PERSISTENCE_TYPE); |
| for (Iterator iter = usedResources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| if(resource instanceof ILibraryResource) { |
| long oldStamp = getLoadStamp(resource); |
| long currentStamp = ((ILibraryResource)resource).getLoadStamp(); |
| if (oldStamp != currentStamp) { |
| if(xmi) { |
| IResource wsRes = FileManager.getResourceForLocation(resource |
| .getURI().toFileString()); |
| if (wsRes != null) { |
| return true; |
| } |
| } |
| else { |
| return true; |
| } |
| } |
| } |
| } |
| return false; |
| } |
| |
| private static ResourceSet getResourceSet(Collection resources) { |
| ResourceSet resourceSet = null; |
| for (Iterator iter = resources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| resourceSet = resource.getResourceSet(); |
| if (resourceSet != null) { |
| break; |
| } |
| } |
| return resourceSet; |
| } |
| |
| private Collection<Resource> getOutOfSyncResources(Collection<Resource> usedResources) { |
| Collection<Resource> outOfSyncResources = new ArrayList<Resource>(); |
| for (Resource resource : usedResources) { |
| if(isOutOfSync(resource)) { |
| outOfSyncResources.add(resource); |
| } |
| } |
| return outOfSyncResources; |
| } |
| |
| |
| private boolean isOutOfSync(Resource resource) { |
| ResourceInfo info = resourceInfoMap.get(resource); |
| long stamp = ISynchronizationHelper.INSTANCE.getModificationStamp(resource); |
| if(stamp != IResource.NULL_STAMP) { |
| if(info == null || info.modificationStamp != stamp) { |
| if(ISynchronizationHelper.INSTANCE.isSynchronized(resource)) { |
| // refresh the cached stamp |
| // |
| if(info == null) { |
| resourceInfoMap.put(resource, new ResourceInfo(resource)); |
| } |
| else { |
| info.modificationStamp = ISynchronizationHelper.INSTANCE.getModificationStamp(resource); |
| } |
| return false; |
| } |
| return true; |
| } |
| else { |
| return false; |
| } |
| } |
| else { |
| return !ISynchronizationHelper.INSTANCE.isSynchronized(resource); |
| } |
| } |
| |
| private boolean checkFileChanged(Collection usedResources) { |
| // check resource set type and continue to check for changed file if the |
| // type is XMI |
| // |
| ResourceSet resourceSet = getResourceSet(usedResources); |
| if (resourceSet instanceof ILibraryResourceSet |
| && ((ILibraryResourceSet) resourceSet).getPersistenceType().equals(Services.XMI_PERSISTENCE_TYPE)) { |
| for (Iterator iter = usedResources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| if(isOutOfSync(resource)) { |
| return true; |
| } |
| } |
| } |
| return false; |
| } |
| |
| protected boolean promptReloadFiles() { |
| String title = AuthoringUIResources.editor_error_activated_outofsync_title; |
| String msg = AuthoringUIResources.editor_error_activated_outofsync_message; |
| return AuthoringUIPlugin.getDefault().getMsgDialog().displayPrompt( |
| title, msg); |
| } |
| |
| private boolean handleFileChanged(final Collection<Resource> usedResources) { |
| boolean ret = promptReloadFiles(); |
| if (ret) { |
| IRunnableWithProgress runnable = new IRunnableWithProgress() { |
| |
| public void run(IProgressMonitor monitor) |
| throws InvocationTargetException, InterruptedException { |
| monitor.beginTask("", 10); //$NON-NLS-1$ |
| monitor.subTask(AuthoringUIResources.refresh_text); |
| monitor.worked(1); |
| try { |
| |
| Collection<Resource> removedResources = new ArrayList<Resource>(); |
| for (Resource resource : usedResources) { |
| if (!new File(resource.getURI().toFileString()) |
| .exists()) { |
| removedResources.add(resource); |
| } |
| } |
| Collection<Resource> changedResources = resourceInfoMap != null ? |
| getOutOfSyncResources(usedResources) : |
| ResourceUtil.getOutOfSyncResources(usedResources); |
| monitor.worked(2); |
| |
| // unload the removed resources |
| // |
| PersistenceUtil.unload(removedResources); |
| monitor.worked(2); |
| |
| // Reload the changed resources. |
| ILibraryManager manager = (ILibraryManager) LibraryService |
| .getInstance().getCurrentLibraryManager(); |
| if (manager != null) { |
| Collection<Resource> reloadedResources = manager |
| .reloadResources(changedResources); |
| if (!reloadedResources.isEmpty()) { |
| RefreshJob.getInstance() |
| .getReloadedBeforeRefreshResources() |
| .addAll(reloadedResources); |
| } |
| |
| if (!removedResources.isEmpty() |
| || !reloadedResources.isEmpty()) { |
| // save changed resources before refresh so |
| // action |
| // manager will not try to save these changed |
| // resources |
| // |
| MethodElementEditor.this.changedResources |
| .addAll(reloadedResources); |
| MethodElementEditor.this.lastUsedResources |
| .removeAll(removedResources); |
| refresh(true); |
| MethodElementEditor.this.changedResources |
| .clear(); |
| } |
| } |
| monitor.worked(4); |
| |
| // refresh out-of-synch resources |
| // |
| for (Resource resource : changedResources) { |
| FileManager.getInstance().refresh(resource); |
| } |
| monitor.worked(1); |
| } finally { |
| monitor.done(); |
| } |
| } |
| |
| }; |
| |
| try { |
| getSite() |
| .getWorkbenchWindow() |
| .getWorkbench() |
| .getProgressService() |
| .runInUI( |
| new ProgressMonitorDialog(getSite().getShell()), |
| runnable, new LibrarySchedulingRule(LibraryService.getInstance().getCurrentMethodLibrary())); |
| } catch (Exception e) { |
| AuthoringUIPlugin.getDefault().getLogger().logError(e); |
| String title = AuthoringUIResources.ProcessEditor_refreshErrorTitle; |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| title, e.toString(), e); |
| } |
| } else { |
| checkFileChangedRequired = false; |
| } |
| return ret; |
| } |
| |
| public void setPartName() { |
| String partName = elementObj.getName(); |
| if (partName == null) { |
| partName = ""; //$NON-NLS-1$ |
| } |
| setPartName(partName); |
| } |
| |
| protected static List<IMethodElementEditorPageProviderExtension> getAllPageProviders() { |
| if (allPageProviders == null) { |
| allPageProviders = ExtensionManager.getExtensions(AuthoringUIPlugin.getDefault().getId(), METHOD_PAGE_PROVIDERS_EXTENSION_NAME, IMethodElementEditorPageProviderExtension.class); |
| } |
| return allPageProviders; |
| } |
| |
| |
| protected IMethodElementEditorPageProviderExtension getDefaultPageProvider() { |
| if (defaultPageProvider == null) { |
| defaultPageProvider = new MethodElementEditorDefaultPageProvider(); |
| } |
| return defaultPageProvider; |
| } |
| |
| /** |
| * @see org.eclipse.ui.forms.editor.FormEditor#addPages() |
| */ |
| protected void addPages() { |
| // first get original list |
| Map<Object,String> pageMap = getDefaultPageProvider().getPages(new LinkedHashMap<Object,String>(), this, elementObj); |
| |
| // let extensions modify |
| List<IMethodElementEditorPageProviderExtension> pageProviders = getAllPageProviders(); |
| if (pageProviders != null && pageProviders.size() > 0) { |
| for (IMethodElementEditorPageProviderExtension extension : pageProviders) { |
| pageMap = extension.getPages(pageMap, this, elementObj); |
| } |
| } |
| // now add pages |
| try { |
| for (Map.Entry<Object, String> pageEntry : pageMap.entrySet()) { |
| Object page = pageEntry.getKey(); |
| String name = pageEntry.getValue(); |
| int index = -1; |
| if (page instanceof Control) { |
| index = addPage((Control)page); |
| } else if (page instanceof IFormPage) { |
| index = addPage((IFormPage)page); |
| } else if (page instanceof IEditorPart) { |
| index = addPage((IEditorPart)page, getEditorInput()); |
| } |
| if (name != null) { |
| setPageText(index, name); |
| } |
| } |
| |
| setPartName(elementObj.getName()); |
| |
| if (!(elementObj instanceof ContentPackage || elementObj instanceof MethodPlugin)) |
| createPreviewPage(); |
| |
| |
| } catch (Throwable t) { |
| AuthoringUIPlugin.getDefault().getLogger().logError(t); |
| dispose(); |
| if(t instanceof RuntimeException) { |
| throw (RuntimeException)t; |
| } |
| if(t instanceof Error) { |
| throw (Error) t; |
| } |
| } |
| } |
| |
| /** |
| * @see org.eclipse.epf.authoring.ui.editors.AbstractBaseFormEditor#dispose() |
| */ |
| public void dispose() { |
| try { |
| // ResourcesPlugin.getWorkspace().removeResourceChangeListener( |
| // resourceChangeListener); |
| |
| if (activationListener != null) { |
| activationListener.dispose(); |
| } |
| |
| modifiedRichText = null; |
| |
| disposeEditorErrorTickUpdater(); |
| |
| ILibraryManager manager = (ILibraryManager) LibraryService |
| .getInstance().getCurrentLibraryManager(); |
| if (manager != null) { |
| manager.stopListeningTo(actionMgr.getCommandStack()); |
| } |
| |
| if (isDirty()) { |
| actionMgr.undoAll(); |
| } |
| actionMgr.dispose(); |
| elementObj.eAdapters().remove(nameChangedListener); |
| |
| if(resourceInfoMap != null) { |
| resourceInfoMap.clear(); |
| resourceInfoMap = null; |
| } |
| |
| if(changedResources != null) { |
| changedResources.clear(); |
| changedResources = null; |
| } |
| |
| if(selectionChangedListeners != null) { |
| selectionChangedListeners.clear(); |
| selectionChangedListeners = null; |
| } |
| |
| if(PerspectiveUtil.isActivePerspective(AuthoringPerspective.PERSPECTIVE_ID)) { |
| // unload all resources of content description that are not used by |
| } |
| |
| if(lastUsedResources != null) { |
| lastUsedResources.clear(); |
| lastUsedResources = null; |
| } |
| } finally { |
| super.dispose(); |
| disposed = true; |
| } |
| } |
| |
| protected void disposeEditorErrorTickUpdater() |
| { |
| if ( fMethodElementEditorErrorTickUpdater != null ) { |
| fMethodElementEditorErrorTickUpdater.dispose(); |
| fMethodElementEditorErrorTickUpdater = null; |
| } |
| } |
| |
| |
| /** |
| * @see org.eclipse.epf.authoring.ui.editors.AbstractBaseFormEditor#isDirty() |
| */ |
| public boolean isDirty() { |
| if (dirty) |
| return true; |
| dirty = actionMgr.isSaveNeeded(); |
| return dirty; |
| } |
| |
| public FailSafeMethodLibraryPersister getPersister() { |
| if (persister == null) { |
| persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister(); |
| } |
| return persister; |
| } |
| |
| protected Collection<Resource> getModifiedResources() { |
| return actionMgr.getModifiedResources(); |
| } |
| |
| /** |
| * Set modified rich text field |
| * @param modifiedRichText |
| */ |
| public void setModifiedRichText(IMethodRichText modifiedRichText) { |
| this.modifiedRichText = modifiedRichText; |
| } |
| |
| /** |
| * Save modified rich text |
| * @param richText |
| */ |
| public void saveModifiedRichText(IMethodRichText richText) { |
| if (richText != null && !richText.isDisposed() |
| && richText.getModified()) { |
| EObject modalObject = richText.getModalObject(); |
| EStructuralFeature modalObjectFeature = richText |
| .getModalObjectFeature(); |
| if (modalObject != null && modalObjectFeature != null) { |
| Object oldContent = modalObject.eGet(modalObjectFeature); |
| if (!mustRestoreValue(richText, oldContent)) { |
| Object newContent = richText.getText(); |
| richText.setInitialText((String)newContent); |
| if (!newContent.equals(oldContent)) { |
| actionMgr.doAction(IActionManager.SET, modalObject, |
| modalObjectFeature, newContent, -1); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Save last modified rich text |
| */ |
| public void saveModifiedRichText() { |
| saveModifiedRichText(modifiedRichText); |
| } |
| |
| protected LibraryValidateAction createValidateResourceAction() { |
| return new LibraryValidateAction(false) { |
| /* (non-Javadoc) |
| * @see org.eclipse.epf.authoring.ui.actions.LibraryValidateAction#refreshViews() |
| */ |
| protected void refreshViews() { |
| LibraryView.getView().refreshViews(); |
| } |
| }; |
| } |
| |
| public boolean validateResources(Collection modifiedResources) { |
| ArrayList<EObject> elements = new ArrayList<EObject>(); |
| for (Iterator iter = modifiedResources.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| if (resource instanceof MultiFileXMIResourceImpl) { |
| elements.addAll(resource.getContents()); |
| } |
| } |
| LibraryValidateAction validateAction = createValidateResourceAction(); |
| validateAction.updateSelection(new StructuredSelection(elements)); |
| validateAction.run(); |
| return validateAction.isSuccessful(); |
| } |
| |
| /** |
| * @see org.eclipse.epf.authoring.ui.editors.AbstractBaseFormEditor#doSave(org.eclipse.core.runtime.IProgressMonitor) |
| */ |
| public void doSave(IProgressMonitor monitor) { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.doSave: saving changes to method library"); //$NON-NLS-1$ |
| } |
| |
| saveModifiedRichText(modifiedRichText); |
| |
| getPersister(); |
| try { |
| // check for modifiable |
| // |
| Collection<Resource> modifiedResources = getModifiedResources(); |
| |
| ArrayList<Resource> resourcesToSave = new ArrayList<Resource>(modifiedResources); |
| |
| // update version info in library resource if needed by adding |
| // library resource to collection |
| // of modified resources |
| // |
| HashSet<Resource> resourcesToUpdateVersionInfo = new HashSet<Resource>(); |
| if (!modifiedResources.isEmpty()) { |
| for (Iterator iter = modifiedResources.iterator(); iter |
| .hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| MethodElement me = PersistenceUtil |
| .getMethodElement(resource); |
| if (me != null) { |
| MethodLibrary lib = UmaUtil.getMethodLibrary(me); |
| if (lib != null) { |
| Resource libResource = lib.eResource(); |
| if (libResource != null |
| && !modifiedResources.contains(libResource) |
| && !resourcesToUpdateVersionInfo |
| .contains(libResource) |
| && PersistenceUtil |
| .checkToolVersion(libResource) != 0) { |
| resourcesToUpdateVersionInfo.add(libResource); |
| } |
| } |
| } |
| } |
| resourcesToSave.addAll(resourcesToUpdateVersionInfo); |
| } |
| |
| IStatus status = UserInteractionHelper.checkModify( |
| resourcesToSave, getSite().getShell()); |
| if (!status.isOK()) { |
| handleError(status); |
| return; |
| } |
| |
| // check for out-of-synch |
| // |
| if (checkFileChanged(resourcesToSave)) { |
| String title = LibraryEditResources.update_outofsynch_title; |
| String msg = LibraryEditResources.update_outofsynch_msg; |
| if (!AuthoringUIPlugin.getDefault().getMsgDialog() |
| .displayPrompt(title, msg)) { |
| return; |
| } |
| } |
| |
| // flag the resources to update version info as modified so they |
| // will be saved |
| // |
| if (!resourcesToUpdateVersionInfo.isEmpty()) { |
| for (Iterator iter = resourcesToUpdateVersionInfo.iterator(); iter |
| .hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| resource.setModified(true); |
| } |
| } |
| |
| if(isValidateResourcesBeforeSaveRequired()) { |
| // validate |
| // |
| if(!validateResources(modifiedResources)) { |
| return; |
| } |
| } |
| else { |
| // no validation before save |
| // remove all validation errors markers associated with current method element |
| // |
| if(LibraryValidationMarkerHelper.INSTANCE.hasMarkers(elementObj)) { |
| LibraryValidationMarkerHelper.INSTANCE.deleteMarkers(elementObj); |
| |
| // refresh library view |
| // |
| LibraryView view = LibraryView.getView(); |
| if(view != null) { |
| MethodElementLabelDecorator.clearDecorationCache(); |
| view.getViewer().refresh(); |
| } |
| } |
| } |
| |
| |
| // Save. |
| // |
| Object oldValue = persister.getSaveOptions().get( |
| ILibraryPersister.FailSafeMethodLibraryPersister.OPTIONS_OVERWRITABLE_RESOURCES); |
| |
| Collection<Resource> resourcesToAdjustLocation = null; |
| |
| try { |
| persister.getSaveOptions().put( |
| ILibraryPersister.FailSafeMethodLibraryPersister.OPTIONS_OVERWRITABLE_RESOURCES, |
| getOverwritableResources()); |
| |
| for (Iterator iter = resourcesToSave.iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| try { |
| persister.save(resource); |
| } catch (Exception e) { |
| String title = AuthoringUIResources.editors_MethodElementEditor_saveErrorTitle; |
| String msg = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage1; |
| String reason = e.getMessage() == null ? AuthoringUIResources.editors_MethodElementEditor_saveErrorReason1 |
| : e.getMessage(); |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| title, msg, reason, e); |
| throw e; |
| } |
| } |
| |
| try { |
| persister.commit(); |
| dirty = false; |
| actionMgr.saveIsDone(); |
| changeTime = -1; |
| resourcesToAdjustLocation = getResourceToAdjustLocation(); |
| setResourceInfos(getUsedResources()); |
| } catch (Exception e) { |
| String reason = e.getMessage(); |
| if (StrUtil.isBlank(reason)) { |
| reason = AuthoringUIResources.editors_MethodElementEditor_saveErrorReason2; |
| } |
| StringWriter details = new StringWriter(); |
| e.printStackTrace(new PrintWriter(details)); |
| String title = AuthoringUIResources.editors_MethodElementEditor_saveErrorTitle; |
| String message = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage2; |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| title, message, reason, details.toString(), e); |
| throw e; |
| } |
| } |
| finally { |
| persister.getSaveOptions().put( |
| ILibraryPersister.FailSafeMethodLibraryPersister.OPTIONS_OVERWRITABLE_RESOURCES, |
| oldValue); |
| } |
| |
| // Rename |
| // |
| //Collection<Resource> resourcesToAdjustLocation = getResourceToAdjustLocation(); |
| if (resourcesToAdjustLocation != null && !resourcesToAdjustLocation.isEmpty()) { |
| try { |
| persister.adjustLocation(resourcesToAdjustLocation); |
| } catch (Exception e) { |
| String title = AuthoringUIResources.editors_MethodElementEditor_renameErrorTitle; |
| String template = AuthoringUIResources.editors_MethodElementEditor_renameErrorMessage1; |
| StringBuffer fileList = new StringBuffer(); |
| for (Iterator iter = resourcesToAdjustLocation.iterator(); iter |
| .hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| Object obj = FileManager.toFileString(resource.getURI()); |
| if(obj == null) { |
| obj = resource; |
| } |
| fileList.append(obj).append(", "); //$NON-NLS-1$ |
| } |
| String msg = MessageFormat.format(template, |
| new Object[] { fileList }); |
| String reason = e.getMessage() == null ? AuthoringUIResources.editors_MethodElementEditor_saveErrorReason1 |
| : e.getMessage(); |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| title, msg, reason, e); |
| throw e; |
| } |
| |
| try { |
| persister.commit(); |
| } catch (Exception e) { |
| String reason = e.getMessage(); |
| if (StrUtil.isBlank(reason)) { |
| reason = AuthoringUIResources.editors_MethodElementEditor_saveErrorReason2; |
| } |
| StringWriter details = new StringWriter(); |
| e.printStackTrace(new PrintWriter(details)); |
| String title = AuthoringUIResources.editors_MethodElementEditor_renameErrorTitle; |
| String message = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage2; |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| title, message, reason, details.toString(), e); |
| throw e; |
| } |
| |
| resourcesToAdjustLocation.clear(); |
| } |
| } catch (Exception e) { |
| AuthoringUIPlugin.getDefault().getLogger().logError(e); |
| try { |
| persister.rollback(); |
| } catch (Exception ex) { |
| AuthoringUIPlugin.getDefault().getLogger().logError(ex); |
| ViewHelper.reloadCurrentLibaryOnRollbackError(getSite() |
| .getShell()); |
| } |
| } |
| } |
| |
| private Collection<Resource> getOverwritableResources() { |
| if(resourceInfoMap == null) { |
| return Collections.EMPTY_LIST; |
| } |
| ArrayList<Resource> resources = new ArrayList<Resource>(); |
| for (Iterator iter = resourceInfoMap.values().iterator(); iter.hasNext();) { |
| ResourceInfo info = (ResourceInfo) iter.next(); |
| if(info.overwrite) { |
| resources.add(info.resource); |
| } |
| } |
| return resources; |
| } |
| |
| private Collection<Resource> getResourceToAdjustLocation() { |
| if(resourceInfoMap == null) { |
| return Collections.EMPTY_LIST; |
| } |
| ArrayList<Resource> resources = new ArrayList<Resource>(); |
| for (Iterator iter = resourceInfoMap.values().iterator(); iter.hasNext();) { |
| ResourceInfo info = (ResourceInfo) iter.next(); |
| if(info.adjustLocation) { |
| resources.add(info.resource); |
| } |
| } |
| return resources; |
| } |
| |
| /** |
| * @return |
| */ |
| protected boolean isValidateResourcesBeforeSaveRequired() { |
| return false; |
| } |
| |
| protected void saveResource(Resource resource) { |
| if (resource != null && resource.isModified()) { |
| try { |
| getPersister().save(resource); |
| } catch (Exception e) { |
| String title = AuthoringUIResources.editors_MethodElementEditor_saveErrorTitle; |
| String template = AuthoringUIResources.editors_MethodElementEditor_saveErrorMessage1; |
| String msg = MessageFormat.format(template, |
| new Object[] { resource.getURI().toFileString() }); |
| String reason = e.getMessage() == null ? AuthoringUIResources.editors_MethodElementEditor_saveErrorReason1 |
| : e.getMessage(); |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| title, msg, reason, e); |
| } |
| } |
| } |
| |
| protected void createPreviewPage() { |
| Composite parent = getContainer(); |
| Composite previewComposite = new Composite(parent, SWT.NONE); |
| previewComposite.setLayout(new GridLayout()); |
| |
| PreviewPage page = new PreviewPage(previewComposite); |
| previewer = page.getPreviewViewer(); |
| |
| preview_page_index = addPage(previewComposite); |
| setPageText(preview_page_index, AuthoringUIResources.previewPage_title); |
| } |
| |
| /** |
| * Override this method to listen to the tab change. |
| */ |
| protected void pageChange(int newPageIndex) { |
| super.pageChange(newPageIndex); |
| |
| if (preview_page_index == newPageIndex && previewer != null) { |
| // Use the default layout manager. |
| //previewer.setLayoutManager(null); |
| previewer.showElementContent(elementObj); |
| } |
| Object page = pages.get(newPageIndex); |
| if (page instanceof MultiPageEditorPart) { |
| IViewPart propertiesView = getEditorSite().getPage().findView("org.eclipse.ui.views.PropertySheet"); //$NON-NLS-1$ |
| if (propertiesView instanceof PropertySheet) { |
| ((PropertySheet)propertiesView).partActivated(this); |
| } |
| |
| } |
| } |
| |
| public void setDirty() { |
| dirty = true; |
| firePropertyChange(PROP_DIRTY); |
| } |
| |
| /** |
| * Restore value of the control |
| * @param control |
| * @param value |
| * @return |
| * boolean value to indicate whether control was restored or not |
| */ |
| public boolean mustRestoreValue(Object control, Object value) { |
| if (widgetToCheck == control) { |
| // the control is currently being checked for editable, but there is |
| // still focus lost |
| // event is being sent out even the check is not completed yet. |
| // return true so the focusLost() will not make any change to the |
| // control. |
| // |
| return true; |
| } |
| |
| Object editControl = control; |
| if (editControl instanceof MethodRichTextEditor) { |
| editControl = ((MethodRichTextEditor) control).getRichTextControl(); |
| } |
| boolean restore = widgetsToRestoreValue.contains(editControl); |
| if (!restore) { |
| synchronized (widgetsToRestoreValue) { |
| restore = widgetsToRestoreValue.contains(editControl); |
| } |
| } |
| if (restore) { |
| if (editControl instanceof Text) { |
| Text text = ((Text) editControl); |
| text.setText((String) value); |
| } else if (editControl instanceof IMethodRichText) { |
| IMethodRichText richText = (IMethodRichText) editControl; |
| richText.setText((String) value); |
| } |
| widgetsToRestoreValue.remove(editControl); |
| } |
| return restore; |
| } |
| |
| /** |
| * Modify Listener |
| * |
| */ |
| public class ModifyListener implements |
| org.eclipse.swt.events.ModifyListener { |
| |
| private EObject element; |
| |
| private boolean checkContainerResource; |
| |
| private boolean disabled = false; |
| |
| /** |
| * Creates a new instance. |
| */ |
| public ModifyListener(EObject element, boolean checkContainer) { |
| super(); |
| checkContainerResource = checkContainer; |
| this.element = element; |
| } |
| |
| private void restoreText(Object control, String txt) { |
| boolean old = disabled; |
| try { |
| disabled = true; |
| Object editControl = control; |
| if (editControl instanceof MethodRichTextEditor) { |
| editControl = ((MethodRichTextEditor) control) |
| .getRichTextControl(); |
| } |
| if (editControl instanceof Text) { |
| Text text = ((Text) editControl); |
| text.setText(txt); |
| } else if (editControl instanceof IMethodRichText) { |
| IMethodRichText richText = (IMethodRichText) editControl; |
| richText.setText(txt); |
| } |
| } finally { |
| disabled = old; |
| } |
| } |
| |
| private boolean checkEdit(EObject element, Object control, |
| boolean checkContainerResource) { |
| // keep a reference to the current widget so mustRestoreValue() can |
| // use it to check |
| // whether a focus lost event is triggered during a checkEdit. |
| // mustRestoreValue() then |
| // returns true so focusLost() will not try to make change to the |
| // value bound to the widget |
| // |
| widgetToCheck = control; |
| try { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.checkEdit: enter, control=" + control); //$NON-NLS-1$ |
| } |
| IStatus status = null; |
| if (widgetsToRestoreValue.contains(control)) { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.checkEdit: widget found in widgetsToRestoreValue, exit"); //$NON-NLS-1$ |
| } |
| return false; |
| } |
| |
| synchronized (widgetsToRestoreValue) { |
| if (widgetsToRestoreValue.contains(control)) { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.checkEdit: widget found in widgetsToRestoreValue, exit"); //$NON-NLS-1$ |
| } |
| return false; |
| } |
| |
| status = TngUtil.checkEdit(element, getSite().getShell()); |
| |
| if (!status.isOK()) { |
| if (control instanceof IRichText) { |
| ((IRichText) control).restoreText(); |
| } else { |
| if (control == currentFeatureEditor) { |
| restoreText(control, (String) element |
| .eGet(currentEditedFeature)); |
| } else { |
| // Add the control to the list of widgets whose |
| // value needs |
| // to be restored to the original one.. |
| widgetsToRestoreValue.add(control); |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.checkEdit: added widget to widgetsToRestoreValue"); //$NON-NLS-1$ |
| } |
| } |
| } |
| } else if (checkContainerResource) { |
| if (element.eContainer() != null |
| && element.eContainer().eResource() != element |
| .eResource()) { |
| status = TngUtil.checkEdit(element.eContainer(), |
| getSite().getShell()); |
| if (!status.isOK()) { |
| // // Add the control to the list of widgets |
| // whose value |
| // // needs to be restored to the original one. |
| // if (debug) { |
| // System.out |
| // .println("MethodElementEditor.checkEdit: |
| // added widget to widgetsToRestoreValue"); |
| // //$NON-NLS-1$ |
| // } |
| if (control instanceof IRichText) { |
| ((IRichText) control).restoreText(); |
| } else { |
| if (control == currentFeatureEditor) { |
| restoreText(control, (String) element |
| .eGet(currentEditedFeature)); |
| } else { |
| widgetsToRestoreValue.add(control); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| if (status != null && !status.isOK()) { |
| AuthoringUIPlugin.getDefault().getMsgDialog().displayError( |
| AuthoringUIResources.editDialog_title, |
| AuthoringUIResources.editDialog_msgCannotEdit, |
| status); |
| return false; |
| } |
| |
| return true; |
| } finally { |
| // clear the reference when the check is done |
| // |
| widgetToCheck = null; |
| } |
| } |
| |
| /** |
| * @see org.eclipse.swt.events.ModifyListener#modifyText(ModifyEvent) |
| */ |
| public void modifyText(ModifyEvent e) { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: enter, disabled=" + disabled); //$NON-NLS-1$ |
| } |
| if (!disabled && element != null) { |
| if (e.widget == null) { |
| return; |
| } |
| |
| Object widget = e.widget; |
| if (widget instanceof Browser) { |
| widget = ((Browser) widget) |
| .getData(IMethodRichText.PROPERTY_NAME); |
| if (widget == null) { |
| widget = e.widget; |
| } |
| } |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: widget=" + widget); //$NON-NLS-1$ |
| } |
| |
| if (widgetsToRestoreValue.contains(widget)) { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: widget found in widgetsToRestoreValue, exit"); //$NON-NLS-1$ |
| } |
| return; |
| } |
| |
| if (!checkEdit(element, widget, checkContainerResource)) { |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: checkEdit failed, exit"); //$NON-NLS-1$ |
| } |
| return; |
| } |
| |
| if (widget instanceof IMethodRichText) { |
| IMethodRichText richText = (IMethodRichText) widget; |
| setModifiedRichText(richText); |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: adding to modifiedRichTexts list"); //$NON-NLS-1$ |
| } |
| } |
| |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: marking editor as dirty"); //$NON-NLS-1$ |
| } |
| setDirty(); |
| } |
| |
| if (DEBUG) { |
| System.out |
| .println("MethodElementEditor.ModifyListener.modifyText: exit"); //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Sets the underlying model element. |
| * |
| * @param element |
| * A method element. |
| */ |
| public void setElement(EObject element) { |
| this.element = element; |
| } |
| |
| /** |
| * Sets the disable flag. |
| * |
| * @param disabled |
| * If <code>true</code>, ignore the modify events. |
| */ |
| public void setDisable(boolean disabled) { |
| this.disabled = disabled; |
| } |
| } |
| |
| /** |
| * Creates an new instance of ModifyListener that supports team and CM |
| * integration Any control in the editor, if it needs a ModifyListener, must |
| * use one created by this method |
| * |
| * @param eObj |
| * |
| * @return |
| */ |
| public ModifyListener createModifyListener(EObject eObj) { |
| return createModifyListener(eObj, false); |
| } |
| |
| /** |
| * Creates an new instance of ModifyListener that supports team and CM |
| * integration Any control in the editor, if it needs a ModifyListener, must |
| * use one created by this method |
| * |
| * @param eObj |
| * @param checkContainer |
| * if true will check the container of the given object for |
| * editable as well when checking the given object for editable |
| * |
| * @return |
| * Modify Listener |
| */ |
| public ModifyListener createModifyListener(EObject eObj, |
| boolean checkContainer) { |
| return new ModifyListener(eObj, checkContainer); |
| } |
| |
| /** |
| * Sets the specified control to be the current editor of the specified |
| * feature. |
| * |
| * @param control |
| * @param feature |
| */ |
| public void setCurrentFeatureEditor(Object control, |
| EStructuralFeature feature) { |
| currentFeatureEditor = control; |
| currentEditedFeature = feature; |
| } |
| |
| protected void monitorChange() { |
| IExtensionRegistry registry = Platform.getExtensionRegistry(); |
| IExtensionPoint point = registry |
| .getExtensionPoint("org.eclipse.core.resources.refreshProviders"); //$NON-NLS-1$ |
| if (point == null) |
| return; |
| IExtension[] extensions = point.getExtensions(); |
| for (int i = 0; i < extensions.length; i++) { |
| IExtension extension = extensions[i]; |
| if (DEBUG) { |
| System.out |
| .println("extension: UID=" + extension.getUniqueIdentifier() + ", " + extension); //$NON-NLS-1$ //$NON-NLS-2$ |
| } |
| } |
| } |
| |
| private Map<Resource, ResourceInfo> getResourceInfoMap() { |
| if(resourceInfoMap == null) { |
| resourceInfoMap = new HashMap<Resource, ResourceInfo>(); |
| } |
| return resourceInfoMap; |
| } |
| |
| /** |
| * Add resource to adjust location |
| * @param resource |
| */ |
| public void addResourceToAdjustLocation(Resource resource) { |
| ResourceInfo info = getResourceInfoMap().get(resource); |
| if(info == null) { |
| info = new ResourceInfo(resource); |
| getResourceInfoMap().put(resource, info); |
| } |
| info.adjustLocation = true; |
| } |
| |
| protected List getUsedFeatures() { |
| return elementObj.eClass().getEAllStructuralFeatures(); |
| } |
| |
| /** |
| * Gets resources that are currently being used by this editors |
| * |
| * @return |
| * list of used resources |
| */ |
| public Collection<Resource> getUsedResources() { |
| HashSet<Resource> resources = new HashSet<Resource>(); |
| Resource resource = elementObj.eResource(); |
| if (resource != null) { |
| resources.add(resource); |
| } |
| List allFeatures = getUsedFeatures(); |
| for (int i = allFeatures.size() - 1; i > -1; i--) { |
| EStructuralFeature feature = (EStructuralFeature) allFeatures |
| .get(i); |
| if (feature.isMany()) { |
| List values = (List) elementObj.eGet(feature); |
| for (int j = values.size() - 1; j > -1; j--) { |
| EObject value = (EObject) values.get(j); |
| if (value.eResource() != null) { |
| resources.add(value.eResource()); |
| } |
| } |
| } else { |
| Object value = elementObj.eGet(feature); |
| if (value instanceof EObject |
| && (resource = ((EObject) value).eResource()) != null) { |
| resources.add(resource); |
| } |
| } |
| } |
| lastUsedResources = resources; |
| return resources; |
| } |
| |
| private Map getURIToUsedResourceMap() { |
| HashMap<URI, Resource> map = new HashMap<URI, Resource>(); |
| for (Iterator iter = getUsedResources().iterator(); iter.hasNext();) { |
| Resource resource = (Resource) iter.next(); |
| map.put(resource.getURI(), resource); |
| } |
| return map; |
| } |
| |
| protected void handleError(IStatus status) { |
| AuthoringUIPlugin.getDefault().getMsgDialog().display( |
| AuthoringUIResources.errorDialog_title, |
| AuthoringUIResources.editDialog_msgCannotEdit, |
| status); |
| } |
| |
| /** |
| * Handles the activation of this view. |
| */ |
| protected void handleActivate(IWorkbenchPart part) { |
| // TODO: Review implementation. |
| // Make sure that the method library open is not closed. |
| XMILibraryUtil.openMethodLibraryProject(LibraryService.getInstance() |
| .getCurrentMethodLibrary(), getEditorSite().getActionBars() |
| .getStatusLineManager().getProgressMonitor()); |
| |
| if (checkFileChangedRequired) { |
| Collection<Resource> usedResources = getUsedResources(); |
| if (checkFileChanged(usedResources)) { |
| handleFileChanged(usedResources); |
| } |
| } |
| } |
| |
| /** |
| * Displays a dialog that asks if conflicting changes should be discarded. |
| */ |
| protected boolean handleDirtyConflict() { |
| String title = AuthoringUIResources._UI_FileConflict_label; |
| String msg = AuthoringUIResources._WARN_FileConflict; |
| return AuthoringUIPlugin.getDefault().getMsgDialog().displayPrompt( |
| title, msg); |
| } |
| |
| /** |
| * Handles changed resources when this view is activated. |
| */ |
| protected void handleChangedResources() { |
| if ((elementObj.eIsProxy() || !changedResources.isEmpty()) |
| && (!isDirty() || handleDirtyConflict())) { |
| // editingDomain.getCommandStack().flush(); |
| |
| // for (Iterator i = changedResources.iterator(); i.hasNext();) { |
| // Resource resource = (Resource) i.next(); |
| // if (resource.isLoaded()) { |
| // if(resource instanceof MultiFileXMIResourceImpl) { |
| // try { |
| // ((MultiFileXMIResourceImpl)resource).reload(null); |
| // } catch (IOException e) { |
| // AuthoringUIPlugin.getDefault().getLogger().logError(e); |
| // } |
| // } |
| // else { |
| // resource.unload(); |
| // try { |
| // resource.load(Collections.EMPTY_MAP); |
| // } catch (IOException e) { |
| // AuthoringUIPlugin.getDefault().getLogger().logError(e); |
| // } |
| // } |
| // } |
| // } |
| } |
| } |
| |
| /** |
| * Checks whether input is valid or not |
| * @return boolean value |
| */ |
| public boolean isInputValid() { |
| if (elementObj != null && elementObj.eIsProxy()) { |
| EObject e = RefreshJob.getInstance().resolve(elementObj); |
| return (e instanceof MethodElement && !e.eIsProxy() && UmaUtil |
| .getMethodLibrary(e) == LibraryService.getInstance() |
| .getCurrentMethodLibrary()); |
| } |
| return true; |
| } |
| |
| protected void updatePages() { |
| while (getPageCount() > 0) { |
| removePage(0); |
| } |
| addPages(); |
| } |
| |
| protected IEditorInput createInput(MethodElement e) { |
| return new MethodElementEditorInput(e); |
| } |
| |
| public synchronized void refresh(final boolean force) { |
| BusyIndicator.showWhile(getSite().getShell().getDisplay(), |
| new Runnable() { |
| |
| public void run() { |
| Collection<Resource> usedResources = lastUsedResources; |
| if (!force && !elementObj.eIsProxy() |
| && !checkReloaded(usedResources)) { |
| // no resource reloaded, no need to refresh |
| // |
| return; |
| } |
| int activePageIndex = getActivePage(); |
| modifiedRichText = null; |
| if (isDirty()) { |
| actionMgr.undoAll(); |
| dirty = false; |
| } |
| if (elementObj.eIsProxy()) { |
| elementObj.eAdapters().remove(nameChangedListener); |
| EObject e = RefreshJob.getInstance().resolve( |
| elementObj); |
| if (e instanceof MethodElement |
| && !e.eIsProxy() |
| && UmaUtil.getMethodLibrary(e) == LibraryService |
| .getInstance() |
| .getCurrentMethodLibrary()) { |
| setInput(createInput((MethodElement) e)); |
| } else { |
| // input element is invalid, close the editor |
| // |
| close(false); |
| return; |
| } |
| } |
| setResourceInfos(usedResources); |
| updatePages(); |
| if (activePageIndex != -1) { |
| setActivePage(activePageIndex); |
| } |
| firePropertyChange(IEditorPart.PROP_DIRTY); |
| } |
| |
| }); |
| |
| } |
| |
| /** |
| * Refreshes the editor |
| */ |
| public void refresh() { |
| refresh(RefreshJob.getInstance().getChangedResources()); |
| } |
| |
| protected void refresh(Collection<Resource> changedResources) { |
| // save changed resources before refresh so action manager will not try |
| // to save these changed resources |
| // |
| this.changedResources.addAll(changedResources); |
| refresh(false); |
| this.changedResources.clear(); |
| } |
| |
| |
| /** |
| * Public method to refresh editor title image on certain action. |
| * e.g. If methodPlugin is locked, editor title image should be grey-ed out. |
| * |
| * @param methodElement |
| */ |
| public void refreshTitleImage() { |
| if (fMethodElementEditorErrorTickUpdater != null) |
| fMethodElementEditorErrorTickUpdater.updateEditorImage(elementObj); |
| } |
| |
| public void updatedTitleImage(Image image) { |
| setTitleImage(image); |
| } |
| |
| public void gotoMarker(IMarker marker) { |
| if(marker.getResource() == elementFile) { |
| try { |
| Object val = marker.getAttribute(LibraryValidationMarkerHelper.GUID); |
| if(val instanceof String) { |
| String guid = (String) val; |
| MethodElement e = LibraryService.getInstance().getCurrentLibraryManager().getMethodElement(guid); |
| if(e != elementObj) { |
| // wrong element is opened because element from the |
| // marker is not the top element in its resource |
| // close this editor and open the right one |
| // |
| close(false); |
| IEditorKeeper.REFERENCE.getEditorKeeper().openEditor(e); |
| return; |
| } |
| } |
| } catch (CoreException e) { |
| |
| } |
| } |
| |
| // open description page |
| setActivePage(0); |
| } |
| |
| public boolean isDisposed() { |
| return disposed; |
| } |
| |
| public EditingDomain getEditingDomain() { |
| return editingDomain; |
| } |
| } |