Skip to content

Package: BasicDetailViewCache$Record

BasicDetailViewCache$Record

nameinstructionbranchcomplexitylinemethod
BasicDetailViewCache.Record(BasicDetailViewCache, EClass, ECPSWTView)
M: 0 C: 16
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 6
100%
M: 0 C: 1
100%
contextDisposed(ViewModelContext)
M: 0 C: 11
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
dispose()
M: 0 C: 4
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%
get()
M: 0 C: 3
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-2019 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: * Eugen Neufeld - initial API and implementation
13: * Christian W. Damus - bug 527686
14: ******************************************************************************/
15: package org.eclipse.emf.ecp.view.spi.swt.masterdetail;
16:
17: import java.util.ArrayList;
18: import java.util.LinkedHashMap;
19: import java.util.List;
20: import java.util.Map;
21: import java.util.Optional;
22: import java.util.function.Supplier;
23:
24: import org.eclipse.emf.ecore.EClass;
25: import org.eclipse.emf.ecore.EObject;
26: import org.eclipse.emf.ecp.ui.view.swt.ECPSWTView;
27: import org.eclipse.emf.ecp.view.spi.context.ViewModelContext;
28: import org.eclipse.emf.ecp.view.spi.context.ViewModelContextDisposeListener;
29:
30: /**
31: * A default implementation of the {@link DetailViewCache} that uses the {@link EClass} as the key.
32: *
33: * @since 1.22
34: */
35: public class BasicDetailViewCache implements DetailViewCache {
36:
37:         private final Map<EClass, Record> cache;
38:
39:         /**
40:          * Creates a cache with maximal 5 entries.
41:          */
42:         public BasicDetailViewCache() {
43:                 this(5);
44:         }
45:
46:         /**
47:          * Creates a cache with a custom number of maximal entries.
48:          *
49:          * @param maxEntries The number of maximal entries to cache
50:          */
51:         public BasicDetailViewCache(final int maxEntries) {
52:                 cache = new LinkedHashMap<EClass, Record>(maxEntries + 1, .75F, true) {
53:                         private static final long serialVersionUID = 1L;
54:
55:                         // This method is called just after a new entry has been added
56:                         @Override
57:                         public boolean removeEldestEntry(Map.Entry<EClass, Record> eldest) {
58:                                 final boolean result = size() > maxEntries;
59:                                 if (result) {
60:                                         eldest.getValue().dispose();
61:                                 }
62:                                 return result;
63:                         }
64:                 };
65:         }
66:
67:         @Override
68:         public boolean isCached(EObject selection) {
69:                 return selection != null && cache.containsKey(selection.eClass());
70:         }
71:
72:         @Override
73:         public ECPSWTView getCachedView(EObject selection) {
74:                 return getRecord(selection).map(Supplier::get).orElse(null);
75:         }
76:
77:         private Optional<Record> getRecord(EObject selection) {
78:                 return Optional.ofNullable(selection).map(EObject::eClass).map(cache::get);
79:         }
80:
81:         @Override
82:         public boolean cacheView(ECPSWTView ecpView) {
83:                 // Don't attempt to cache a view already disposed
84:                 if (ecpView == null || ecpView.getSWTControl().isDisposed()) {
85:                         return false;
86:                 }
87:
88:                 final EClass key = ecpView.getViewModelContext().getDomainModel().eClass();
89:                 final Record existing = cache.get(key);
90:
91:                 if (existing == null) {
92:                         // Easy. Add it
93:                         cache.put(key, new Record(key, ecpView));
94:                 } else if (existing.get() != ecpView) {
95:                         // Not the same view. Dispose the old
96:                         existing.dispose();
97:                         cache.put(key, new Record(key, ecpView));
98:                 } // Otherwise we already have cached exactly this view
99:
100:                 return true;
101:         }
102:
103:         @Override
104:         public void clear() {
105:                 final List<Record> records = new ArrayList<>(cache.values());
106:                 cache.clear();
107:                 records.forEach(Record::dispose);
108:         }
109:
110:         //
111:         // Nested types
112:         //
113:
114:         /**
115:          * Self-disposing record of the caching of a rendered view for some {@link EClass}.
116:          * Disposes itself when the view context is disposed.
117:          */
118:         private final class Record implements ViewModelContextDisposeListener, Supplier<ECPSWTView> {
119:
120:                 private final EClass eClass;
121:                 private final ECPSWTView ecpView;
122:
123:                 Record(EClass eClass, ECPSWTView ecpView) {
124:                         super();
125:
126:                         this.eClass = eClass;
127:                         this.ecpView = ecpView;
128:
129:                         ecpView.getViewModelContext().registerDisposeListener(this);
130:                 }
131:
132:                 void dispose() {
133:                         ecpView.dispose();
134:                 }
135:
136:                 @Override
137:                 public ECPSWTView get() {
138:                         return ecpView;
139:                 }
140:
141:                 @Override
142:                 public void contextDisposed(ViewModelContext viewModelContext) {
143:                         dispose();
144:                         cache.remove(eClass, this);
145:                 }
146:         }
147:
148: }