Skip to content

Package: PageCandidate

PageCandidate

nameinstructionbranchcomplexitylinemethod
PageCandidate(IConfigurationElement)
M: 42 C: 0
0%
M: 2 C: 0
0%
M: 2 C: 0
0%
M: 10 C: 0
0%
M: 1 C: 0
0%
determineOrder()
M: 33 C: 0
0%
M: 6 C: 0
0%
M: 4 C: 0
0%
M: 6 C: 0
0%
M: 1 C: 0
0%
enqueue(List)
M: 47 C: 0
0%
M: 8 C: 0
0%
M: 5 C: 0
0%
M: 11 C: 0
0%
M: 1 C: 0
0%
getPages(IConfigurationElement[])
M: 46 C: 0
0%
M: 4 C: 0
0%
M: 3 C: 0
0%
M: 9 C: 0
0%
M: 1 C: 0
0%
linkPages()
M: 76 C: 0
0%
M: 12 C: 0
0%
M: 7 C: 0
0%
M: 15 C: 0
0%
M: 1 C: 0
0%
static {...}
M: 5 C: 0
0%
M: 0 C: 0
100%
M: 1 C: 0
0%
M: 1 C: 0
0%
M: 1 C: 0
0%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2008-2011 Chair for Applied Software Engineering,
3: * Technische Universitaet Muenchen.
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: ******************************************************************************/
13: package org.eclipse.emf.ecp.editor.internal.e3;
14:
15: import java.util.LinkedHashMap;
16: import java.util.LinkedList;
17: import java.util.List;
18: import java.util.Map;
19: import java.util.Map.Entry;
20:
21: import org.eclipse.core.runtime.IConfigurationElement;
22:
23: /**
24: * Represents a page candidate to be showsn in meeditor.
25: *
26: * @author helming
27: */
28: public final class PageCandidate {
29:
30:         // By which pages this page is about to be replaced
31:         private final List<PageCandidate> replacedBy = new LinkedList<PageCandidate>();
32:
33:         // Which pages follow after this page
34:         private final List<PageCandidate> successors = new LinkedList<PageCandidate>();
35:
36:         // The wrapped configuration element
37:         private final IConfigurationElement page;
38:
39:         // If this page is already in the resulting list
40:         private boolean enqueued;
41:
42:         // The mapping from name to page candidate to store all candidates
43:         private static Map<String, PageCandidate> candidates = new LinkedHashMap<String, PageCandidate>();
44:
45:         /**
46:          * This method gets an input array of MEEditor pages and performs the tasks "after" and "replace" on them. That
47:          * means, pages replaced by others will be omitted and pages with the after attribute set to a valid page name will
48:          * be sorted so they appear after that page. If a page that has elements "after" it is replaced, the elements will
49:          * instead be after the replacing page.
50:          *
51:          * @param input A list of MEEditor page candidates (directly from reading the extensions for the pages extension
52:          * point)
53:          * @return A properly ordered list of all pages to be added to the MEEditor.
54:          */
55:         public static List<IConfigurationElement> getPages(IConfigurationElement[] input) {
56:
57:                 // Create Page Candidates and store them in the map
58:•                for (final IConfigurationElement i : input) {
59:                         new PageCandidate(i);
60:                 }
61:
62:                 // Link them together (build page Tree)
63:                 linkPages();
64:
65:                 // Determine order
66:                 final List<PageCandidate> orderedPages = determineOrder();
67:
68:                 // The hashmap content is no longer needed
69:                 candidates.clear();
70:
71:                 // Unwrap ordered Pages and return them.
72:                 final List<IConfigurationElement> result = new LinkedList<IConfigurationElement>();
73:•                for (final PageCandidate p : orderedPages) {
74:                         result.add(p.page);
75:                 }
76:
77:                 return result;
78:         }
79:
80:         /**
81:          * Constructor of a page candidate.
82:          *
83:          * @param page the wrapped page
84:          */
85:         private PageCandidate(IConfigurationElement page) {
86:                 super();
87:                 this.page = page;
88:                 final String name = page.getAttribute("name"); //$NON-NLS-1$
89:
90:                 // Entry the page into the candidates map. Log an exception if there are colliding names
91:•                if (candidates.containsKey(name)) {
92:                         Activator.logException(new Exception("Two pages to be added to the MEEditor have the same name (" + name //$NON-NLS-1$
93:                                 + ")! One of them will not be visible.")); //$NON-NLS-1$
94:                 }
95:                 candidates.put(name, this);
96:         }
97:
98:         /**
99:          * This function links the pages by connecting them via the after and replace attributes. After this, the pages are
100:          * linked in a treelike manner which can be used to order them.
101:          */
102:         private static void linkPages() {
103:                 // Build the page tree...
104:•                for (final Entry<String, PageCandidate> curEntry : candidates.entrySet()) {
105:                         final PageCandidate cur = curEntry.getValue();
106:                         // Set replacements if this page has any
107:                         final String r = cur.page.getAttribute("replace"); //$NON-NLS-1$
108:•                        if (r != null) {
109:                                 final String[] replacements = r.split(","); //$NON-NLS-1$
110:
111:                                 // Loop over replacements and set them, if they exist
112:•                                for (final String s : replacements) {
113:                                         final PageCandidate replaced = candidates.get(s.trim());
114:•                                        if (replaced != null) {
115:                                                 // Replaced page does exist, link them
116:                                                 replaced.replacedBy.add(cur);
117:                                         }
118:                                 }
119:                         }
120:
121:                         // Build the after fields
122:                         final String after = cur.page.getAttribute("after"); //$NON-NLS-1$
123:•                        if (after != null) {
124:                                 final PageCandidate before = candidates.get(after);
125:•                                if (before != null) {
126:                                         before.successors.add(cur);
127:                                 }
128:                         }
129:                 }
130:
131:         }
132:
133:         /**
134:          * This function enqueues this page candidate into the List l, unless it is replaced by another page or is already
135:          * in the list.
136:          *
137:          * @param l The list to enqueue this page
138:          */
139:         private void enqueue(List<PageCandidate> l) {
140:
141:                 // Already enqueued? Skip!
142:•                if (enqueued) {
143:                         return;
144:                 }
145:
146:                 // Was this page replaced?
147:•                if (replacedBy.size() != 0) {
148:
149:                         // Enqueue all pages that replaced this page
150:•                        for (final PageCandidate c : replacedBy) {
151:                                 c.enqueue(l);
152:                         }
153:
154:                 } else {
155:                         // This page was not replaced, enqueue it.
156:                         l.add(this);
157:                         enqueued = true;
158:                 }
159:
160:                 // Were some pages tagged "after" this page? Enqueue them!
161:•                for (final PageCandidate c : successors) {
162:                         c.enqueue(l);
163:                 }
164:         }
165:
166:         /**
167:          * This method determines the ordered resulting page list. Replaced pages will be omitted and all other pages will
168:          * be in the desired order
169:          *
170:          * @return A properly ordered list of all non-replaced page candidates.
171:          */
172:         private static List<PageCandidate> determineOrder() {
173:                 final List<PageCandidate> result = new LinkedList<PageCandidate>();
174:
175:                 // Loop over all pages and enqueue pages that are not after a specific page
176:                 // and also do not replace a page. (These pages get enqueued recursively)
177:•                for (final Entry<String, PageCandidate> e : candidates.entrySet()) {
178:                         final PageCandidate p = e.getValue();
179:•                        if (p.successors.size() == 0 && p.replacedBy.size() == 0) {
180:                                 p.enqueue(result);
181:                         }
182:                 }
183:
184:                 return result;
185:         }
186: }