blob: 1c15c6b540b02202ae1920287fb46ae423c27aab [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2008 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;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.configuration.PracticeSubgroupItemProvider;
import org.eclipse.epf.library.edit.process.ActivityWrapperItemProvider;
import org.eclipse.epf.library.edit.realization.IRealizationManager;
import org.eclipse.epf.library.edit.uma.Scope;
import org.eclipse.epf.library.edit.util.LibraryEditUtil;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.TngUtil;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.layout.IElementLayout;
import org.eclipse.epf.library.layout.elements.AbstractElementLayout;
import org.eclipse.epf.library.layout.elements.AbstractProcessElementLayout;
import org.eclipse.epf.library.layout.elements.ElementLayoutExtender;
import org.eclipse.epf.library.layout.elements.SummaryPageLayout;
import org.eclipse.epf.library.persistence.ILibraryResourceSet;
import org.eclipse.epf.library.realization.RealizationManagerFactory;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.BreakdownElement;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.CustomCategory;
import org.eclipse.epf.uma.MethodConfiguration;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
import org.eclipse.epf.uma.MethodPackage;
import org.eclipse.epf.uma.MethodPlugin;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.epf.uma.ProcessPackage;
import org.eclipse.epf.uma.ecore.impl.MultiResourceEObject;
import org.eclipse.epf.uma.ecore.util.OppositeFeature;
import org.eclipse.swt.SWT;
import org.eclipse.ui.IPerspectiveDescriptor;
import org.eclipse.ui.IPerspectiveListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
/**
* Delegate class used in ConfigurationHelper
*
* @author Weiping Lu
* @since 1.5
*/
public class ConfigHelperDelegate {
private boolean publishingMode = false;
private boolean authoringPerspective = false;
private MethodConfiguration config;
private boolean loadForBrowsingNeeded = true;
public ConfigHelperDelegate() {
LibraryService.getInstance().addListener(libServiceListener);
IRealizationManager mgr = RealizationManagerFactory.getInstance().newRealizationManager(null);
LibraryEditUtil.getInstance().setDefaultRealizationManager(mgr);
}
/**
* Test if pkg is a system package of plugin
* @param plugin
* @param pkg
* @return
*/
public boolean isSystemPackage(MethodPlugin plugin, MethodPackage pkg) {
return TngUtil.getAllSystemPackages(plugin).contains(pkg);
}
public void loadOppositeFeatures(ILibraryResourceSet resouceSet,
List<OppositeFeature> oppositeFeatures, MethodElement element) {
Set<String> GUIDs = new HashSet<String>();
GUIDs.add(element.getGuid());
resouceSet.loadOppositeFeatures(oppositeFeatures, GUIDs);
}
public boolean isOwnerSelected(MethodElement element,
MethodConfiguration config, boolean checkSubtracted) {
if (config instanceof Scope) {
return ((Scope)config).inScope(element);
}
MethodLibrary library = LibraryServiceUtil.getMethodLibrary(config);
ILibraryManager libraryManager = library == null? null : LibraryService.getInstance().getLibraryManager(library);
if (libraryManager != null) {
return LibraryService.getInstance()
.getConfigurationManager(config)
.getConfigurationData()
.isOwnerSelected(element, checkSubtracted);
}
if (element == null) {
return false;
}
if (config == null || ConfigurationHelper.isDescriptionElement(element)) {
return true;
}
// since UMA 1.0.4, configuration can have added categories
// and subtracted categories. The order of filtering is:
// 1. any element in the subtracted categories should be excluded
// 2. any element in the added categories should be included
// 3. any element not in the selected package or plugin should be excluded.
if ( checkSubtracted ) {
// first check subtracted elements
List subtractedCategories = config.getSubtractedCategory();
if ( subtractedCategories.size() > 0 ) {
for ( Iterator it = subtractedCategories.iterator(); it.hasNext(); ) {
ContentCategory cc = (ContentCategory)it.next();
if ( cc == element ) {
return false;
}
// need to check all content category types and sub-categories
// we need to have an efficient algorithm for this checking.
// for now, only check the custom category's categorised elements
// TODO. Jinhua Xi, 11/27/2006
if ( cc instanceof CustomCategory ) {
if ( ((CustomCategory)cc).getCategorizedElements().contains(element) ) {
return false;
}
} else {
// TODO, not implemented yet
System.out.println("TODO, isOwnerSelected: not implemented yet"); //$NON-NLS-1$
}
}
}
}
// then check added categories
// TODO
// elements beyond configuration scope should be always visible
if ((element instanceof MethodLibrary)
|| (element instanceof MethodConfiguration)) {
return true;
} else if (element instanceof MethodPlugin) {
List plugins = config.getMethodPluginSelection();
return (plugins != null) && plugins.contains(element);
} else {
// if the ownerprocess can't show, can't accept
if (element instanceof Activity) {
Activity base = (Activity) ((Activity) element)
.getVariabilityBasedOnElement();
if (base != null && base != element) {
MethodElement owningProc = TngUtil.getOwningProcess(base);
if ( owningProc != null && owningProc != element
&& !ConfigurationHelper.inConfig(owningProc, config, checkSubtracted)) {
return false;
}
}
}
EObject pkg = LibraryUtil.getSelectable(element);
// accept global package if the plugin is in the configuration
if (pkg instanceof MethodPackage
&& ConfigurationHelper.isGlobalPackage((MethodPackage) pkg)) {
MethodPlugin plugin = LibraryUtil.getMethodPlugin(pkg);
return ConfigurationHelper.inConfig(plugin, config, checkSubtracted);
}
List pkgs = config.getMethodPackageSelection();
if (pkgs == null) {
return false;
}
// per Phong's request, for ProcessPackage, check the
// ProcessComponent parent instead
if (pkg instanceof ProcessPackage) {
while ((pkg != null) && !(pkg instanceof ProcessComponent)
&& !pkgs.contains(pkg)) {
pkg = pkg.eContainer();
}
}
// if package not selected, return false
if ((pkg == null) || !pkgs.contains(pkg)) {
return false;
}
return true;
}
}
public void loadOppositeFeatures(Map map, List oppositeFeatures, Set deletedGUIDs) {
int max = oppositeFeatures.size() - 1;
if (max < 0) {
return;
}
Collection elements = new HashSet(map.values());
HashSet loadedElements = new HashSet();
while (!elements.isEmpty()) {
for (Iterator iter = elements.iterator(); iter.hasNext();) {
Object obj = iter.next();
if (obj instanceof MethodElement) {
MethodElement element = (MethodElement) obj;
MultiResourceEObject mrEObject = ((MultiResourceEObject) element);
for (int i = max; i > -1; i--) {
OppositeFeature oppositeFeature = ((OppositeFeature) oppositeFeatures
.get(i));
EStructuralFeature eFeature = oppositeFeature.getTargetFeature();
if (eFeature.getContainerClass().isInstance(element)) {
if (eFeature.isMany()) {
InternalEList list = (InternalEList) element
.eGet(eFeature);
if (!list.isEmpty()) {
boolean resolve = false;
check_resolve: for (Iterator iterator = list
.basicIterator(); iterator
.hasNext();) {
InternalEObject e = (InternalEObject) iterator
.next();
if (e.eIsProxy()) {
String guid = e.eProxyURI()
.fragment();
if (deletedGUIDs.contains(guid)) {
resolve = true;
break check_resolve;
}
}
}
if (resolve) {
Collection<Object> deletedElements = new HashSet<Object>();
for (Iterator iterator = list
.iterator(); iterator.hasNext();) {
Object o = iterator.next();
if(o instanceof MethodElement && deletedGUIDs.contains(((MethodElement) o).getGuid())) {
deletedElements.add(o);
}
}
for (Object e : deletedElements) {
if(oppositeFeature.isMany()) {
mrEObject.oppositeAdd(oppositeFeature, e);
}
else {
mrEObject.getOppositeFeatureMap().put(oppositeFeature, e);
}
}
}
}
} else {
Object value = element.eGet(eFeature, false);
if (value instanceof InternalEObject) {
InternalEObject e = (InternalEObject) value;
if (e.eIsProxy()) {
String guid = e.eProxyURI().fragment();
if (deletedGUIDs.contains(guid)) {
Object o = element.eGet(eFeature);
if(oppositeFeature.isMany()) {
mrEObject.oppositeAdd(oppositeFeature, o);
}
else {
mrEObject.getOppositeFeatureMap().put(oppositeFeature, o);
}
}
}
}
}
}
}
}
}
// gets the newly loaded elements to load their opposite features
//
loadedElements.addAll(elements);
elements = new HashSet(map.values());
elements.removeAll(loadedElements);
}
}
public String generateHtml(Object raw_element, HtmlBuilder htmlBuilder) {
loadForBrowsing(raw_element);
IElementLayout layout = null;
String file_url = "about:blank"; //$NON-NLS-1$
Object element = LibraryUtil.unwrap(raw_element);
if ( raw_element instanceof ActivityWrapperItemProvider ) {
ActivityWrapperItemProvider wrapper = (ActivityWrapperItemProvider)raw_element;
Object proc = wrapper.getTopItem();
if ( element instanceof MethodElement && proc instanceof org.eclipse.epf.uma.Process ) {
String path = AbstractProcessElementLayout.getPath(wrapper);
//System.out.println(topItem);
layout = htmlBuilder.getLayoutManager()
.createLayout((MethodElement)element,
(org.eclipse.epf.uma.Process)proc, path);
file_url = htmlBuilder.generateHtml(layout);
}
} else if (raw_element instanceof PracticeSubgroupItemProvider) {
PracticeSubgroupItemProvider provider = (PracticeSubgroupItemProvider) raw_element;
layout = new SummaryPageLayout(htmlBuilder.getLayoutManager(),
provider.getPractice(), provider.getPrefix(),
provider.getText(null), (List) provider.getChildren(null),
provider.getText(null));
((SummaryPageLayout) layout).setHtmlBuilder(htmlBuilder);
file_url = htmlBuilder.generateHtml(layout);
} else if (element instanceof MethodElement) {
file_url = htmlBuilder.generateHtml((MethodElement)element);
}
if ( file_url == null ) {
file_url = "about:blank"; //$NON-NLS-1$
}
// on linux, the file path need to be specified as file, otherwise it will be treated as url
// and casuign encoding/decoding issue
// Linux: Configuration names containing accented characters cannot be browsed.
else {
if (!SWT.getPlatform().equals("win32") && !file_url.startsWith("file://") && //$NON-NLS-1$ //$NON-NLS-2$
!file_url.equals("about:blank")) //$NON-NLS-1$
{
file_url = "file://" + file_url; //$NON-NLS-1$
}
// Bug 201335 - Refresh does not work correctly for process pages in browsing mode
// need to append the query string
if ( layout instanceof AbstractProcessElementLayout ) {
file_url += ((AbstractProcessElementLayout)layout).getQueryString();
}
}
return file_url;
}
//Should be overriden by sub classes
public ElementLayoutExtender newElementLayoutExtender(AbstractElementLayout layout) {
return null;
}
public void configViewRefreshNotified() {
}
public void debugDump(String msg) {
System.out.println("LD> " + getClass() + ".debugDump: " + msg); //$NON-NLS-1$//$NON-NLS-2$
}
public boolean isPublishingMode() {
return publishingMode;
}
public void setPublishingMode(boolean publishingMode) {
this.publishingMode = publishingMode;
}
public boolean isAuthoringPerspective() {
return authoringPerspective;
}
public void setAuthoringPerspective(boolean authoringPerspective) {
this.authoringPerspective = authoringPerspective;
}
public boolean isAuthoringMode() {
return isAuthoringPerspective();
}
private IPerspectiveListener perspectiveListener;
private void addPerspectiveListener() {
if (perspectiveListener != null) {
return;
}
IWorkbenchWindow window = PlatformUI.getWorkbench()
.getActiveWorkbenchWindow();
if (window != null) {
perspectiveListener = new IPerspectiveListener() {
public void perspectiveActivated(IWorkbenchPage page,
IPerspectiveDescriptor desc) {
handleConfigOrPersepctiveChange();
}
public void perspectiveChanged(IWorkbenchPage page,
IPerspectiveDescriptor desc, String id) {
handleConfigOrPersepctiveChange();
}
};
window.addPerspectiveListener(perspectiveListener);
}
}
private ILibraryServiceListener libServiceListener = new LibraryServiceListener() {
public void configurationSet(MethodConfiguration newConfig) {
addPerspectiveListener();
if (config == newConfig) {
return;
}
handleConfigOrPersepctiveChange();
config = newConfig;
}
};
private void loadForBrowsing(Object raw_element) {
if (!loadForBrowsingNeeded) {
return;
}
if (raw_element instanceof BreakdownElement
|| raw_element instanceof ActivityWrapperItemProvider) {
MethodConfiguration config = LibraryService.getInstance()
.getCurrentMethodConfiguration();
if (config == null) {
LibraryUtil.loadAll(LibraryService.getInstance()
.getCurrentMethodLibrary());
} else {
LibraryUtil.loadAllPlugins(config);
IRealizationManager mgr = getRealizationManager(config);
if (mgr != null) {
mgr.updateAllProcesseModels();
}
}
}
loadForBrowsingNeeded = false;
}
public IRealizationManager getRealizationManager(MethodConfiguration config) {
if (config == null || config instanceof Scope || ! ProcessUtil.isSynFree()) {
return null;
}
IConfigurationManager configMgr = LibraryService.getInstance().getConfigurationManager(config);
return configMgr == null ? null : configMgr.getRealizationManager();
}
private void handleConfigOrPersepctiveChange() {
loadForBrowsingNeeded = true;
}
}