blob: 33a1011b0fffe31fc42dee41c436b02b463f07de [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.publishing.services;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ITreeItemContentProvider;
import org.eclipse.epf.common.utils.FileUtil;
import org.eclipse.epf.common.utils.StrUtil;
import org.eclipse.epf.common.utils.Timer;
import org.eclipse.epf.library.configuration.ConfigurationFilter;
import org.eclipse.epf.library.configuration.ConfigurationHelper;
import org.eclipse.epf.library.edit.IFilter;
import org.eclipse.epf.library.edit.TngAdapterFactory;
import org.eclipse.epf.library.edit.process.IBSItemProvider;
import org.eclipse.epf.library.edit.util.ProcessUtil;
import org.eclipse.epf.library.edit.util.Suppression;
import org.eclipse.epf.library.layout.HtmlBuilder;
import org.eclipse.epf.library.layout.IElementLayout;
import org.eclipse.epf.library.layout.elements.ActivityLayout;
import org.eclipse.epf.library.layout.elements.ProcessElementItem;
import org.eclipse.epf.library.layout.elements.ProcessLayoutData;
import org.eclipse.epf.library.layout.elements.SummaryPageLayout;
import org.eclipse.epf.library.layout.util.XmlElement;
import org.eclipse.epf.library.util.LibraryUtil;
import org.eclipse.epf.publishing.PublishingResources;
import org.eclipse.epf.publishing.layout.Bookmark;
import org.eclipse.epf.publishing.util.PublishingUtil;
import org.eclipse.epf.uma.Activity;
import org.eclipse.epf.uma.Artifact;
import org.eclipse.epf.uma.ContentCategory;
import org.eclipse.epf.uma.DeliveryProcess;
import org.eclipse.epf.uma.Discipline;
import org.eclipse.epf.uma.Guidance;
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.ProcessElement;
import org.eclipse.epf.uma.Role;
import org.eclipse.epf.uma.Task;
import org.eclipse.epf.uma.Tool;
import org.eclipse.epf.uma.UmaPackage;
import org.eclipse.epf.uma.WorkProduct;
import org.eclipse.epf.uma.util.AssociationHelper;
/**
* @author Shilpa Toraskar
* @author Jinhua Xi
* @since 1.0
*/
public class ConfigurationViewBuilder extends AbstractViewBuilder {
private static final String PREFIX_Reference_Workflows = "Reference_Workflows"; //$NON-NLS-1$
private static final String PREFIX_Tasks = "Tasks"; //$NON-NLS-1$
private static final String PREFIX_ResponsibleFor_Tasks = "Primarily_Performs"; //$NON-NLS-1$
private static final String PREFIX_ParticipatesIn_Tasks = "Additionally_Performs"; //$NON-NLS-1$
private static final String PREFIX_Performing_Roles = "Performing_Roles"; //$NON-NLS-1$
private static final String PREFIX_Input_Work_Products = "Input_Work_Products"; //$NON-NLS-1$
private static final String PREFIX_Output_Work_Products = "Output_Work_Products"; //$NON-NLS-1$
private static final String PREFIX_Work_Products_Created = "Responsible_For"; //$NON-NLS-1$
private static final String PREFIX_Work_Products_Modified = "Modifies"; //$NON-NLS-1$
private static final String PREFIX_Responsible_Role = "Responsible_Role"; //$NON-NLS-1$
private static final String PREFIX_Containing_Work_Product = "Containing_Work_Product"; //$NON-NLS-1$
private static final String PREFIX_Contained_Work_Products = "Contained_Work_Products"; //$NON-NLS-1$
private static final String PREFIX_Guidances = "Guidance"; //$NON-NLS-1$
private static final String PREFIX_InputTo_Task = "Input_to"; //$NON-NLS-1$
private static final String PREFIX_OutputOf_Task = "Output_from"; //$NON-NLS-1$
private static final String ICON_FOLDER = DefaultNodeIconResources
.getIconName("folder"); //$NON-NLS-1$
private static final String NODE_Reference_Workflows = PublishingResources.referenceWorkflowsNode_text; //$NON-NLS-1$
private static final String NODE_Tasks = PublishingResources.taskNode_text; //$NON-NLS-1$
private static final String NODE_ResponsibleFor_Tasks = PublishingResources.primarilyPerformsNode_text; //$NON-NLS-1$
private static final String NODE_ParticipatesIn_Tasks = PublishingResources.additionallyPerformsNode_text; //$NON-NLS-1$
private static final String NODE_Performing_Roles = PublishingResources.performingRolesNode_text; //$NON-NLS-1$
private static final String NODE_Input_Work_Products = PublishingResources.inputWorkProductsNode_text; //$NON-NLS-1$
private static final String NODE_Output_Work_Products = PublishingResources.outputWorkProductsNode_text; //$NON-NLS-1$
private static final String NODE_Work_Products_Created = PublishingResources.responsibleForNode_text; //$NON-NLS-1$
private static final String NODE_Work_Products_Modified = PublishingResources.modifiesNode_text; //$NON-NLS-1$
private static final String NODE_Responsible_Role = PublishingResources.responsibleRoleNode_text; //$NON-NLS-1$
private static final String NODE_Containing_Work_Product = PublishingResources.containingWorkProductNode_text; //$NON-NLS-1$
private static final String NODE_Contained_Work_Products = PublishingResources.containedWorkProductsNode_text; //$NON-NLS-1$
private static final String NODE_Guidances = PublishingResources.guidanceNode_text; //$NON-NLS-1$
private static final String NODE_InputTo_Task = PublishingResources.inputToNode_text; //$NON-NLS-1$
private static final String NODE_OutputOf_Task = PublishingResources.outputFromNode_text; //$NON-NLS-1$
private static final String PROCESS_LAYOUT_DATA_FILE = "/scripts/processElementData.js";
// MethodConfiguration config;
List bookmarks = new ArrayList();
AdapterFactory adapterFactory;
private static final Class ITreeItemContentProviderClass = ITreeItemContentProvider.class;
protected IProgressMonitor monitor = null;
protected EObjectComparator nameComparator = new EObjectComparator();
/**
* constructor
*
* @param builder HtmlBuilder
* @param options PublishOptions
*/
public ConfigurationViewBuilder(ISiteGenerator siteGenerator) {
super(siteGenerator);
}
/**
* build the views defined in the configuration and publish the related contents
*
* @param monitor IProgressMonitor
* @return List a list of Bookmarks for the views
*/
public List buildViews(IProgressMonitor monitor)
{
this.monitor = monitor;
// System.out.println("Building views..."); //$NON-NLS-1$
if (config != null)
{
// first of all, we need to load the libray,
// otherwise, some relationships and opposite features are not
// established
monitor.subTask(PublishingResources.loadLibraryTask_name);
LibraryUtil.loadAll((MethodLibrary)config.eContainer());
IFilter configFilter = new ConfigurationFilter(config, null);
adapterFactory = TngAdapterFactory.INSTANCE.getConfigurationView_AdapterFactory(configFilter);
if ( options != null && options.isPublishProcess() )
{
makeProcessClosure();
}
// publish all the views in the configuration
List views = config.getProcessViews();
for ( Iterator it = views.iterator(); it.hasNext(); )
{
if ( monitor.isCanceled() )
{
return null;
}
ContentCategory v = (ContentCategory)it.next();
if ( !ConfigurationHelper.canShow(v, config) )
{
continue;
}
Object element = LibraryUtil.unwrap(v);
Bookmark b = createBookmark(this.monitor, element);
if ( v == config.getDefaultView() )
{
super.defaultView = b;
}
// iterate thru configuration to build the view
iterate(v, b);
if ( b.getChildCount() > 0 )
{
bookmarks.add(b);
}
}
if ( monitor.isCanceled() )
{
return null;
}
}
publishReferenceElements();
// copyIconsForNonApplet();
if ( monitor.isCanceled() )
{
return null;
}
// save published element urls
saveElementUrls();
return bookmarks;
}
/**
* The process element closure is generated as follows:
*
* 1. publish the selected processses, which brings in all the related process elements
* 2. publish all the referenced process elements from step 1, this brings in all the directly referenced content elements.
* make a first level closure to include the published elements and the referenced elements.
* Any direct references to any type of guidances are also in this closure.
* 3. publish all the referened non-ContentCategory content elements from step 2. based on the first level closure.
* The purpose of the first level closure is to allow bring in guidances with valid element link
* and any other references such as a Task or Role, being linked with a missing element link.
* This again brings in all the direct references
* 4. Make the final closure by including the following elements:
* a. all published elements from step 1,2,3.
* b. all referenced Guidances from step 3
* c. all Guidances of type Practice, RoadMap, Suporting Material, and Term Definition, in the configuration
* d. all Content Categories that contains at least one element of type a, b, or c. and their parent categories
*
* The selected view is published based on the element closure defined above.
*/
private void makeProcessClosure() {
monitor.subTask(PublishingResources.buildingProcessClosureTask_name);
// publish the selected processes
// need to build a closure of all the elements involved in the
// processes
List processes = options.getDeliverProcessList();
if ( processes != null && processes.size() > 0 ) {
for (Iterator it = processes.iterator(); it.hasNext(); ) {
makeProcessClosure( (org.eclipse.epf.uma.Process)it.next());
if (monitor.isCanceled()) {
return;
}
}
}
// make the first level closure to include all the process elements and it's referenced elements
// any thing except Guidances and ContentCategories outside the closure is filtered
getValidator().addClosureElements(getValidator().getPublishedElements());
getValidator().addClosureElements(getValidator().getReferencedElements());
// now publish all referenced elements, any direct references in the process elements are
// part of the closure
// don't publish content categories for now since they might be empty and discarded later
List refs = new ArrayList(getValidator().getReferencedElements());
for (Iterator it = refs.iterator(); it.hasNext(); ) {
MethodElement e = (MethodElement)it.next();
if ( !(e instanceof ContentCategory) ) {
super.publish(monitor, e);
// collect process specific layout info with suppression status
// this will incldue the diagrams and the supression states of
// each item under the current procee
if ( LibraryUtil.isProcess(e)) {
publishProcessLayout((org.eclipse.epf.uma.Process) e);
}
}
}
// now, any referenced guidance should be in the closure,
// so include them and make the final closure
refs.clear();
for (Iterator it = getValidator().getReferencedElements().iterator(); it.hasNext(); ) {
MethodElement e = (MethodElement)it.next();
if ( e instanceof Guidance ) {
refs.add(e);
}
}
if ( refs.size() > 0 ) {
getValidator().addClosureElements(refs);
}
// now all the published elements are the element closure, make the final closure
getValidator().makeElementClosure();
}
private void makeProcessClosure(org.eclipse.epf.uma.Process proc) {
if ( proc == null ) {
return;
}
if ( ConfigurationHelper.canShow(proc, config) )
{
ActivityLayout l = new ActivityLayout();
l.init(getLayoutMgr(), proc, proc, null);
l.findAllLinkedElements();
}
if (monitor.isCanceled()) {
return;
}
if ( ConfigurationHelper.isExtender(proc) ) {
org.eclipse.epf.uma.Process baseProc = (org.eclipse.epf.uma.Process)
proc.getVariabilityBasedOnElement();
if ( ConfigurationHelper.inConfig(baseProc, config) ) {
makeProcessClosure(baseProc);
}
}
}
private void publishReferenceElements() {
// now process the referenced elements and publish the contents
while (getValidator().getReferencedElements().size() > 0) {
MethodElement e = (MethodElement) getValidator()
.getReferencedElements().remove(0);
try {
if (monitor.isCanceled()) {
return;
}
// references to method plugins and method packages can be
// ignored
if (e instanceof MethodPlugin || e instanceof MethodPackage) {
continue;
}
super.publish(monitor, e);
// collect process specific layout info with suppression status
// this will incldue the diagrams and the supression states of
// each item under the current procee
if ( LibraryUtil.isProcess(e)) {
publishProcessLayout((org.eclipse.epf.uma.Process) e);
}
} catch (Exception ex) {
ex.printStackTrace();
getValidator().logError(e, "Error publishing element", ex); //$NON-NLS-1$
}
}
}
private void publishProcessLayout(final org.eclipse.epf.uma.Process e) {
Runnable runnable = new Runnable() {
public void run() {
try {
ActivityLayout layout = new ActivityLayout();
layout.init(getLayoutMgr(), (org.eclipse.epf.uma.Process) e, null,
null);
ProcessLayoutData pd = new ProcessLayoutData(e.getGuid());
layout.loadLayoutData(pd);
printLayoutScript(pd);
} catch (Exception e1) {
getValidator()
.logError(
e,
"Error publishing process specific layout data", e1); //$NON-NLS-1$
}
}
};
Timer timer = new Timer();
try {
// run the publishing and check the time, if timeout, terminate it
Thread t = new Thread(runnable);
t.start();
t.join(timeout_millis);
if (t.isAlive()) {
// wait for the thread to die and log an error
timer.stop();
getValidator()
.logInfo(
e,
"publishing process specific layout data takes " + timer.getTime() + " mini seconds already and is still not done yet ..."); //$NON-NLS-1$ //$NON-NLS-2$
timer.start();
t.join();
}
} catch (InterruptedException e1) {
e1.printStackTrace();
} finally {
timer.stop();
getValidator()
.logInfo(
e,
timer.getTotalTime()
+ " mini seconds publishing process specific layout data"); //$NON-NLS-1$
}
}
private void printLayoutScript(ProcessLayoutData data) {
File outputFile = new File(getLayoutMgr().getPublishDir(),
PROCESS_LAYOUT_DATA_FILE); //$NON-NLS-1$
PrintWriter pw = null;
try {
// create a stream with append enabled
FileOutputStream os = new FileOutputStream(outputFile, true);
// create a write with utf-8 encoding
OutputStreamWriter writer = new OutputStreamWriter(os, "utf-8"); //$NON-NLS-1$
// create a print writer with auto flush
pw = new PrintWriter(writer, true);
data.print(pw);
} catch (Exception e) {
getValidator()
.logError("unable to save process layout data", e); //$NON-NLS-1$
} finally {
if (pw != null) {
pw.flush();
pw.close();
}
}
}
/**
* Iterate thru tuee
*
* @param obj
* @param parent
*/
private void iterate(Object obj, Bookmark parent) {
try {
if (monitor.isCanceled()) {
return;
}
// Get the adapter from the factory.
ITreeItemContentProvider treeItemContentProvider = null;
if (obj instanceof ITreeItemContentProvider) {
treeItemContentProvider = (ITreeItemContentProvider) obj;
} else {
treeItemContentProvider = (ITreeItemContentProvider) adapterFactory
.adapt(obj, ITreeItemContentProvider.class);
}
// Either delegate the call or return nothing.
if (treeItemContentProvider != null) {
Collection items = treeItemContentProvider.getChildren(obj);
for (Iterator it = items.iterator(); it.hasNext();) {
if (monitor.isCanceled()) {
return;
}
// create bookmark
Object itorObj = it.next();
Object element = LibraryUtil.unwrap(itorObj);
if ((element instanceof MethodElement)) {
MethodElement me = (MethodElement) element;
try {
if (ConfigurationHelper.canShow(me, config)) {
me = ConfigurationHelper
.getCalculatedElement(me,
getLayoutMgr()
.getElementRealizer());
if (me != null) {
if (me instanceof Tool) {
buildToolSubTree((Tool) me, parent);
} else if (me instanceof Discipline) {
buildDisciplineSubTree((Discipline) me,
parent);
}
// else if (me instanceof DisciplineGrouping
// || me instanceof Domain || me instanceof
// WorkProductType
// || me instanceof RoleSetGrouping || me
// instanceof RoleSet )
else if (me instanceof ContentCategory) {
ContentCategory cc = (ContentCategory)me;
// if the content category is empty,
// don't add to the parent
Bookmark b = createBookmark(
this.monitor, cc);
iterate(itorObj, b);
if ( options.includeEmptyCategories ||
b.getChildCount() > 0) {
parent.addChild(b);
discardEmptyCategory(cc, false);
} else {
discardEmptyCategory(cc, true);
}
} else {
Bookmark b = createBookmark(me, parent);
if (!buildSubTree(itorObj, me, b)) {
iterate(itorObj, b);
}
}
}
}
} catch (Exception e) {
String message = "Error building navigation tree for " + LibraryUtil.getTypeName(me); //$NON-NLS-1$
getHtmlBuilder().getValidator().logError(message, e);
e.printStackTrace();
}
} else {
iterate(itorObj, parent);
}
}
}
} catch (Exception e) {
String message = "Error building navigation tree"; //$NON-NLS-1$
getHtmlBuilder().getValidator().logError(message, e);
e.printStackTrace();
}
}
/**
* create a bookmark under the specified parent. If no parent is specified,
*
* @param monitor
* @param element
* @param parent
* @return
*/
protected Bookmark createBookmark(Object element, Bookmark parent) {
Bookmark b = createBookmark(this.monitor, element);
if (parent == null) {
bookmarks.add(b);
} else {
parent.addChild(b);
}
return b;
}
/**
* build the sub tree for the given element. return true if the element is
* handled, false otherwise
*
* @param element
* @param bm
* @return boolean
*/
private boolean buildSubTree(Object obj, MethodElement element, Bookmark bm) {
if (element instanceof Task) {
buildTaskSubTree((Task) element, bm);
} else if (element instanceof Role) {
buildRoleSubTree((Role) element, bm);
} else if (element instanceof WorkProduct) {
buildWorkProductSubTree((WorkProduct) element, bm);
} else if ( LibraryUtil.isProcess(element)) {
buildProcessSubTree(obj, (org.eclipse.epf.uma.Process) element, bm);
} else {
// System.out.println("Not handled: " + element);
return false;
}
return true;
}
private void buildItems(List elements, Bookmark bm) {
buildItems(elements, bm, false);
}
private void buildItems(List elements, Bookmark bm, boolean buildSubTree) {
for (Iterator it = elements.iterator(); it.hasNext();) {
if (monitor.isCanceled()) {
return;
}
MethodElement element = (MethodElement)it.next();
// filter away the containment child-element if any of the parent(s) are in the list
// 00384619 - Published site: Display of WPs under responsible role
// if the container of the element is in the list, ignore it
if (ConfigurationHelper.isContainmentElement(element) &&
ConfigurationHelper.isContainerInList(element, elements, config)) {
continue;
}
buildItem(element, bm, buildSubTree);
}
}
private Bookmark buildItem(MethodElement element, Bookmark parent,
boolean buildSubTree) {
if (monitor.isCanceled()) {
return null;
}
Bookmark b = null;
// make sure the element is showable
MethodElement e = ConfigurationHelper.getCalculatedElement(element,
getLayoutMgr().getElementRealizer());
if (canShow(e)) {
b = createBookmark(this.monitor, e);
if (b == null) {
return b;
}
parent.addChild(b);
if (buildSubTree) {
if (e instanceof Artifact) {
buildContainedArtifactsSubTree((Artifact) e, b, true);
}
}
}
return b;
}
/**
* create the folder bookmark and it's children. generate the folder summary
* page
*
* @param element
* @param bm
* @param nodeName
* @param items
*/
private Bookmark createFolderBookmark(MethodElement element, Bookmark bm,
String nodeName, List items, boolean createChildren) {
Bookmark b = null;
if (items.size() > 0) {
IElementLayout l = new SummaryPageLayout(
getHtmlBuilder().getLayoutManager(), element, nodeName, items);
String url = l.getUrl();
getHtmlBuilder().generateHtml(l);
b = createBookmark(nodeName, nodeName, url, ICON_FOLDER,
ICON_FOLDER);
bm.addChild(b);
if (createChildren) {
buildItems(items, b);
}
}
return b;
}
private Bookmark createFolderBookmark(MethodElement element, Bookmark bm,
String prefixName, String nodeName, List items,
boolean createChildren) {
Bookmark b = null;
if (items.size() > 0) {
IElementLayout l = new SummaryPageLayout(
getHtmlBuilder().getLayoutManager(), element, prefixName, nodeName,
items);
String url = l.getUrl();
getHtmlBuilder().generateHtml(l);
b = createBookmark(nodeName, nodeName, url, ICON_FOLDER,
ICON_FOLDER);
bm.addChild(b);
if (createChildren) {
buildItems(items, b);
}
}
return b;
}
private Bookmark buildDisciplineSubTree(Discipline element, Bookmark parent) {
String url = ""; //$NON-NLS-1$
Bookmark b;
// need to calculate the realized value of the feature
List items_workflow = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getDiscipline_ReferenceWorkflows());
// Tasks in published site under Disciplines are in
// random order
// use the adaptor factory to get the childrens
// List items_task = ConfigurationHelper.calc0nFeatureValue(element,
// UmaPackage.eINSTANCE.getDiscipline_Tasks(), config);
List items_task = new ArrayList();
List item_subDisciplies = new ArrayList();
ITreeItemContentProvider treeItemContentProvider = (ITreeItemContentProvider) adapterFactory
.adapt(element, ITreeItemContentProvider.class);
if (treeItemContentProvider != null) {
Collection items = treeItemContentProvider.getChildren(element);
for (Iterator it = items.iterator(); it.hasNext();) {
if (monitor.isCanceled()) {
return null;
}
// create bookmark
Object itorObj = it.next();
Object e = LibraryUtil.unwrap(itorObj);
if ((e instanceof Task)) {
MethodElement t = ConfigurationHelper.getCalculatedElement(
(MethodElement) e, getLayoutMgr()
.getElementRealizer());
if ( t != null ) {
items_task.add(t);
}
} else if ( e instanceof Discipline ) {
MethodElement d = ConfigurationHelper.getCalculatedElement(
(MethodElement) e, getLayoutMgr()
.getElementRealizer());
if ( d != null ) {
item_subDisciplies.add(d);
}
}
}
}
if (monitor.isCanceled()) {
return null;
}
// all guidances
List items_guidance = new ArrayList();
items_guidance.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Assets()));
items_guidance.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Checklists()));
items_guidance.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_ConceptsAndPapers()));
items_guidance.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Examples()));
items_guidance.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Guidelines()));
items_guidance.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_SupportingMaterials()));
if (!options.includeEmptyCategories &&
items_workflow.size() + items_task.size() + items_guidance.size()
+ item_subDisciplies.size() == 0) {
// do nothing, don't show the folder
discardEmptyCategory(element, true);
return null;
}
if (monitor.isCanceled()) {
return null;
}
// create the item bookmark
// don't set to the parent yet. make sure it's not empty
// need to check the sub-disciplines
// 150984 - Publishing: Nested discipline is not display in the publish page
//Bookmark bm = createBookmark(element, parent);
Bookmark bm = createBookmark(this.monitor, element);
// sub-disciplines come first
if ( item_subDisciplies.size() > 0 ) {
for (Iterator it = item_subDisciplies.iterator(); it.hasNext(); ) {
Discipline d = (Discipline)it.next();
buildDisciplineSubTree(d, bm);
}
}
if ( options.generateLightWeightTree ) {
Collections.sort(items_workflow, nameComparator);
Collections.sort(items_task, nameComparator);
Collections.sort(items_guidance, nameComparator);
buildItems(items_workflow, bm);
buildItems(items_task, bm);
buildItems(items_guidance, bm);
} else {
if (items_workflow.size() > 0) {
Bookmark wfFolder = createFolderBookmark(element, bm,
PREFIX_Reference_Workflows, NODE_Reference_Workflows,
items_workflow, false);
// Capability Patterns in treebrowser under
// disciplines-reference workflows cannot be expanded
for (Iterator it = items_workflow.iterator(); it.hasNext();) {
if (monitor.isCanceled()) {
return null;
}
org.eclipse.epf.uma.Process proc = (org.eclipse.epf.uma.Process) it.next();
Bookmark bmWorkflow = buildItem(proc, wfFolder, false);
buildProcessSubTree(proc, proc, bmWorkflow);
}
}
if (monitor.isCanceled()) {
return null;
}
if (items_task.size() > 0) {
createFolderBookmark(element, bm, PREFIX_Tasks, NODE_Tasks,
items_task, true);
}
if (monitor.isCanceled()) {
return null;
}
if (items_guidance.size() > 0) {
createFolderBookmark(element, bm, PREFIX_Guidances, NODE_Guidances,
items_guidance, true);
}
}
if (options.includeEmptyCategories || bm.getChildCount() > 0) {
parent.addChild(bm);
discardEmptyCategory(element, false);
} else {
discardEmptyCategory(element, true);
}
return bm;
}
private void buildToolSubTree(Tool element, Bookmark parent) {
if (monitor.isCanceled()) {
return;
}
List items = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getTool_ToolMentors());
if (options.includeEmptyCategories || items.size() > 0) {
Bookmark b = createBookmark(element, parent);
buildItems(items, b);
discardEmptyCategory(element, false);
} else {
discardEmptyCategory(element, true);
}
}
private void buildTaskSubTree(Task element, Bookmark bm) {
String url;
Bookmark b;
List allItems = new ArrayList();
// performing roles
List items = new ArrayList();
Role r = (Role) calc01FeatureValue(element, UmaPackage.eINSTANCE
.getTask_PerformedBy());
if (r != null) {
items.add(r);
}
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getTask_AdditionallyPerformedBy()));
if (items.size() > 0) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, PREFIX_Performing_Roles,
NODE_Performing_Roles, items, true);
}
}
if (monitor.isCanceled()) {
return;
}
if ( !options.generateLightWeightTree ) {
// input work products, need a summary page,
items = new ArrayList();
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getTask_MandatoryInput()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getTask_OptionalInput()));
if (items.size() > 0) {
createFolderBookmark(element, bm, PREFIX_Input_Work_Products,
NODE_Input_Work_Products, items, true);
}
if (monitor.isCanceled()) {
return;
}
}
// output work products, need a summary page, TODO
items = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getTask_Output());
if (items.size() > 0) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, PREFIX_Output_Work_Products,
NODE_Output_Work_Products, items, true);
}
}
if (monitor.isCanceled()) {
return;
}
// all guidances
items.clear();
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Assets()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Checklists()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_ConceptsAndPapers()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Examples()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Guidelines()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_SupportingMaterials()));
// Object e = calc01FeatureValue(element, UmaPackage.eINSTANCE
// .getTask_Estimate());
// if (e != null) {
// items.add(e);
// }
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getTask_ToolMentors()));
if (items.size() > 0) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, PREFIX_Guidances, NODE_Guidances,
items, true);
}
}
if ( options.generateLightWeightTree ) {
buildItems(allItems, bm);
}
}
private void buildRoleSubTree(Role element, Bookmark bm) {
String url;
Bookmark b;
if (monitor.isCanceled()) {
return;
}
List allItems = new ArrayList();
// tasks, // need a general overview page, TODO
// List items = AssociationHelper.getPrimaryTasks(element);
List items = calc0nFeatureValue(element,
AssociationHelper.Role_Primary_Tasks);
if (items.size() > 0 ) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, PREFIX_ResponsibleFor_Tasks,
NODE_ResponsibleFor_Tasks, items, true);
}
}
if (monitor.isCanceled()) {
return;
}
if ( !options.generateLightWeightTree ) {
// secondary tasks
items = calc0nFeatureValue(element,
AssociationHelper.Role_Secondary_Tasks);
if (items.size() > 0) {
createFolderBookmark(element, bm, PREFIX_ParticipatesIn_Tasks,
NODE_ParticipatesIn_Tasks, items, true);
}
}
if (monitor.isCanceled()) {
return;
}
// responsible for work products,
items = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getRole_ResponsibleFor());
if (items.size() > 0 ) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
b = createFolderBookmark(element, bm, PREFIX_Work_Products_Created,
NODE_Work_Products_Created, items, false);
buildItems(items, b, true);
}
}
if (monitor.isCanceled()) {
return;
}
if ( !options.generateLightWeightTree ) {
// modifies work products, need a summary page, TODO
items = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getRole_Modifies());
if (items.size() > 0) {
b = createFolderBookmark(element, bm,
PREFIX_Work_Products_Modified, NODE_Work_Products_Modified,
items, false);
buildItems(items, b, true);
}
if (monitor.isCanceled()) {
return;
}
}
// all guidances
items.clear();
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Assets()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Checklists()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_ConceptsAndPapers()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Examples()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Guidelines()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_SupportingMaterials()));
if (items.size() > 0) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, NODE_Guidances, items, true);
}
}
if ( options.generateLightWeightTree ) {
// light weight tree, no sub folders
buildItems(allItems, bm);
}
}
private void buildWorkProductSubTree(WorkProduct element, Bookmark bm) {
List items;
String url = ""; //$NON-NLS-1$
// Bookmark b;
if (monitor.isCanceled()) {
return;
}
List allItems = new ArrayList();
// performing roles, 0.1 reference element will be realized in buildItem
// multiplicity change for opposite features
// Role r = AssociationHelper.getResponsibleRole(element);
items = calc0nFeatureValue(element, AssociationHelper.WorkProduct_ResponsibleRoles);
if ( items.size() > 0 ) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, PREFIX_Responsible_Role,
NODE_Responsible_Role, items, true);
}
}
if (monitor.isCanceled()) {
return;
}
// containing work products, need a summary page, TODO
if (element instanceof Artifact) {
if ( !options.generateLightWeightTree ) {
WorkProduct wp = ((Artifact) element).getContainerArtifact();
createBookmark(NODE_Containing_Work_Product,
NODE_Containing_Work_Product, url, "", ""); //$NON-NLS-1$ //$NON-NLS-2$
if (wp != null) {
items = new ArrayList();
items.add(wp);
createFolderBookmark(element, bm,
PREFIX_Containing_Work_Product,
NODE_Containing_Work_Product, items, true);
}
if (monitor.isCanceled()) {
return;
}
}
// contained work products, need a summary page, TODO
// items = ((Artifact)element).getContainedArtifacts();
items = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getArtifact_ContainedArtifacts());
// make sure the contained elements does not contain the container,
// this is possible due to realization, say, the containing element
// contribute to the container
items.remove(element);
if (items.size() > 0) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
Bookmark b = createFolderBookmark(element, bm,
PREFIX_Contained_Work_Products,
NODE_Contained_Work_Products, items, false);
// for each contained work product, create the nested sub tree
buildItems(items, b, true);
}
}
}
if (monitor.isCanceled()) {
return;
}
if ( !options.generateLightWeightTree ) {
// input to tasks
items = new ArrayList();
items.addAll(calc0nFeatureValue(element,
AssociationHelper.WorkProduct_MandatoryInputTo_Tasks));
items.addAll(calc0nFeatureValue(element,
AssociationHelper.WorkProduct_OptionalInputTo_Tasks));
if (items.size() > 0) {
createFolderBookmark(element, bm, PREFIX_InputTo_Task,
NODE_InputTo_Task, items, true);
}
if (monitor.isCanceled()) {
return;
}
// output from tasks
items = calc0nFeatureValue(element,
AssociationHelper.WorkProduct_OutputFrom_Tasks);
if (items.size() > 0) {
createFolderBookmark(element, bm, PREFIX_OutputOf_Task,
NODE_OutputOf_Task, items, true);
}
if (monitor.isCanceled()) {
return;
}
}
// all guidances
items = new ArrayList();
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Assets()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Checklists()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_ConceptsAndPapers()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Examples()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Guidelines()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_SupportingMaterials()));
// Object e = calc01FeatureValue(element, UmaPackage.eINSTANCE
// .getWorkProduct_Estimate());
// if (e != null) {
// items.add(e);
// }
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getWorkProduct_Reports()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getWorkProduct_Templates()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getWorkProduct_ToolMentors()));
if (items.size() > 0) {
if ( options.generateLightWeightTree ) {
Collections.sort(items, nameComparator);
allItems.addAll(items);
} else {
createFolderBookmark(element, bm, PREFIX_Guidances, NODE_Guidances,
items, true);
}
}
if ( options.generateLightWeightTree ) {
buildItems(allItems, bm);
}
}
private void buildContainedArtifactsSubTree(Artifact element, Bookmark bm,
boolean showGuidances) {
if (monitor.isCanceled()) {
return;
}
List items;
String url = ""; //$NON-NLS-1$
// contained work products, need a summary page, TODO
// items = ((Artifact)element).getContainedArtifacts();
items = calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getArtifact_ContainedArtifacts());
// make sure the contained elements does not contain the container,
// this is possible due to realization, say, the containing element
// contribute to the container
items.remove(element);
if (monitor.isCanceled()) {
return;
}
if (items.size() > 0) {
// Bookmark b = createFolderBookmark(element, bm,
// NODE_Contained_Work_Products, items, false);
// for each contained work product, create the nested sub tree
for (Iterator it = items.iterator(); it.hasNext();) {
if (monitor.isCanceled()) {
return;
}
Artifact e = (Artifact) it.next();
buildItem(e, bm, true);
}
}
if (!showGuidances) {
return;
}
if (monitor.isCanceled()) {
return;
}
// all guidances
items = new ArrayList();
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Assets()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Checklists()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_ConceptsAndPapers()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Examples()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_Guidelines()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getContentElement_SupportingMaterials()));
// Object e = calc01FeatureValue(element, UmaPackage.eINSTANCE
// .getWorkProduct_Estimate());
// if (e != null) {
// items.add(e);
// }
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getWorkProduct_Reports()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getWorkProduct_Templates()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getWorkProduct_ToolMentors()));
if (items.size() > 0) {
// createFolderBookmark(element, bm, NODE_Guidances, items, true);
buildItems(items, bm);
}
}
/**
* iterate the break down structure and build the xml document
*
* @param parentObj
* The object to iterate. It can be a breakdown element, or it's
* adaptor
* @param parentXml
* @param adapterFactory
*/
private void iterateActivity(ProcessElementItem parentItem,
Bookmark parentBm, ComposedAdapterFactory adapterFactory,
Suppression sup) {
if (monitor.isCanceled()) {
return;
}
ITreeItemContentProvider provider = null;
Object parentObj = parentItem.rawItem;
if (parentObj instanceof ITreeItemContentProvider) {
provider = (ITreeItemContentProvider) parentObj;
} else {
provider = (ITreeItemContentProvider) adapterFactory.adapt(
parentObj, ITreeItemContentProvider.class);
}
if (provider != null) {
// String displayName = ProcessUtil.getAttribute(parentObj,
// IBSItemProvider.COL_PRESENTATION_NAME, provider);
// parentXml.setAttribute("DisplayName", displayName);
Collection children = provider.getChildren(parentObj);
for (Iterator it = children.iterator(); it.hasNext();) {
if (monitor.isCanceled()) {
return;
}
Object rawitem = it.next();
if (sup.isSuppressed(rawitem)) {
continue;
}
MethodElement item = (MethodElement) LibraryUtil
.unwrap(rawitem);
if (!(item instanceof Activity)) {
continue;
}
ProcessElementItem elementItem = new ProcessElementItem(
rawitem, item, parentItem);
Bookmark child = buildItem(elementItem.element, parentBm, false);
if (child != null) {
// set the query string
child.setQueryString(elementItem.getQueryString());
IBSItemProvider adapter = null;
if (rawitem instanceof IBSItemProvider) {
adapter = (IBSItemProvider) rawitem;
} else {
adapter = (IBSItemProvider) adapterFactory.adapt(item,
ITreeItemContentProvider.class);
;
}
String displayName = ProcessUtil.getAttribute(item,
IBSItemProvider.COL_PRESENTATION_NAME, adapter);
child.setPresentationName(displayName);
iterateActivity(elementItem, child, adapterFactory, sup);
}
}
}
}
private void buildProcessSubTree(Object obj, org.eclipse.epf.uma.Process element,
Bookmark bm) {
if (monitor.isCanceled()) {
return;
}
List items = new ArrayList();
ProcessElementItem procItem = new ProcessElementItem(obj, element,
element.getGuid());
ComposedAdapterFactory adapterFactory = super.getLayoutMgr()
.getWBSAdapterFactory();
Suppression sup = new Suppression(element);
iterateActivity(procItem, bm, adapterFactory, sup);
String url;
Bookmark b;
if (monitor.isCanceled()) {
return;
}
// all guidances
items = new ArrayList();
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getActivity_Checklists()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getActivity_Concepts()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getActivity_Examples()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getActivity_Guidelines()));
if (element instanceof DeliveryProcess) {
DeliveryProcess dp = (DeliveryProcess) element;
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getDeliveryProcess_CommunicationsMaterials()));
items.addAll(calc0nFeatureValue(element, UmaPackage.eINSTANCE
.getDeliveryProcess_EducationMaterials()));
}
if (items.size() > 0) {
createFolderBookmark(element, bm, PREFIX_Guidances, NODE_Guidances,
items, true);
}
}
/**
* dispose the object
*/
public void dispose() {
super.dispose();
elementUrls.clear();
}
protected Set elementUrls = new HashSet();
protected void elementPublished(IElementLayout layout, String htmlfile) {
// only for process element for now
// may cover all method elements later
if ( layout.getElement() instanceof ProcessElement ) {
ElementUrl url = new ElementUrl(layout.getElement().getGuid(), layout.getUrl(), layout.getDisplayName() );
elementUrls.add(url);
}
}
private void saveElementUrls() {
// save published element urls
// need to escape the url and text since it will be assigned to a javascript variable as literal
XmlElement xml = new XmlElement("ElementUrls"); //$NON-NLS-1$
for ( Iterator it = elementUrls.iterator(); it.hasNext(); ) {
ElementUrl url = (ElementUrl)it.next();
xml.newChild("elementUrl", url.guid) //$NON-NLS-1$
.setAttribute("text", StrUtil.escape(url.text)) //$NON-NLS-1$
.setAttribute("url", StrUtil.escape(url.url)); //$NON-NLS-1$
}
// StringBuffer buffer = new StringBuffer();
// buffer.append(XmlHelper.XML_HEADER).append(xml.toXml());
// File f = new File(getLayoutMgr().getPublishDir(), "ElementUrls.xml"); //$NON-NLS-1$
// FileUtil.writeUTF8File(f.getAbsolutePath(), buffer.toString());
String html = PublishingUtil.getHtml(xml, "xsl/elementUrls.xsl");
File f = new File(getLayoutMgr().getPublishDir(), PROCESS_LAYOUT_DATA_FILE); //$NON-NLS-1$
FileUtil.writeUTF8File(f.getAbsolutePath(), html, true);
}
/**
* data structure to define url of an element
*
* @author Jinhua Xi
*
*/
public class ElementUrl{
String guid;
String url;
String text;
/**
* constructor
*
* @param guid String the guid of the element
* @param url String the url of the element
* @param text String the text alone with the url
*/
public ElementUrl(String guid, String url, String text) {
this.guid = guid;
this.url = url;
this.text = text;
}
}
class EObjectComparator implements Comparator {
private EStructuralFeature pName = UmaPackage.eINSTANCE.getDescribableElement_PresentationName();
private EStructuralFeature name = UmaPackage.eINSTANCE.getNamedElement_Name();
public EObjectComparator() {
}
public int compare(Object e1, Object e2) {
if ( e1 instanceof EObject && e2 instanceof EObject ) {
Object v1 = getValue(e1);
Object v2 = getValue(e2);
if ( v1 == null && v2 == null ) {
return e1.toString().compareTo(e2.toString());
} else if ( v1 == null ) {
return -1;
} else if ( v2 == null ) {
return 1;
} else {
return v1.toString().compareTo(v2.toString());
}
} else {
return e1.toString().compareTo(e2.toString());
}
}
private Object getValue(Object e) {
Object v = null;
try {
v = ((EObject)e).eGet(pName);
} catch (Exception ex){
};
if ( v == null || v.toString().length() == 0 ) {
try {
v = ((EObject)e).eGet(name);
} catch (Exception ex) {
};
}
return v;
}
}
}