Skip to content

Package: ViewTemplateProviderImpl$1

ViewTemplateProviderImpl$1

nameinstructionbranchcomplexitylinemethod
compare(VTStyleProperty, VTStyleProperty)
M: 0 C: 26
100%
M: 0 C: 2
100%
M: 0 C: 2
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
{...}
M: 0 C: 9
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: * EclipseSource Munich - initial API and implementation
13: * Lucas Koehler - Refactoring to delegate to customizable suppliers
14: */
15: package org.eclipse.emf.ecp.view.template.service;
16:
17: import java.text.MessageFormat;
18: import java.util.Collection;
19: import java.util.Comparator;
20: import java.util.HashSet;
21: import java.util.LinkedHashMap;
22: import java.util.LinkedHashSet;
23: import java.util.LinkedList;
24: import java.util.List;
25: import java.util.Map;
26: import java.util.Set;
27: import java.util.TreeSet;
28:
29: import org.eclipse.core.runtime.IStatus;
30: import org.eclipse.emf.ecore.EStructuralFeature;
31: import org.eclipse.emf.ecp.spi.view.template.service.ViewTemplateSupplier;
32: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
33: import org.eclipse.emf.ecp.view.spi.model.VElement;
34: import org.eclipse.emf.ecp.view.template.model.VTControlValidationTemplate;
35: import org.eclipse.emf.ecp.view.template.model.VTStyleProperty;
36: import org.eclipse.emf.ecp.view.template.model.VTTemplateFactory;
37: import org.eclipse.emf.ecp.view.template.model.VTViewTemplate;
38: import org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider;
39: import org.eclipse.emf.ecp.view.template.style.validation.model.VTValidationFactory;
40: import org.eclipse.emf.ecp.view.template.style.validation.model.VTValidationStyleProperty;
41: import org.eclipse.emfforms.spi.common.report.AbstractReport;
42: import org.eclipse.emfforms.spi.common.report.ReportService;
43: import org.osgi.service.component.annotations.Component;
44: import org.osgi.service.component.annotations.Reference;
45: import org.osgi.service.component.annotations.ReferenceCardinality;
46: import org.osgi.service.component.annotations.ReferencePolicy;
47:
48: /**
49: * Implementation of the VTViewTemplateProvider. This implementations uses {@link ViewTemplateSupplier} to offer an
50: * extensible mechanism of gathering {@link VTStyleProperty VTStyleProperties} from different sources.
51: *
52: * @author Eugen Neufeld
53: *
54: */
55: @Component(name = "viewTemplate", service = VTViewTemplateProvider.class)
56: public class ViewTemplateProviderImpl implements VTViewTemplateProvider {
57:
58:         private final List<ViewTemplateSupplier> templateSuppliers = new LinkedList<ViewTemplateSupplier>();
59:         private ReportService reportService;
60:
61:         /**
62:          * Adds a {@link ViewTemplateSupplier}.
63:          *
64:          * @param viewTemplateSupplier The {@link ViewTemplateSupplier}
65:          */
66:         @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.STATIC)
67:         void addViewTemplateSupplier(ViewTemplateSupplier viewTemplateSupplier) {
68:                 templateSuppliers.add(viewTemplateSupplier);
69:         }
70:
71:         /**
72:          * Removes a {@link ViewTemplateSupplier}.
73:          *
74:          * @param viewTemplateSupplier The {@link ViewTemplateSupplier}
75:          */
76:         void removeViewTemplateSupplier(ViewTemplateSupplier viewTemplateSupplier) {
77:                 templateSuppliers.remove(viewTemplateSupplier);
78:         }
79:
80:         /**
81:          * Set the {@link ReportService}.
82:          *
83:          * @param reportService The {@link ReportService}
84:          */
85:         @Reference(unbind = "-")
86:         void setReportService(ReportService reportService) {
87:                 this.reportService = reportService;
88:         }
89:
90:         /**
91:          * {@inheritDoc}
92:          * <p>
93:          * This implementation returns a new {@link VTViewTemplate} merged from all view templates known to the
94:          * {@link ViewTemplateSupplier ViewTemplateSuppliers}. If multiple view templates provide a
95:          * {@link VTControlValidationTemplate}, it is not specified which one is used.
96:          *
97:          * @see org.eclipse.emf.ecp.view.template.model.VTViewTemplateProvider#getViewTemplate()
98:          * @return The merged {@link VTViewTemplate} which might be empty but never <code>null</code>.
99:          */
100:         @Deprecated
101:         @Override
102:         public VTViewTemplate getViewTemplate() {
103:                 final VTViewTemplate resultTemplate = VTTemplateFactory.eINSTANCE.createViewTemplate();
104:                 final Set<String> referencedEcores = new HashSet<String>();
105:                 for (final ViewTemplateSupplier supplier : templateSuppliers) {
106:                         for (final VTViewTemplate viewTemplate : supplier.getViewTemplates()) {
107:                                 referencedEcores.addAll(viewTemplate.getReferencedEcores());
108:                                 // last set control validation configuration wins if there are multiple
109:                                 if (viewTemplate.getControlValidationConfiguration() != null) {
110:                                         resultTemplate.setControlValidationConfiguration(viewTemplate.getControlValidationConfiguration());
111:                                 }
112:                                 resultTemplate.getStyles().addAll(viewTemplate.getStyles());
113:                         }
114:                 }
115:                 resultTemplate.getReferencedEcores().addAll(referencedEcores);
116:                 return resultTemplate;
117:         }
118:
119:         @Override
120:         public Set<VTStyleProperty> getStyleProperties(VElement vElement, ViewModelContext viewModelContext) {
121:                 final Map<VTStyleProperty, Double> properties = new LinkedHashMap<VTStyleProperty, Double>();
122:                 for (final ViewTemplateSupplier supplier : templateSuppliers) {
123:                         final Map<VTStyleProperty, Double> supplierProperties = supplier.getStyleProperties(vElement,
124:                                 viewModelContext);
125:                         /*
126:                          * Legacy support: Generate Validation Style Properties for Control Validation Templates and add them with a
127:                          * lower specificity than a View Model Element Selector => If there is any applicable validation style
128:                          * property, it is higher ranked than any legacy one.
129:                          */
130:                         for (final VTStyleProperty generated : generateValidationStyleProperties(supplier.getViewTemplates())) {
131:                                 supplierProperties.put(generated, 1d);
132:                         }
133:
134:                         for (final VTStyleProperty styleProperty : supplierProperties.keySet()) {
135:                                 final double specificity = supplierProperties.get(styleProperty);
136:                                 // a new property -> add it
137:                                 final VTStyleProperty savedStyleProperty = getSavedStyleProperty(styleProperty, properties.keySet());
138:                                 if (savedStyleProperty == null) {
139:                                         reportConflictingProperties(styleProperty, specificity, properties);
140:                                         properties.put(styleProperty, specificity);
141:                                         continue;
142:                                 }
143:                                 // the old property is less specific as the new -> remove it and add the higher rated one
144:                                 if (properties.get(savedStyleProperty) < specificity) {
145:                                         properties.remove(savedStyleProperty);
146:                                         properties.put(styleProperty, specificity);
147:                                 }
148:                         }
149:                 }
150:
151:                 // Returned properties should be ordered by specificity
152:                 final Set<VTStyleProperty> treeSet = new TreeSet<VTStyleProperty>(new Comparator<VTStyleProperty>() {
153:                         @Override
154:                         public int compare(VTStyleProperty o1, VTStyleProperty o2) {
155:                                 final Double specificity1 = properties.get(o1);
156:                                 final Double specificity2 = properties.get(o2);
157:
158:                                 /* higher value comes before lower value */
159:                                 final int result = specificity2.compareTo(specificity1);
160:•                                if (result != 0) {
161:                                         return result;
162:                                 }
163:                                 return o1.toString().compareTo(o2.toString());
164:                         }
165:                 });
166:                 treeSet.addAll(properties.keySet());
167:                 return treeSet;
168:         }
169:
170:         /**
171:          * Generates a {@link VTValidationStyleProperty} for every {@link VTControlValidationTemplate} contained in a given
172:          * {@link VTViewTemplate}. Thereby, all configured validation styles are copied to the newly created style property.
173:          *
174:          * @param viewTemplates The {@link VTViewTemplate VTViewTemplates} potentially containing a
175:          * {@link VTControlValidationTemplate}.
176:          * @return The set of generated {@link VTValidationStyleProperty VTValidationStyleProperties} or an empty set; never
177:          * <code>null</code>
178:          */
179:         @SuppressWarnings("deprecation")
180:         private Set<VTStyleProperty> generateValidationStyleProperties(Collection<VTViewTemplate> viewTemplates) {
181:                 final LinkedHashSet<VTStyleProperty> result = new LinkedHashSet<VTStyleProperty>();
182:                 for (final VTViewTemplate template : viewTemplates) {
183:                         if (template.getControlValidationConfiguration() == null) {
184:                                 continue;
185:                         }
186:                         final VTValidationStyleProperty validationProperty = VTValidationFactory.eINSTANCE
187:                                 .createValidationStyleProperty();
188:                         final VTControlValidationTemplate validationConfig = template.getControlValidationConfiguration();
189:                         // Copy the values of all attributes configuring the validation styling
190:                         for (final EStructuralFeature configFeature : validationConfig.eClass().getEAttributes()) {
191:                                 final EStructuralFeature propertyFeature = validationProperty.eClass()
192:                                         .getEStructuralFeature(configFeature.getName());
193:                                 validationProperty.eSet(propertyFeature, validationConfig.eGet(configFeature));
194:                         }
195:                         result.add(validationProperty);
196:                 }
197:                 return result;
198:         }
199:
200:         /**
201:          * Iterate over all given properties and report a conflict for every style which has the same type and
202:          * specificity but is not equal to the given current style property.
203:          *
204:          * @param property The {@link VTStyleProperty} to report conflicts for
205:          * @param currentSpecificity The specificity of the given style property
206:          * @param properties The map of style properties potentially containing conflicting style properties
207:          */
208:         private void reportConflictingProperties(VTStyleProperty property, double currentSpecificity,
209:                 Map<VTStyleProperty, Double> properties) {
210:                 if (property == null) {
211:                         return;
212:                 }
213:                 if (properties == null) {
214:                         return;
215:                 }
216:                 if (properties.isEmpty()) {
217:                         return;
218:                 }
219:                 for (final VTStyleProperty other : properties.keySet()) {
220:                         if (property.eClass().equals(other.eClass()) && !property.equalStyles(other)
221:                                 && currentSpecificity == properties.get(other).doubleValue()) {
222:                                 reportService.report(new AbstractReport(MessageFormat.format(
223:                                         "The VTStyleProperty '{0}' with specificity {1} is conflicting with property '{2}'. " //$NON-NLS-1$
224:                                                 + "Therefore, it is not determind which of the two properties will be applied.", //$NON-NLS-1$
225:                                         property, currentSpecificity, other), IStatus.WARNING));
226:                         }
227:                 }
228:         }
229:
230:         private VTStyleProperty getSavedStyleProperty(VTStyleProperty style, Set<VTStyleProperty> properties) {
231:                 if (style == null) {
232:                         return null;
233:                 }
234:                 if (properties == null) {
235:                         return null;
236:                 }
237:                 if (properties.isEmpty()) {
238:                         return null;
239:                 }
240:                 for (final VTStyleProperty styleProperty : properties) {
241:                         if (!styleProperty.getClass().equals(style.getClass())) {
242:                                 continue;
243:                         }
244:                         if (styleProperty.equalStyles(style)) {
245:                                 return styleProperty;
246:                         }
247:                 }
248:                 return null;
249:         }
250:
251:         @Deprecated
252:         @Override
253:         public boolean hasControlValidationTemplate() {
254:                 for (final ViewTemplateSupplier supplier : templateSuppliers) {
255:                         for (final VTViewTemplate viewTemplate : supplier.getViewTemplates()) {
256:                                 if (viewTemplate.getControlValidationConfiguration() != null) {
257:                                         return true;
258:                                 }
259:                         }
260:                 }
261:                 return false;
262:         }
263:
264: }