Skip to main content
summaryrefslogtreecommitdiffstats
blob: 08128d337904e00440f8f184e41af8a336f8ce16 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
/*******************************************************************************
 * Copyright (c) 2011, 2012 Red Hat, Inc.
 *  All rights reserved.
 * This program is 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:
 * Red Hat, Inc. - initial API and implementation
 *
 * @author Bob Brodt
 ******************************************************************************/
package org.eclipse.bpmn2.modeler.ui.property;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.eclipse.bpmn2.modeler.core.runtime.Bpmn2SectionDescriptor;
import org.eclipse.bpmn2.modeler.core.runtime.PropertyTabDescriptor;
import org.eclipse.bpmn2.modeler.core.runtime.TargetRuntime;
import org.eclipse.bpmn2.modeler.core.utils.BusinessObjectUtil;
import org.eclipse.bpmn2.modeler.ui.editor.BPMN2Editor;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.views.properties.tabbed.ITabDescriptor;
import org.eclipse.ui.views.properties.tabbed.ITabDescriptorProvider;

public class PropertyTabDescriptorProvider implements ITabDescriptorProvider {

	// This map caches the Tab Descriptor List. A Tab Descriptor List is built for each EObject and then
	// cached in this map. It is the BPMN2 Editor's responsibility to remove these items from the map
	// when it is disposed().
	// @see PropertyTabDescriptorProvider#disposeTabDescriptors(Resource)
	Hashtable <EObject, TabDescriptorList> tabDescriptorListMap = new Hashtable <EObject, TabDescriptorList>();
	
	public PropertyTabDescriptorProvider() {
		super();
	}

	@SuppressWarnings("unchecked")
	@Override
	public ITabDescriptor[] getTabDescriptors(IWorkbenchPart part, ISelection selection) {
		
		// is the Tab Descriptor List already in our cache?
		TabDescriptorList tabDescriptorList = null;
		EObject businessObject = BusinessObjectUtil.getBusinessObjectForSelection(selection);
		if (businessObject!=null) {
			tabDescriptorList = tabDescriptorListMap.get(businessObject);
			if (tabDescriptorList!=null) {
				// Yes! return it.
				return tabDescriptorList.toArray();
			}
		}
		
		// No, we need build the list: get the Target Runtime <propertyTab> contributions
		// and merge with the Default Runtime Tab Descriptors
		TargetRuntime rt = TargetRuntime.getDefaultRuntime();
		Object bpmn2Editor = part.getAdapter(BPMN2Editor.class);
		if (bpmn2Editor instanceof BPMN2Editor) {
			rt = ((BPMN2Editor)bpmn2Editor).getTargetRuntime(this);
		}
		
		List<PropertyTabDescriptor> desc = null;
		if (rt!=TargetRuntime.getDefaultRuntime()) {
			desc = TargetRuntime.getDefaultRuntime().buildPropertyTabDescriptors();
			desc.addAll(rt.buildPropertyTabDescriptors());
		}
		else
			desc = rt.buildPropertyTabDescriptors();
		
		// do tab replacement
		ArrayList<PropertyTabDescriptor> replaced = new ArrayList<PropertyTabDescriptor>();
		for (PropertyTabDescriptor d : desc) {
			String replacedId = d.getReplaceTab();
			if (replacedId!=null) {
				String[] replacements = replacedId.split(" "); //$NON-NLS-1$
				// tab replacement is only done if the replacement tab has section descriptors
				// that want the replacement to happen.
				for (String id : replacements) {
					for (Bpmn2SectionDescriptor s : (List<Bpmn2SectionDescriptor>) d.getSectionDescriptors()) {
//						if (s.appliesTo(part, selection)) 
						{
							// ask the section if it wants to replace this tab
							if (s.doReplaceTab(id, part, selection)) {
								// replace the tab whose ID is specified as "replaceTab" in this tab.
								PropertyTabDescriptor replacedTab = TargetRuntime.findPropertyTabDescriptor(id);
								if (replacedTab!=null) {
									replaced.add(replacedTab);
									int i = desc.indexOf(replacedTab);
									if (i>=0) {
										desc.set(i, d);
									}
								}
							}
						}
					}
				}
			}
		}
		if (replaced.size()>0)
			desc.removeAll(replaced);

		for (int i=desc.size()-1; i>=0; --i) {
			PropertyTabDescriptor d = desc.get(i);
			for (int j=i-1; j>=0; --j) {
				if (desc.get(j)==d) {
					desc.remove(i);
					break;
				}
			}
		}
		
		// remove empty tabs
		// also move the advanced tab to end of list
		ArrayList<PropertyTabDescriptor> emptyTabs = new ArrayList<PropertyTabDescriptor>();
		PropertyTabDescriptor advancedPropertyTab = null;
		for (PropertyTabDescriptor d : desc) {
			boolean empty = true;
			for (Bpmn2SectionDescriptor s : (List<Bpmn2SectionDescriptor>) d.getSectionDescriptors()) {
				if (s.appliesTo(part, selection)) {
					empty = false;
				}
				if (s.getSectionClass() instanceof AdvancedPropertySection) {
					advancedPropertyTab = d;
				}
			}
			if (empty) {
				emptyTabs.add(d);
			}
		}
		
		if (emptyTabs.size()>0)
			desc.removeAll(emptyTabs);
		
		if (advancedPropertyTab!=null) {
			if (desc.remove(advancedPropertyTab))
				desc.add(advancedPropertyTab);
		}
		
		// make copies of all tab descriptors to prevent cross-talk between editors
		replaced.clear(); // we'll just reuse an ArrayList from before...
		for (PropertyTabDescriptor td : desc) {
			// Note that the copy() makes the Tab Descriptor IDs and Section IDs unique.
			// This is important because the TabbedPropertySheetPage uses these IDs to
			// look up the Sections.
			String rtid = td.getRuntimeId();
			if (rtid==null || rtid.equals(TargetRuntime.DEFAULT_RUNTIME_ID) || rt.getId().equals(rtid)) {
				if (td.getConfigFile()!=null && !rt.getId().equals(rtid))
					// don't include Default Runtime tabs that were defined in a config file
					// if this isn't the Default Runtime.
					continue;
				// what's left is just the Tab Descriptors defined by the current Target Runtime
				// and the ones from the Default ("None") runtime.
				replaced.add(td.copy());
			}
		}
		
		// save this in the cache.
		if (businessObject!=null) {
			tabDescriptorList = new TabDescriptorList();
			tabDescriptorList.addAll(replaced);
			tabDescriptorListMap.put(businessObject, tabDescriptorList);
			return tabDescriptorList.toArray();
		}
		
		return replaced.toArray(new ITabDescriptor[replaced.size()]);
	}

	/**
	 * This should be called by the editor during dispose() to remove all the items
	 * from the cache.
	 *  
	 * @param resource - the EMF Resource containing the EObjects for which
	 *        Property Tab Descriptors were built.
	 */
	public void disposeTabDescriptors(Resource resource) {
		if (resource!=null) {
			TreeIterator<EObject> iter = resource.getAllContents();
			while (iter.hasNext()) {
				EObject object = iter.next();
				tabDescriptorListMap.remove(object);
			}
		}
	}
}

Back to the top