Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 1ec0ea895e9d9a7924f01b28ed446d44cc145102 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*****************************************************************************
 * Copyright (c) 2010, 2016 LIFL, CEA LIST, Christian W. Damus, and others.
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   LIFL - Initial API and implementation
 *   Christian W. Damus - bug 485220
 *   
 *****************************************************************************/
package org.eclipse.papyrus.infra.services.resourceloading;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.papyrus.infra.core.language.ILanguageService;
import org.eclipse.papyrus.infra.core.resource.AbstractBaseModel;
import org.eclipse.papyrus.infra.core.resource.ModelSet;
import org.eclipse.papyrus.infra.core.resource.sasheditor.SashModelUtils;
import org.eclipse.papyrus.infra.core.utils.DiResourceSet;
import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationUtils;
import org.eclipse.papyrus.infra.services.resourceloading.impl.ProxyManager;


/**
 * A {@link ModelSet} allowing to load models on demand.
 * Also, this implementation allows to have loading strategies.
 *
 * TODO extends {@link ModelSet} rather than {@link DiResourceSet}. This can be done once
 * DiResourceSet is not referenced anywhere.
 *
 * @author cedric dumoulin
 * @author emilien perico
 *
 */
public class OnDemandLoadingModelSet extends DiResourceSet {

	/** Set that enables to always load the uri with any strategy. */
	private Set<URI> uriLoading = new HashSet<URI>();

	/**
	 * The proxy manager that loads the model according to a specific strategy.
	 */
	private IProxyManager proxyManager;

	private AbstractBaseModel semanticModel;

	/**
	 *
	 * Constructor.
	 *
	 */
	public OnDemandLoadingModelSet() {
		super();
		// Register declared models
		// The ModelsReader has already been invoked in super()
		// ModelsReader reader = new ModelsReader();
		// reader.readModel(this);
		proxyManager = new ProxyManager(this);
	}



	@Override
	public void unload() {
		super.unload();
		proxyManager.dispose();
		semanticModel = null;
	}



	/**
	 * @see org.eclipse.emf.ecore.resource.impl.ResourceSetImpl#getEObject(org.eclipse.emf.common.util.URI, boolean)
	 */
	@Override
	public EObject getEObject(URI uri, boolean loadOnDemand) {
		// return super.getEObject(uri, loadOnDemand);

		URI resourceURI = uri.trimFragment();
		// for performance reasons, we check the three initial resources first
		if (resourceURI.equals(getSemanticResourceURI()) || resourceURI.equals(NotationUtils.getNotationModel(this).getResourceURI()) || resourceURI.equals(SashModelUtils.getSashModel(this).getResourceURI())
				|| uriLoading.contains(resourceURI)) {
			// do not manage eObject of the current resources
			return super.getEObject(uri, loadOnDemand);
		} else if (loadOnDemand) {
			return proxyManager.getEObjectFromStrategy(uri);
		} else {
			// call super so that the eobject is returned
			// if the resource is already loaded
			return super.getEObject(uri, loadOnDemand);
		}
	}

	/**
	 * Enables to add an URI that will be always loaded.
	 * It is not listening at the current loading strategy and always load the specified URI if needed.
	 *
	 * @param alwaysLoadedUri
	 *            the always loaded uri
	 */
	public void forceUriLoading(URI alwaysLoadedUri) {
		uriLoading.add(alwaysLoadedUri);
	}

	private AbstractBaseModel getSemanticModel() {
		if (semanticModel == null) {
			semanticModel = ILanguageService.getLanguageModels(this).stream()
					.filter(AbstractBaseModel.class::isInstance)
					.map(AbstractBaseModel.class::cast)
					.findAny().orElseGet(DummyModel::new);
		}

		return semanticModel;
	}

	private URI getSemanticResourceURI() {
		AbstractBaseModel model = getSemanticModel();
		return (model == null) ? null : model.getResourceURI();
	}

	//
	// Nested types
	//

	private static class DummyModel extends AbstractBaseModel {
		@Override
		public String getIdentifier() {
			return ""; // Dummy model
		}

		@Override
		protected String getModelFileExtension() {
			return "\0"; // Dummy model
		}
	}
}

Back to the top