summaryrefslogtreecommitdiffstats
blob: 6fe890bbfe32d8a6ca057496d7313a460bcf788b (plain)
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
package org.eclipse.emf.ecore.xcore.resource;

import java.util.Collections;
import java.util.Iterator;

import org.eclipse.emf.codegen.ecore.genmodel.GenBase;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EModelElement;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.ecore.xcore.XPackage;
import org.eclipse.emf.ecore.xcore.scoping.LazyCreationProxyUriConverter;
import org.eclipse.emf.ecore.xcore.util.XcoreEcoreBuilder;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.util.Pair;
import org.eclipse.xtext.xbase.resource.XbaseResource;

import com.google.inject.Inject;

public class XcoreResource extends XbaseResource {
	
	@Inject
	private LazyCreationProxyUriConverter proxyConverter;
	
	@Inject
	private IQualifiedNameProvider nameProvider; 
	
	private boolean fullyInitialized = false;
	
	@Override
	public EList<EObject> getContents() {
		if (!isLoading && !fullyInitialized) {
			try {
				eSetDeliver(false);
				lateInitialize();
				fullyInitialized = true;
			} finally {
				eSetDeliver(true);
			}
		}
		return super.getContents();
	}
	
	@Override
	protected void updateInternalState(IParseResult parseResult) {
		fullyInitialized = false;
		super.updateInternalState(parseResult);
	}
	
	protected void lateInitialize() {
		if (getParseResult() != null && getParseResult().getRootASTElement() instanceof XPackage)
    {
			XPackage model = (XPackage) getParseResult().getRootASTElement();
      XcoreEcoreBuilder xcoreEcoreBuilder = new XcoreEcoreBuilder();
      EPackage ePackage = xcoreEcoreBuilder.getEPackage(model);
      super.getContents().add(ePackage);
      GenModel genModel =  GenModelFactory.eINSTANCE.createGenModel();
      genModel.initialize(Collections.singleton(ePackage));
      super.getContents().add(genModel);
      genModel.initialize();
      for (Iterator<EObject> i = genModel.eAllContents(); i.hasNext(); )
      {
        EObject eObject = i.next();
        if (eObject instanceof GenBase)
        {
          GenBase genBase = (GenBase)eObject;
          EModelElement eModelElement = genBase.getEcoreModelElement();
          if (eModelElement != null)
          {
            XcoreEcoreBuilder.map(eModelElement, (GenBase)eObject);
          }
        }
      }
      xcoreEcoreBuilder.link(); 
    }
	}
	
	@Override
	public synchronized EObject getEObject(String uriFragment) {
		Pair<EClass,QualifiedName> fragmentInfo = proxyConverter.decodeFragment(uriFragment);
		if (fragmentInfo != null) {
			return findEObject(fragmentInfo.getFirst(), fragmentInfo.getSecond());
		} else {
			return super.getEObject(uriFragment);
		}
	}

	/**
	 * finds the EObject of the given type and the given {@link QualifiedName}.
	 * 
	 * TODO optimize
	 */
	protected EObject findEObject(EClass clazz, QualifiedName name) {
		TreeIterator<EObject> iterator = EcoreUtil.getAllContents(this, false);
		while (iterator.hasNext()) {
			EObject candidate = iterator.next();
			if (clazz.isInstance(candidate)) {
				QualifiedName qualifiedName = nameProvider.getFullyQualifiedName(candidate);
				if (name.equals(qualifiedName))
					return candidate;
			}
		}
		return null;
	}
	
}