Skip to content

Package: ECPRepositoryManagerImpl$RepositoryParser

ECPRepositoryManagerImpl$RepositoryParser

nameinstructionbranchcomplexitylinemethod
ECPRepositoryManagerImpl.RepositoryParser(ECPRepositoryManagerImpl)
M: 0 C: 9
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 3
100%
M: 0 C: 1
100%
createElement(String, IConfigurationElement)
M: 0 C: 20
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 4
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2012 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: * Eike Stepper - initial API and implementation
13: * Eugen Neufeld - JavaDoc
14: *******************************************************************************/
15:
16: package org.eclipse.emf.ecp.internal.core;
17:
18: import java.io.File;
19: import java.io.FileInputStream;
20: import java.io.IOException;
21: import java.io.InputStream;
22: import java.io.ObjectInput;
23: import java.io.ObjectInputStream;
24: import java.io.ObjectOutput;
25: import java.util.ArrayList;
26: import java.util.Collection;
27: import java.util.Collections;
28: import java.util.HashSet;
29: import java.util.List;
30: import java.util.Map;
31: import java.util.Map.Entry;
32: import java.util.Set;
33:
34: import org.eclipse.core.runtime.IConfigurationElement;
35: import org.eclipse.emf.ecp.core.ECPProvider;
36: import org.eclipse.emf.ecp.core.ECPRepository;
37: import org.eclipse.emf.ecp.core.ECPRepositoryManager;
38: import org.eclipse.emf.ecp.core.util.ECPProperties;
39: import org.eclipse.emf.ecp.core.util.ECPRepositoryAware;
40: import org.eclipse.emf.ecp.core.util.ECPUtil;
41: import org.eclipse.emf.ecp.core.util.observer.ECPObserver;
42: import org.eclipse.emf.ecp.core.util.observer.ECPPropertiesObserver;
43: import org.eclipse.emf.ecp.core.util.observer.ECPProvidersChangedObserver;
44: import org.eclipse.emf.ecp.core.util.observer.ECPRepositoriesChangedObserver;
45: import org.eclipse.emf.ecp.core.util.observer.ECPRepositoryContentChangedObserver;
46: import org.eclipse.emf.ecp.internal.core.util.ExtensionParser;
47: import org.eclipse.emf.ecp.internal.core.util.ExtensionParser.ExtensionDescriptor;
48: import org.eclipse.emf.ecp.internal.core.util.InternalUtil;
49: import org.eclipse.emf.ecp.internal.core.util.Properties;
50: import org.eclipse.emf.ecp.internal.core.util.PropertiesStore;
51: import org.eclipse.emf.ecp.spi.core.InternalProvider;
52: import org.eclipse.emf.ecp.spi.core.InternalProvider.LifecycleEvent;
53: import org.eclipse.emf.ecp.spi.core.InternalRepository;
54: import org.eclipse.net4j.util.AdapterUtil;
55: import org.eclipse.net4j.util.io.IOUtil;
56:
57: /**
58: * This class manages the repositories.
59: *
60: * @author Eike Stepper
61: * @author Eugen Neufeld
62: */
63: public final class ECPRepositoryManagerImpl extends PropertiesStore<InternalRepository, ECPObserver> implements
64:         ECPRepositoryManager, ECPProvidersChangedObserver {
65:
66:         /**
67:          * The file extension that is used for dynamic properties of statically declared repositories.
68:          */
69:         private static final String DYNAMIC_PROPERTIES_EXTENSION = ".dynamic_properties"; //$NON-NLS-1$
70:
71:         private final RepositoryParser extensionParser = new RepositoryParser();
72:
73:         /**
74:          * Should not be called directly, use service instead.
75:          */
76:         public ECPRepositoryManagerImpl() {
77:
78:                 final File stateLocation = Activator.getInstance().getStateLocation().toFile();
79:                 setFolder(new File(stateLocation, "repositories")); //$NON-NLS-1$
80:         }
81:
82:         /** {@inheritDoc} **/
83:         @Override
84:         public InternalRepository getRepository(Object adaptable) {
85:                 if (adaptable instanceof ECPRepositoryAware) {
86:                         final ECPRepositoryAware repositoryAware = (ECPRepositoryAware) adaptable;
87:                         return (InternalRepository) repositoryAware.getRepository();
88:                 }
89:
90:                 return AdapterUtil.adapt(adaptable, InternalRepository.class);
91:         }
92:
93:         /** {@inheritDoc} **/
94:         @Override
95:         public InternalRepository getRepository(String name) {
96:                 return getElement(name);
97:         }
98:
99:         /** {@inheritDoc} **/
100:         @Override
101:         public Collection<ECPRepository> getRepositories() {
102:                 return (Collection) getElements();
103:         }
104:
105:         /**
106:          * Checks whether any repositories are available.
107:          *
108:          * @return true if any repository is available, false otherwise
109:          */
110:         public boolean hasRepositories() {
111:                 return hasElements();
112:         }
113:
114:         /** {@inheritDoc} **/
115:         @Override
116:         public ECPRepository addRepository(ECPProvider provider, String name, String label, String description,
117:                 ECPProperties properties) {
118:                 if (!provider.hasCreateRepositorySupport()) {
119:                         throw new UnsupportedOperationException("The provider " + provider.getLabel() //$NON-NLS-1$
120:                                 + " doesn't support the addition of new repositories."); //$NON-NLS-1$
121:                 }
122:                 final InternalRepository repository = new ECPRepositoryImpl(provider, name, properties);
123:                 repository.setLabel(label);
124:                 repository.setDescription(description);
125:
126:                 ((InternalProvider) provider).handleLifecycle(repository, LifecycleEvent.CREATE);
127:                 changeElements(null, Collections.singleton(repository));
128:                 return repository;
129:         }
130:
131:         /**
132:          * This is called by the {@link ECPRepository} to notificate observers about chnages it its objects.
133:          *
134:          * @param repository the repository where the changes occured
135:          * @param objects the changed objects
136:          */
137:         public void notifyObjectsChanged(ECPRepository repository, Collection<Object> objects) {
138:
139:                 try {
140:                         ECPUtil.getECPObserverBus().notify(ECPRepositoryContentChangedObserver.class)
141:                                 .contentChanged(repository, objects);
142:                 } catch (final Exception ex) {
143:                         Activator.log(ex);
144:                 }
145:         }
146:
147:         /** {@inheritDoc} **/
148:         @Override
149:         public void providersChanged(Collection<ECPProvider> oldProviders, Collection<ECPProvider> newProviders) {
150:                 final Set<ECPProvider> addedProviders = InternalUtil.getAddedElements(oldProviders, newProviders);
151:                 if (!addedProviders.isEmpty()) {
152:                         load();
153:                 }
154:         }
155:
156:         @Override
157:         protected File getFile(InternalRepository element) {
158:                 if (element instanceof RepositoryDescriptor) {
159:                         return new File(getFolder(), element.getName() + DYNAMIC_PROPERTIES_EXTENSION);
160:                 }
161:                 return super.getFile(element);
162:         }
163:
164:         @Override
165:         protected boolean isLoadableElement(File file) {
166:                 return super.isLoadableElement(file) && !file.getName().endsWith(DYNAMIC_PROPERTIES_EXTENSION);
167:         }
168:
169:         @Override
170:         protected InternalRepository loadElement(ObjectInput in) throws IOException {
171:                 return new ECPRepositoryImpl(in);
172:         }
173:
174:         // @Override
175:         // protected InternalRepository[] createElementArray(int size) {
176:         // return new InternalRepository[size];
177:         // }
178:
179:         @Override
180:         protected void notifyObservers(Collection<InternalRepository> oldRepositories,
181:                 Collection<InternalRepository> newRepositories) throws Exception {
182:                 ECPUtil.getECPObserverBus().notify(ECPRepositoriesChangedObserver.class)
183:                         .repositoriesChanged((Collection) oldRepositories, (Collection) newRepositories);
184:         }
185:
186:         @Override
187:         protected void doActivate() throws Exception {
188:                 super.doActivate(); // 1. Load dynamic repositories
189:                 extensionParser.activate(); // 2. Register static repositories
190:                 ECPUtil.getECPObserverBus().register(this);
191:         }
192:
193:         @Override
194:         protected void doDeactivate() throws Exception {
195:                 ECPUtil.getECPObserverBus().unregister(this);
196:                 extensionParser.deactivate();
197:                 super.doDeactivate();
198:         }
199:
200:         /**
201:          * @author Eike Stepper
202:          */
203:         private final class RepositoryParser extends ExtensionParser<InternalRepository> {
204:                 private static final String EXTENSION_POINT_NAME = "repositories"; //$NON-NLS-1$
205:
206:                 RepositoryParser() {
207:                         super(ECPRepositoryManagerImpl.this, Activator.PLUGIN_ID, EXTENSION_POINT_NAME);
208:                 }
209:
210:                 @Override
211:                 protected InternalRepository createElement(String name, IConfigurationElement configurationElement) {
212:                         final RepositoryDescriptor descriptor = new RepositoryDescriptor(name, configurationElement);
213:                         descriptor.setLabel(configurationElement.getDeclaringExtension().getLabel());
214:                         descriptor.setDescription(configurationElement.getAttribute("description")); //$NON-NLS-1$
215:                         return descriptor;
216:                 }
217:         }
218:
219:         /**
220:          * @author Eike Stepper
221:          */
222:         private final class RepositoryDescriptor extends ExtensionDescriptor<InternalRepository> implements
223:                 InternalRepository {
224:                 private final Set<String> declaredPropertyKeys;
225:                 private final ECPProperties properties = new Properties() {
226:                         @Override
227:                         public void addProperty(String key, String value) {
228:                                 excludeDeclaredProperties(key);
229:                                 super.addProperty(key, value);
230:                         }
231:
232:                         @Override
233:                         public void removeProperty(String key) {
234:                                 excludeDeclaredProperties(key);
235:                                 super.removeProperty(key);
236:                         }
237:
238:                         private void excludeDeclaredProperties(String key) {
239:                                 if (declaredPropertyKeys != null && declaredPropertyKeys.contains(key)) {
240:                                         throw new IllegalArgumentException("Statically declared property can not be changed: " + key); //$NON-NLS-1$
241:                                 }
242:                         }
243:
244:                         @Override
245:                         protected Collection<Map.Entry<String, String>> getElementsToWrite() {
246:                                 final List<Map.Entry<String, String>> elementsToWrite = new ArrayList<Map.Entry<String, String>>();
247:                                 for (final Map.Entry<String, String> entry : getElements()) {
248:                                         if (!declaredPropertyKeys.contains(entry.getKey())) {
249:                                                 elementsToWrite.add(entry);
250:                                         }
251:                                 }
252:                                 return elementsToWrite;
253:                         }
254:                 };
255:
256:                 RepositoryDescriptor(String name, IConfigurationElement configurationElement) {
257:                         super(ECPRepositoryManagerImpl.this, name, TYPE, configurationElement);
258:                         for (final IConfigurationElement property : configurationElement.getChildren("property")) { //$NON-NLS-1$
259:                                 final String key = property.getAttribute("key"); //$NON-NLS-1$
260:                                 final String value = property.getAttribute("value"); //$NON-NLS-1$
261:                                 properties.addProperty(key, value);
262:                         }
263:
264:                         declaredPropertyKeys = new HashSet<String>(properties.getKeys());
265:
266:                         InputStream stream = null;
267:
268:                         try {
269:                                 final File file = getFile(this);
270:                                 if (file.exists()) {
271:                                         stream = new FileInputStream(file);
272:                                         final ObjectInputStream in = new ObjectInputStream(stream);
273:
274:                                         final Properties dynamicProperties = new Properties(in);
275:                                         for (final Entry<String, String> property : dynamicProperties.getProperties()) {
276:                                                 properties.addProperty(property.getKey(), property.getValue());
277:                                         }
278:                                 }
279:                         } catch (final IOException ex) {
280:                                 Activator.log(ex);
281:                         } finally {
282:                                 IOUtil.close(stream);
283:                         }
284:
285:                         properties.addObserver(new ECPPropertiesObserver() {
286:                                 @Override
287:                                 public void propertiesChanged(ECPProperties properties,
288:                                         Collection<Entry<String, String>> oldProperties, Collection<Entry<String, String>> newProperties) {
289:                                         ((ECPRepositoryManagerImpl) ECPUtil.getECPRepositoryManager())
290:                                                 .storeElement(RepositoryDescriptor.this);
291:                                 }
292:                         });
293:                 }
294:
295:                 /** {@inheritDoc} */
296:                 @Override
297:                 public boolean isStorable() {
298:                         return true;
299:                 }
300:
301:                 /** {@inheritDoc} */
302:                 @Override
303:                 public void write(ObjectOutput out) throws IOException {
304:                         ((Properties) properties).write(out);
305:                 }
306:
307:                 /** {@inheritDoc} */
308:                 @Override
309:                 public InternalProvider getProvider() {
310:                         final String providerName = getConfigurationElement().getAttribute("provider"); //$NON-NLS-1$
311:                         return (InternalProvider) ECPUtil.getECPProviderRegistry().getProvider(providerName);
312:                 }
313:
314:                 /** {@inheritDoc} */
315:                 @Override
316:                 public ECPProperties getProperties() {
317:                         return properties;
318:                 }
319:
320:                 /** {@inheritDoc} */
321:                 @Override
322:                 public Object getProviderSpecificData() {
323:                         return getResolvedElement().getProviderSpecificData();
324:                 }
325:
326:                 /** {@inheritDoc} */
327:                 @Override
328:                 public void setProviderSpecificData(Object data) {
329:                         getResolvedElement().setProviderSpecificData(data);
330:                 }
331:
332:                 /** {@inheritDoc} */
333:                 @Override
334:                 public boolean canDelete() {
335:                         return false;
336:                 }
337:
338:                 /** {@inheritDoc} */
339:                 @Override
340:                 public void delete() {
341:                         throw new UnsupportedOperationException();
342:                 }
343:
344:                 /** {@inheritDoc} */
345:                 @Override
346:                 public void notifyObjectsChanged(Collection<Object> objects) {
347:                         getResolvedElement().notifyObjectsChanged(objects);
348:                 }
349:
350:                 /** {@inheritDoc} */
351:                 @Override
352:                 protected InternalRepository resolve() throws Exception {
353:                         return new ECPRepositoryImpl(getProvider(), getName(), getProperties());
354:                 }
355:         }
356: }