blob: 26da044f315703bfeafa17f6561db687202ecee0 [file] [log] [blame]
//------------------------------------------------------------------------------
// 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.views;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.util.WrappedException;
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.ecore.util.InternalEList;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.emf.edit.provider.ItemProviderAdapter;
import org.eclipse.epf.authoring.ui.AuthoringUIPlugin;
import org.eclipse.epf.authoring.ui.AuthoringUIResources;
import org.eclipse.epf.common.serviceability.MsgBox;
import org.eclipse.epf.common.serviceability.MsgDialog;
import org.eclipse.epf.library.ILibraryManager;
import org.eclipse.epf.library.LibraryService;
import org.eclipse.epf.library.LibraryServiceUtil;
import org.eclipse.epf.library.edit.FeatureValueWrapperItemProvider;
import org.eclipse.epf.library.edit.ui.UserInteractionHelper;
import org.eclipse.epf.library.edit.util.Misc;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.ui.LibraryUIManager;
import org.eclipse.epf.services.ILibraryPersister;
import org.eclipse.epf.uma.BreakdownElementDescription;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.NamedElement;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.util.UmaUtil;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
/**
* A helper class for managing the views and editors in the Authoring
* perspective.
*
* @author Phong Nguyen Le
* @author Kelvin Low
* @since 1.0
*/
public final class ViewHelper {
/**
* Prompts the user to save the open library if it has been modified.
*
* @return <code>true<code> if the user saved or discarded the change,
* <code>false</code> if the user cancelled the action that
* triggered this call.
*/
public static boolean promptSave() {
ILibraryManager manager = (ILibraryManager) LibraryService
.getInstance().getCurrentLibraryManager();
if (manager != null && manager.isMethodLibraryModified()) {
int ret = MsgBox.prompt(AuthoringUIResources.saveLibraryDialog_title,
AuthoringUIResources.saveLibraryDialog_text,
SWT.YES | SWT.NO | SWT.CANCEL);
switch (ret) {
case SWT.YES:
try {
LibraryService.getInstance().saveCurrentMethodLibrary();
} catch (Exception e) {
MsgDialog dialog = AuthoringUIPlugin.getDefault()
.getMsgDialog();
dialog
.displayError(
AuthoringUIResources.saveLibraryDialog_title,
AuthoringUIResources.saveLibraryError_msg,
AuthoringUIResources.error_reason, e);
return dialog
.displayPrompt(
AuthoringUIResources.openLibraryDialog_title,
AuthoringUIResources.openLibraryDialog_text);
}
break;
case SWT.NO:
// Discard all changes by resetting all resources as unchanged.
manager.discardMethodLibraryChanges();
break;
case SWT.CANCEL:
return false;
}
}
return true;
}
/**
* Prompts the user to save the open library if it has been modified.
*
* @return the choice the user made when prompted to save - one of SWT.YES, SWT.NO, SWT.CANCEL
*/
public static int promptSaveInt() {
ILibraryManager manager = (ILibraryManager) LibraryService
.getInstance().getCurrentLibraryManager();
if (manager != null && manager.isMethodLibraryModified()) {
int ret = MsgBox.prompt(AuthoringUIResources.saveLibraryDialog_title,
AuthoringUIResources.saveLibraryDialog_text,
SWT.YES | SWT.NO | SWT.CANCEL);
switch (ret) {
case SWT.YES:
try {
LibraryService.getInstance().saveCurrentMethodLibrary();
} catch (Exception e) {
MsgDialog dialog = AuthoringUIPlugin.getDefault()
.getMsgDialog();
dialog
.displayError(
AuthoringUIResources.saveLibraryDialog_title,
AuthoringUIResources.saveLibraryError_msg,
AuthoringUIResources.error_reason, e);
}
return SWT.YES;
case SWT.NO:
// Discard all changes by resetting all resources as unchanged.
manager.discardMethodLibraryChanges();
return SWT.NO;
case SWT.CANCEL:
return SWT.CANCEL;
}
}
return SWT.CANCEL;
}
/**
* closes all editors on the active page
*
*/
public static void closeAllEditors() {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.closeAllEditors(true);
}
/**
* closes the MessageView (error view)
*
*/
public static void closeMessageView() {
PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage()
.hideView(MessageView.getView());
}
/**
* handles a dangling object
* @param object
* @return
* Object
*/
public static Object handleDangling(Object object) {
if (object instanceof MethodElement
&& ((EObject) object).eResource() == null) {
AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
AuthoringUIResources.errorDialog_title,
AuthoringUIResources.bind(AuthoringUIResources.elementAlreadyDeletedError_msg, ((MethodElement) object).getName()));
return null;
} else if (object instanceof FeatureValueWrapperItemProvider) {
FeatureValueWrapperItemProvider adapter = (FeatureValueWrapperItemProvider) object;
Object value = adapter.getValue();
if (value instanceof MethodElement
&& ((EObject) value).eResource() == null) {
Object owner = TngUtil.unwrap(adapter.getParent(value));
if (owner instanceof ItemProviderAdapter) {
// This is a UI item provider.
owner = ((ItemProviderAdapter) owner).getTarget();
}
String ownerName = ((MethodElement) owner).getName();
EStructuralFeature feature = adapter.getFeature();
if (feature != null) {
if (AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayPrompt(
AuthoringUIResources.deleteDialog_title,
AuthoringUIResources.bind(AuthoringUIResources.ViewHelper_alreadydeletedconfirm_text, ((MethodElement) value)
.getName(), ownerName))) {
// Remove the association.
if (feature.isMany()) {
((Collection) ((EObject) owner).eGet(feature))
.remove(value);
}
}
} else {
AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayError(
AuthoringUIResources.errorDialog_title,
AuthoringUIResources.bind(AuthoringUIResources.elementAlreadyDeletedError_msg, ((MethodElement) value)
.getName()));
}
return null;
}
}
return object;
}
/* TODO: Is this still needed?
public static void loadAllAndSaveAll() {
final MethodLibrary lib = LibraryService.getInstance()
.getCurrentMethodLibrary();
if (lib == null)
return;
// Do the work within an operation because this is a long running
// activity that modifies the workbench.
WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
// This is the method that gets invoked when the operation runs.
public void execute(IProgressMonitor monitor) {
monitor.beginTask(AuthoringUIResources
.getString("AuthoringUI.upgradingLibraryTask.name"), 3); //$NON-NLS-1$
try {
try {
monitor.worked(1);
monitor
.setTaskName(AuthoringUIResources
.getString("AuthoringUI.loadingLibraryElementsTask.name")); //$NON-NLS-1$
ModelStorage.loadAllProxies(lib);
} catch (Exception e) {
AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayError(
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryDialog.title"), //$NON-NLS-1$
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryError.msg"), //$NON-NLS-1$
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryError.reason"), //$NON-NLS-1$
e);
return;
}
try {
monitor.worked(1);
monitor
.setTaskName(AuthoringUIResources
.getString("AuthoringUI.savingUpgradedElementsTask.name")); //$NON-NLS-1$
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) lib
.eResource().getResourceSet();
resourceSet.save(LibraryProcessor.getInstance()
.getSaveOptions(), true);
} catch (Exception e) {
AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayError(
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryDialog.title"), //$NON-NLS-1$
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryError.msg"), //$NON-NLS-1$
AuthoringUIResources
.getString("AuthoringUI.saveUpgradedLibraryError.reason"), //$NON-NLS-1$
e);
}
} finally {
monitor.done();
}
}
};
try {
// Run the operation and display the progress.
new ProgressMonitorDialog(Display.getDefault().getActiveShell())
.run(true, false, operation);
} catch (Exception e) {
AuthoringUIPlugin
.getDefault()
.getMsgDialog()
.displayError(
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryDialog.title"), //$NON-NLS-1$
AuthoringUIResources
.getString("AuthoringUI.upgradeLibraryError.msg"), //$NON-NLS-1$
AuthoringUIResources
.getString("AuthoringUI.internalError.reason"), //$NON-NLS-1$
e);
}
}
*/
/**
* Checks if the current selection is locked.
*/
public static boolean isLocked(IStructuredSelection selection) {
for (Iterator iter = selection.iterator(); iter.hasNext();) {
Object element = iter.next();
while (element instanceof ITreeItemContentProvider) {
element = ((ITreeItemContentProvider) element).getParent(null);
}
element = TngUtil.unwrap(element);
if (element instanceof EObject
&& TngUtil.isLocked((EObject) element)) {
return true;
}
}
return false;
}
/**
* Fixes the content description GUIDs.
*/
public static void fixContentDescriptionGUIDs() {
final MethodLibrary lib = LibraryService.getInstance()
.getCurrentMethodLibrary();
if (lib == null)
return;
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
HashSet modifiedResources = new HashSet();
for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
InternalEObject element = (InternalEObject) iter.next();
if (element.eProxyURI() == null) {
if (element instanceof ContentDescription) {
ContentDescription content = (ContentDescription) element;
DescribableElement container = (DescribableElement) element
.eContainer();
if (container != null) {
String guid = UmaUtil.generateGUID(container
.getGuid());
if (!guid.equals(content.getGuid())) {
content.setGuid(guid);
modifiedResources.add(content.eResource());
modifiedResources
.add(container.eResource());
}
}
}
} else {
AuthoringUIPlugin
.getDefault()
.getLogger()
.logError(
"Unresolved proxy in '" + element.eResource().getURI().toFileString() + "': " + element); //$NON-NLS-1$ //$NON-NLS-2$
}
}
monitor.subTask(AuthoringUIResources.savingFilesTask_name);
ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
try {
for (Iterator iter = modifiedResources.iterator(); iter
.hasNext();) {
Resource resource = (Resource) iter.next();
monitor.subTask(AuthoringUIResources.bind(AuthoringUIResources.savingTask_name, resource.getURI().toFileString()));
persister.save(resource);
}
persister.commit();
} catch (Exception e) {
persister.rollback();
throw new WrappedException(e);
}
}
};
UserInteractionHelper
.runWithProgress(
runnable,
AuthoringUIResources.fixingContentDescriptionGUIDsTask_name);
}
private static String checkProxy(InternalEObject element, EReference ref,
Object value) {
if (value instanceof InternalEObject) {
InternalEObject eObj = (InternalEObject) value;
if (eObj.eIsProxy()) {
EObject resolved = element.eResolveProxy(eObj);
String errMsg = null;
if (resolved == eObj) {
errMsg = "Unresolved proxy"; //$NON-NLS-1$
} else if (!ref.getEType().isInstance(resolved)) {
errMsg = "Invalid data"; //$NON-NLS-1$
}
if (errMsg != null) {
String path;
if (element instanceof NamedElement) {
path = ref.getEType().getName()
+ "(" + Misc.getPathRelativeToLibrary((NamedElement) element) + ")." + ref.getName() + " = "; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
} else {
path = ""; //$NON-NLS-1$
}
return errMsg
+ " in '" + element.eResource().getURI().toFileString() + "': " + path + resolved; //$NON-NLS-1$ //$NON-NLS-2$
}
}
}
return null;
}
/**
* Library health check
*
*/
public static void checkLibraryHealth() {
final MethodLibrary lib = LibraryService.getInstance()
.getCurrentMethodLibrary();
if (lib == null)
return;
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
AuthoringUIPlugin.getDefault().getLogger().logInfo(
"++++ LIBRARY HEALTH CHECK REPORT - START +++"); //$NON-NLS-1$
StringWriter strWriter = new StringWriter();
PrintWriter printWriter = new PrintWriter(strWriter);
printWriter.println();
printWriter
.println("UNRESOLVED/INVALID PROXIES IN X-REFERENCES"); //$NON-NLS-1$
printWriter
.println("------------------------------------------"); //$NON-NLS-1$
for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
InternalEObject element = (InternalEObject) iter.next();
if (element.eProxyURI() == null) {
if (element instanceof ContentDescription) {
ContentDescription content = (ContentDescription) element;
DescribableElement container = (DescribableElement) element
.eContainer();
if (container != null) {
String guid = UmaUtil.generateGUID(container
.getGuid());
if (!guid.equals(content.getGuid())) {
AuthoringUIPlugin
.getDefault()
.getLogger()
.logError(
"ContentDescription with invalid GUID: " + content.getGuid() + " in '" + content.eResource().getURI().toFileString() + "'"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
} else {
AuthoringUIPlugin
.getDefault()
.getLogger()
.logError(
"ContentDescription without a container: " + content); //$NON-NLS-1$
}
if (content instanceof BreakdownElementDescription) {
// check if the content.xmi of the process is in
// the right place
ProcessComponent procComp = UmaUtil
.getProcessComponent(content);
if (procComp != null) {
String modelPath = procComp.eResource()
.getURI().toFileString();
File dir = new File(modelPath)
.getParentFile();
String contentPath = content.eResource()
.getURI().toFileString();
// System.out.println("model path: " +
// modelPath);
// System.out.println("content path: " +
// contentPath);
// System.out.println();
File contentDir = new File(contentPath)
.getParentFile();
if (!dir.equals(contentDir)) {
AuthoringUIPlugin
.getDefault()
.getLogger()
.logError(
"Content file of " + container.eClass().getName() + " '" + container.getName() + "' in '" + modelPath + " is misplaced: " + contentPath); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
}
}
}
}
// check for unresolved proxies in cross references
ArrayList xReferences = new ArrayList(element.eClass()
.getEAllReferences());
xReferences.removeAll(element.eClass()
.getEAllContainments());
for (Iterator iterator = xReferences.iterator(); iterator
.hasNext();) {
EReference ref = (EReference) iterator.next();
Object value = element.eGet(ref, false);
if (ref.isMany()) {
if (value instanceof InternalEList) {
InternalEList list = (InternalEList) value;
for (Iterator iter1 = list.basicIterator(); iter1
.hasNext();) {
String msg = checkProxy(element, ref,
iter1.next());
if (msg != null) {
printWriter.println(msg);
}
}
}
} else {
String msg = checkProxy(element, ref, value);
if (msg != null) {
printWriter.println(msg);
}
}
}
} else {
AuthoringUIPlugin
.getDefault()
.getLogger()
.logError(
"Unresolved proxy in '" + element.eResource().getURI().toFileString() + "': " + element); //$NON-NLS-1$ //$NON-NLS-2$
}
}
AuthoringUIPlugin.getDefault().getLogger().logError(
strWriter.toString());
AuthoringUIPlugin.getDefault().getLogger().logInfo(
"++++ LIBRARY HEALTH CHECK REPORT - END +++"); //$NON-NLS-1$
}
};
if (UserInteractionHelper
.runWithProgress(runnable, AuthoringUIResources.viewHelper_performHealthCheck)) {
String title = AuthoringUIResources.viewHelperHealthCheckDialog_title;
String message = AuthoringUIResources.viewHelperHealthCheckDialog_message;
AuthoringUIPlugin.getDefault().getMsgDialog().displayInfo(title,
message);
}
}
/**
* removes invalid reference in the open library
*
*/
public static void removeInvalidReferences() {
final MethodLibrary lib = LibraryService.getInstance()
.getCurrentMethodLibrary();
if (lib == null)
return;
IRunnableWithProgress runnable = new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
throws InvocationTargetException, InterruptedException {
HashSet modifiedResources = new HashSet();
for (Iterator iter = lib.eAllContents(); iter.hasNext();) {
InternalEObject element = (InternalEObject) iter.next();
if (element.eProxyURI() == null) {
ArrayList xReferences = new ArrayList(element.eClass()
.getEAllReferences());
xReferences.removeAll(element.eClass()
.getEAllContainments());
for (Iterator iterator = xReferences.iterator(); iterator
.hasNext();) {
EReference ref = (EReference) iterator.next();
Object value = element.eGet(ref, false);
if (ref.isMany()) {
if (value instanceof InternalEList) {
InternalEList list = (InternalEList) value;
ArrayList invalidProxies = new ArrayList();
for (Iterator iter1 = list.basicIterator(); iter1
.hasNext();) {
Object v = iter1.next();
if (isInvalidReference(element, ref, v)) {
invalidProxies.add(v);
}
}
if (!invalidProxies.isEmpty()) {
removeInvalidReferences(element, list,
invalidProxies);
modifiedResources.add(element
.eResource());
}
}
} else {
if (isInvalidReference(element, ref, value)) {
element.eSet(ref, null);
modifiedResources.add(element.eResource());
}
}
}
} else {
AuthoringUIPlugin
.getDefault()
.getLogger()
.logError(
"Unresolved proxy in '" + element.eResource().getURI().toFileString() + "': " + element); //$NON-NLS-1$ //$NON-NLS-2$
}
}
monitor.subTask(AuthoringUIResources.savingFilesTask_name); //$NON-NLS-1$
ILibraryPersister.FailSafeMethodLibraryPersister persister = LibraryServiceUtil.getCurrentPersister().getFailSafePersister();
try {
for (Iterator iter = modifiedResources.iterator(); iter
.hasNext();) {
Resource resource = (Resource) iter.next();
monitor.subTask(AuthoringUIResources.bind(AuthoringUIResources.savingTask_name, resource.getURI().toFileString()));
persister.save(resource);
}
persister.commit();
} catch (Exception e) {
persister.rollback();
throw new WrappedException(e);
}
}
private boolean isInvalidReference(InternalEObject element,
EReference ref, Object value) {
if (value instanceof InternalEObject) {
InternalEObject eObj = (InternalEObject) value;
if (eObj.eIsProxy()) {
EObject resolved = element.eResolveProxy(eObj);
if (!ref.getEType().isInstance(resolved)) {
return true;
}
}
}
return false;
}
private void removeInvalidReferences(InternalEObject element,
InternalEList values, Collection invalidProxies) {
ArrayList list = new ArrayList(values.basicList());
list.removeAll(invalidProxies);
values.clear();
int max = list.size() - 1;
for (int i = max; i > -1; i--) {
list.set(i, element.eResolveProxy((InternalEObject) list
.get(i)));
}
values.addAll(list);
}
};
UserInteractionHelper.runWithProgress(runnable, AuthoringUIResources.deletingInvalidReferencesTask_name);
}
/**
* reloads the current library. Used on a rollback error
* @param shell
*/
public static void reloadCurrentLibaryOnRollbackError(Shell shell) {
reloadCurrentLibrary(shell, AuthoringUIResources.ViewHelper_reloadLibOnRollbackError);
}
/**
* displays the message and reloads the current library
* @param shell
* @param message
*/
public static void reloadCurrentLibrary(Shell shell, String message) {
if (shell == null) {
MsgBox.getDefaultShell();
}
String title = AuthoringUIResources.reloadDialog_title;
if (message == null) {
message = AuthoringUIResources.reloadDialog_message;
}
AuthoringUIPlugin.getDefault().getMsgDialog().displayInfo(title,
message);
// The library needs to be reloaded.
String libDir = LibraryService.getInstance()
.getCurrentMethodLibraryPath();
LibraryUIManager.getInstance().openLibrary(libDir);
}
/**
* opens the given viewId
* @param viewId
* @return
* View
*/
public static IViewPart openView(String viewId) {
try {
IWorkbenchPage activePage = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow().getActivePage();
if (activePage != null) {
IViewPart view = activePage.findView(viewId);
if (view == null) {
view = activePage.showView(viewId);
}
return view;
}
} catch (Exception e) {
AuthoringUIPlugin.getDefault().getMsgDialog().displayError(
AuthoringUIResources.errorDialog_title,
AuthoringUIResources.internalError_msg,
e);
}
return null;
}
}