Skip to content

Package: Bazaar$Builder

Bazaar$Builder

nameinstructionbranchcomplexitylinemethod
Bazaar.Builder()
M: 0 C: 13
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
Bazaar.Builder(Collection)
M: 0 C: 18
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
add(Vendor)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
add(Vendor, Vendor, Vendor[])
M: 0 C: 21
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 5
100%
M: 0 C: 1
100%
addAll(Collection)
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
addContextFunction(Class, BazaarContextFunction)
M: 0 C: 6
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
addContextFunction(String, BazaarContextFunction)
M: 0 C: 8
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
build()
M: 0 C: 63
100%
M: 0 C: 8
100%
M: 0 C: 5
100%
M: 0 C: 11
100%
M: 0 C: 1
100%
empty()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
onPriorityOverlap(Bazaar.PriorityOverlapCallBack)
M: 0 C: 13
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 4
100%
M: 0 C: 1
100%
threadSafe()
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
with(Collection)
M: 0 C: 5
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 1
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2018 EclipseSource Muenchen GmbH and others.
3: *
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: * jonas - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emfforms.bazaar;
15:
16: import java.security.AllPermission;
17: import java.util.ArrayList;
18: import java.util.Arrays;
19: import java.util.Collection;
20: import java.util.HashMap;
21: import java.util.List;
22: import java.util.Map;
23:
24: import org.eclipse.emfforms.bazaar.internal.BazaarImpl;
25: import org.eclipse.emfforms.bazaar.internal.ThreadSafeBazaar;
26:
27: /**
28: * A Bazaar is a flexible registry for factories to create specific objects of type T, called "product". To create a
29: * product,
30: * an arbitrary number of {@link Vendor} is queried. {@link Vendor} request certain parameters to create a product.
31: * This is queried from the {@link BazaarContext}. If a {@link AllPermission} parameters requested by a
32: * {@link Vendor} are present in the {@link BazaarContext}, a {@link Vendor} will do a {@link Bid}. The
33: * {@link Vendor} with the highest {@link Bid} will finally create a product.
34: *
35: * If two or more {@link Vendor} do the same bid, the registered {@link PriorityOverlapCallBack} will be notified,
36: * an arbitrary {@link Vendor} with the same {@link Bid} will create the product in this case.
37: *
38: * To transform parameter in the {@link BazaarContext} into parameters {@link Vendor}s expect, you can register
39: * {@link BazaarContextFunction}s at the {@link Bazaar}.
40: *
41: * @param <T> the type of product create by this Bazaar
42: * @author jonas
43: *
44: */
45: public interface Bazaar<T> {
46:
47:         /**
48:          * Adds a {@link Vendor} to the bazaar. Will be queried if a product is requested, the best fitting will create the
49:          * product. Has no effect if the {@code vendor} is already present in this bazaar.
50:          *
51:          * @param vendor the {@link Vendor}
52:          */
53:         void addVendor(Vendor<? extends T> vendor);
54:
55:         /**
56:          * Removes a {@link Vendor} from the bazaar. Has no effect if the {@code vendor} is not present in this bazaar.
57:          *
58:          * @param vendor the {@link Vendor} to remove
59:          */
60:         void removeVendor(Vendor<? extends T> vendor);
61:
62:         /**
63:          * Adds a {@link BazaarContextFunction} to this {@link Bazaar} to exchange existing parameters to a parameter
64:          * requested by a {@link Vendor}.
65:          *
66:          * @param key the key of a requested parameter, which can be exchanged from other available parameters in the
67:          * {@link BazaarContext} by this {@link BazaarContextFunction}
68:          * @param contextFunction the {@link BazaarContextFunction} being able to exchange to the requested parameter
69:          */
70:         void addContextFunction(String key, BazaarContextFunction contextFunction);
71:
72:         /**
73:          * Creates a product of type T, provided by the {@link Vendor} with the highest {@link Bid} and which is statisfied
74:          * by the parameters in the {@link BazaarContext}. In case of tied bids, the {@link PriorityOverlapCallBack}
75:          * if one is set will be notified of which vendor is chosen to break the tie. Note that during the
76:          * bidding process, ties may have to be broken in this way that are later defeated by a higher bid.
77:          *
78:          * @param context the {@link BazaarContext}, which is used to provide requested parameters for {@link Vendor}
79:          * @return the product provided by the best {@link Vendor}
80:          *
81:          * @see #setPriorityOverlapCallBack(PriorityOverlapCallBack)
82:          */
83:         T createProduct(BazaarContext context);
84:
85:         /**
86:          * Creates a list of products of type T, provided by {@link Vendor}s which are statisfied by the parameters in the
87:          * {@link BazaarContext}, ordered by their {@link Bid}. Ties are not broken as all bids are successful
88:          * and are used only for ordering.
89:          *
90:          * @param context the {@link BazaarContext}, which is used to provide requested parameters for {@link Vendor}
91:          * @return a list of products ordered by the highest {@link Bid}
92:          */
93:         List<T> createProducts(BazaarContext context);
94:
95:         /**
96:          * Adds a {@link PriorityOverlapCallBack}, see {@link PriorityOverlapCallBack}.
97:          *
98:          * @param priorityOverlapCallBack a PriorityOverlapCallBack
99:          */
100:         void setPriorityOverlapCallBack(PriorityOverlapCallBack<? super T> priorityOverlapCallBack);
101:
102:         //
103:         // Nested types
104:         //
105:
106:         /**
107:          * If two or more {@link Vendor}s make the same bid, the registered
108:          * {@link org.eclipse.emfforms.bazaar.Bazaar.PriorityOverlapCallBack} will be
109:          * notified,
110:          * an arbitrary {@link Vendor} with the same {@link Bid} will create the product in this case.
111:          *
112:          * @param <T> the type of product create by this Bazaar
113:          * @author jonas
114:          *
115:          */
116:         public interface PriorityOverlapCallBack<T> {
117:                 /**
118:                  * Will be called if two {@link Vendor}s do the same bid.
119:                  *
120:                  * @param winner The {@link Vendor} who will win and create the product
121:                  * @param overlapping Another {@link Vendor} with the same bid, but who will not create the product
122:                  */
123:
124:                 void priorityOverlap(Vendor<? extends T> winner, Vendor<? extends T> overlapping);
125:
126:         }
127:
128:         /**
129:          * A fluent <em>builder</em> of {@link Bazaar}s.
130:          *
131:          * @author Christian W. Damus
132:          *
133:          * @param <T> the type of product provided by the bazaar
134:          */
135:         final class Builder<T> {
136:                 private final List<Vendor<? extends T>> vendors = new ArrayList<Vendor<? extends T>>();
137:                 private final Map<String, BazaarContextFunction> contextFunctions = new HashMap<String, BazaarContextFunction>();
138:                 private PriorityOverlapCallBack<? super T> overlapHandler;
139:                 private boolean isThreadSafe;
140:
141:                 /**
142:                  * Creates a new empty bazaar builder.
143:                  */
144:                 private Builder() {
145:                         super();
146:                 }
147:
148:                 /**
149:                  * Creates a new context builder with the given initial {@code vendors}.
150:                  *
151:                  * @param vendors initial vendors
152:                  */
153:                 private Builder(Collection<? extends Vendor<? extends T>> vendors) {
154:                         super();
155:
156:                         this.vendors.addAll(vendors);
157:                 }
158:
159:                 /**
160:                  * Creates a new empty bazaar builder.
161:                  *
162:                  * @param <T> the type of product provided by the {@link Bazaar}
163:                  * @return an initially empty builder
164:                  */
165:                 public static <T> Builder<T> empty() {
166:                         return new Builder<T>();
167:                 }
168:
169:                 /**
170:                  * Creates a new bazaar builder with the given initial {@code vendors}.
171:                  *
172:                  * @param <T> the type of product provided by the {@link Bazaar}
173:                  *
174:                  * @param vendors initial vendors
175:                  * @return an initialized builder
176:                  */
177:                 public static <T> Builder<T> with(Collection<? extends Vendor<? extends T>> vendors) {
178:                         return new Builder<T>(vendors);
179:                 }
180:
181:                 /**
182:                  * Adds a vendor.
183:                  *
184:                  * @param vendor the vendor to add
185:                  *
186:                  * @return this builder
187:                  */
188:                 public Builder<T> add(Vendor<? extends T> vendor) {
189:                         vendors.add(vendor);
190:                         return this;
191:                 }
192:
193:                 /**
194:                  * Adds vendors.
195:                  *
196:                  * @param vendor1 a vendor to add
197:                  * @param vendor2 another vendor to add
198:                  * @param more optional additional vendors to add
199:                  *
200:                  * @return this builder
201:                  */
202:                 // @SafeVarargs (not available in JDK 1.6)
203:                 public Builder<T> add(Vendor<? extends T> vendor1, Vendor<? extends T> vendor2, Vendor<? extends T>... more) {
204:                         vendors.add(vendor1);
205:                         vendors.add(vendor2);
206:•                        if (more.length > 0) {
207:                                 vendors.addAll(Arrays.asList(more));
208:                         }
209:                         return this;
210:                 }
211:
212:                 /**
213:                  * Adds vendors.
214:                  *
215:                  * @param vendors vendors to add
216:                  *
217:                  * @return this builder
218:                  */
219:                 public Builder<T> addAll(Collection<? extends Vendor<? extends T>> vendors) {
220:                         this.vendors.addAll(vendors);
221:                         return this;
222:                 }
223:
224:                 /**
225:                  * Add a context function.
226:                  *
227:                  * @param type the context value type provided by the function
228:                  * @param contextFunction the context function to add
229:                  * @return this {@link org.eclipse.emfforms.bazaar.Bazaar.Builder}
230:                  */
231:                 public Builder<T> addContextFunction(Class<?> type, BazaarContextFunction contextFunction) {
232:                         return addContextFunction(type.getName(), contextFunction);
233:                 }
234:
235:                 /**
236:                  * Add a context function.
237:                  *
238:                  * @param key the context key for the function
239:                  * @param contextFunction the context function to add
240:                  * @return this {@link org.eclipse.emfforms.bazaar.Bazaar.Builder}
241:                  */
242:                 public Builder<T> addContextFunction(String key, BazaarContextFunction contextFunction) {
243:                         contextFunctions.put(key, contextFunction);
244:                         return this;
245:                 }
246:
247:                 /**
248:                  * Set the handler for priority overlaps. This may only be set once.
249:                  *
250:                  * @param overlapHandler the overlap handler to set
251:                  *
252:                  * @return this builder
253:                  */
254:                 public Builder<T> onPriorityOverlap(PriorityOverlapCallBack<? super T> overlapHandler) {
255:•                        if (this.overlapHandler != null) {
256:                                 throw new IllegalStateException("overlap handler already set"); //$NON-NLS-1$
257:                         }
258:                         this.overlapHandler = overlapHandler;
259:                         return this;
260:                 }
261:
262:                 /**
263:                  * Request that the bazaar be thread-safe. This is useful for bazaars that
264:                  * may be accessed arbitrarily by concurrent threads. By default, the builder
265:                  * creates bazaars that are not thread-safe.
266:                  *
267:                  * @return this builder
268:                  */
269:                 public Builder<T> threadSafe() {
270:                         this.isThreadSafe = true;
271:                         return this;
272:                 }
273:
274:                 /**
275:                  * Create the bazaar. Further updates to the builder will have
276:                  * no effect on the resulting bazaar.
277:                  *
278:                  * @return the bazaar
279:                  */
280:                 public Bazaar<T> build() {
281:                         final Bazaar<T> result;
282:•                        if (isThreadSafe) {
283:                                 result = new ThreadSafeBazaar<T>(vendors, contextFunctions, overlapHandler);
284:                         } else {
285:                                 result = new BazaarImpl<T>();
286:
287:•                                for (final Vendor<? extends T> vendor : vendors) {
288:                                         result.addVendor(vendor);
289:                                 }
290:•                                for (final Map.Entry<String, BazaarContextFunction> entry : contextFunctions.entrySet()) {
291:                                         result.addContextFunction(entry.getKey(), entry.getValue());
292:                                 }
293:•                                if (overlapHandler != null) {
294:                                         result.setPriorityOverlapCallBack(overlapHandler);
295:                                 }
296:                         }
297:
298:                         return result;
299:                 }
300:         }
301:
302: }