1
2
3
4
5
6
7
8 package de.uni_leipzig.wifa.iwi.mr3.service.impl;
9
10 import java.io.BufferedWriter;
11 import java.io.IOException;
12 import java.io.StringReader;
13 import java.io.StringWriter;
14 import java.io.Writer;
15 import java.util.Calendar;
16 import java.util.Collections;
17 import java.util.HashMap;
18
19 import javax.xml.parsers.FactoryConfigurationError;
20 import javax.xml.stream.XMLInputFactory;
21 import javax.xml.stream.XMLStreamException;
22 import javax.xml.stream.XMLStreamReader;
23
24 import org.apache.axiom.om.OMElement;
25 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
26 import org.apache.log4j.Logger;
27 import org.eclipse.emf.common.util.EList;
28 import org.eclipse.emf.common.util.URI;
29 import org.eclipse.emf.compare.diff.metamodel.DiffFactory;
30 import org.eclipse.emf.compare.diff.metamodel.DiffModel;
31 import org.eclipse.emf.compare.diff.metamodel.ModelInputSnapshot;
32 import org.eclipse.emf.compare.diff.service.DiffService;
33 import org.eclipse.emf.compare.match.metamodel.MatchModel;
34 import org.eclipse.emf.compare.match.service.MatchService;
35 import org.eclipse.emf.compare.util.ModelUtils;
36 import org.eclipse.emf.ecore.EObject;
37 import org.eclipse.emf.ecore.EPackage;
38 import org.eclipse.emf.ecore.EPackage.Registry;
39 import org.eclipse.emf.ecore.resource.ResourceSet;
40 import org.eclipse.emf.ecore.resource.Resource.Factory;
41 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
42 import org.eclipse.emf.ecore.xmi.XMIResource;
43 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
44
45 import de.uni_leipzig.wifa.iwi.mr3.common.Comparison;
46 import de.uni_leipzig.wifa.iwi.mr3.common.Model;
47 import de.uni_leipzig.wifa.iwi.mr3.dao.ModelRepositoryDao;
48 import de.uni_leipzig.wifa.iwi.mr3.service.CompareProcessor;
49 import de.uni_leipzig.wifa.iwi.mr3.service.MRException;
50 import de.uni_leipzig.wifa.iwi.mr3.service.ServiceHelper;
51
52
53
54
55 public class CompareProcessorImpl implements CompareProcessor
56 {
57
58 private static final Logger LOG = Logger.getLogger(ModelRepositoryServiceImpl.class);
59
60
61 private static final String DUMMY_URI = "";
62
63
64 private static final String DEFAULT_CONTENT_TYPE = "*";
65
66
67 private static final Factory RESOURCE_FACTORY = new XMIResourceFactoryImpl();
68
69
70 private ModelRepositoryDao dao;
71
72
73 private ServiceHelper helper;
74
75
76
77
78
79
80
81
82
83
84
85
86 public Comparison process(final String leftUri, final String rightUri) throws MRException
87 {
88 final long startTime = System.currentTimeMillis();
89
90 final ResourceSet rset = new ResourceSetImpl();
91 rset.getResourceFactoryRegistry().getContentTypeToFactoryMap().put(DEFAULT_CONTENT_TYPE, RESOURCE_FACTORY);
92 final Registry reg = rset.getPackageRegistry();
93
94 final XMIResource leftResource = (XMIResource) rset.createResource(URI.createURI(leftUri));
95 final EObject leftModel = getDao().load(leftUri, new HashMap<Object, EObject>());
96 leftResource.getContents().add(leftModel);
97 reg.put(leftUri, leftModel);
98
99 final XMIResource rightResource = (XMIResource) rset.createResource(URI.createURI(rightUri));
100 final EObject rightModel = getDao().load(rightUri, new HashMap<Object, EObject>());
101 rightResource.getContents().add(rightModel);
102 reg.put(rightUri, rightModel);
103
104 try
105 {
106 final ResourceSet resourceSet = new ResourceSetImpl();
107 resourceSet.getResourceFactoryRegistry().getContentTypeToFactoryMap().put(DEFAULT_CONTENT_TYPE, RESOURCE_FACTORY);
108 final XMIResource diffModelResource = (XMIResource) resourceSet.createResource(URI.createURI(DUMMY_URI));
109
110
111 diffModelResource.getContents().add(compare(leftModel, rightModel));
112
113 final OMElement axiomDiffModel = serializeResource(diffModelResource);
114 final OMElement axiomLeftModel = serializeResource(leftResource);
115 final OMElement axiomRightModel = serializeResource(rightResource);
116
117 if (LOG.isInfoEnabled())
118 {
119 LOG.info("compare finished after " + (System.currentTimeMillis() - startTime) + " ms.");
120 }
121
122 final Comparison cmp = wrap(axiomDiffModel, axiomLeftModel, axiomRightModel);
123
124 if (!(leftModel instanceof EPackage))
125 {
126 final String leftMetaNsUri = ((EPackage) leftModel.eClass().eContainer()).getNsURI();
127 final String rightMetaNsUri = ((EPackage) rightModel.eClass().eContainer()).getNsURI();
128 if (!leftMetaNsUri.equals(rightMetaNsUri))
129 {
130 throw new MRException("Models do not have the same metamodel. Select two models with the same metamodel, please.");
131 }
132 final OMElement metaAxiomModel = serializeMetamodel(leftMetaNsUri, rset);
133 cmp.addReferenced(wrap(metaAxiomModel));
134 }
135 return cmp;
136 }
137 catch (final InterruptedException e)
138 {
139 throw new MRException("error while comparing models [" + leftUri + "] and [" + rightUri + "]", e);
140 }
141 catch (final IOException e)
142 {
143 throw new MRException("error while comparing models [" + leftUri + "] and [" + rightUri + "]", e);
144 }
145 catch (final XMLStreamException e)
146 {
147 throw new MRException("error while comparing models [" + leftUri + "] and [" + rightUri + "]", e);
148 }
149 catch (final FactoryConfigurationError e)
150 {
151 throw new MRException("error while comparing models [" + leftUri + "] and [" + rightUri + "]", e);
152 }
153 }
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168 private ModelInputSnapshot compare(final EObject leftModel, final EObject rightModel) throws InterruptedException,
169 IOException
170 {
171 final MatchModel match = MatchService.doMatch(leftModel, rightModel, Collections.<String, Object> emptyMap());
172 LOG.debug(ModelUtils.serialize(match));
173
174 final DiffModel diff = DiffService.doDiff(match, false);
175 LOG.debug(ModelUtils.serialize(diff));
176
177 final ModelInputSnapshot snapshot = DiffFactory.eINSTANCE.createModelInputSnapshot();
178 snapshot.setDate(Calendar.getInstance().getTime());
179 snapshot.setMatch(match);
180 snapshot.setDiff(diff);
181 LOG.debug(ModelUtils.serialize(snapshot));
182
183 return snapshot;
184 }
185
186
187
188
189
190
191
192
193
194
195
196
197 private OMElement serializeResource(final XMIResource resource) throws IOException, XMLStreamException
198 {
199 final StringWriter writer = new StringWriter();
200 final Writer out = new BufferedWriter(writer);
201 resource.save(out, resource.getDefaultSaveOptions());
202 out.flush();
203
204
205 final StringReader reader = new StringReader(writer.getBuffer().toString());
206
207
208 final XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(reader);
209
210
211 final StAXOMBuilder builder = new StAXOMBuilder(xmlReader);
212 final OMElement axiomModel = builder.getDocumentElement();
213
214 out.close();
215 writer.close();
216 return axiomModel;
217 }
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233 private OMElement serializeMetamodel(final String leftMetaNsUri, final ResourceSet rset) throws IOException,
234 XMLStreamException
235 {
236 final EPackage metaPackage = (EPackage) getDao().load(leftMetaNsUri, new HashMap<Object, EObject>());
237 helper.registerAllSubpackages(metaPackage, rset);
238 final XMIResource metaResource = (XMIResource) rset.createResource(URI.createURI(DUMMY_URI));
239
240
241 final EList<EObject> metaContents = metaResource.getContents();
242 metaContents.add(metaPackage);
243
244 final StringWriter metaWriter = new StringWriter();
245 final Writer metaOut = new BufferedWriter(metaWriter);
246 metaResource.save(metaOut, metaResource.getDefaultSaveOptions());
247 metaOut.flush();
248
249
250 final StringReader metaReader = new StringReader(metaWriter.getBuffer().toString());
251
252
253 final XMLStreamReader metaXmlReader = XMLInputFactory.newInstance().createXMLStreamReader(metaReader);
254
255
256 final StAXOMBuilder metaBuilder = new StAXOMBuilder(metaXmlReader);
257 final OMElement metaAxiomModel = metaBuilder.getDocumentElement();
258 LOG.debug(metaAxiomModel);
259
260 metaOut.close();
261 metaWriter.close();
262
263 return metaAxiomModel;
264 }
265
266
267
268
269
270
271
272
273
274
275
276
277 private Comparison wrap(final OMElement ss, final OMElement left, final OMElement right)
278 {
279 final Comparison cmp = new Comparison();
280 cmp.setSnapshot(wrap(ss));
281 cmp.setLeft(wrap(left));
282 cmp.setRight(wrap(right));
283 return cmp;
284 }
285
286
287
288
289
290
291
292
293 private Model wrap(final OMElement content)
294 {
295 final Model m = new Model();
296 m.setExtraElement(content);
297 return m;
298 }
299
300
301
302
303
304
305
306 public ModelRepositoryDao getDao()
307 {
308 return dao;
309 }
310
311
312
313
314
315
316
317
318 public void setDao(final ModelRepositoryDao dao)
319 {
320 this.dao = dao;
321 }
322
323
324
325
326
327
328 public ServiceHelper getHelper()
329 {
330 return helper;
331 }
332
333
334
335
336
337
338
339 public void setHelper(final ServiceHelper helper)
340 {
341 this.helper = helper;
342 }
343 }