1
2
3
4
5
6
7
8
9
10 package de.uni_leipzig.wifa.iwi.mr3.service.impl;
11
12 import java.io.BufferedInputStream;
13 import java.io.BufferedWriter;
14 import java.io.ByteArrayInputStream;
15 import java.io.IOException;
16 import java.io.InputStream;
17 import java.io.StringReader;
18 import java.io.StringWriter;
19 import java.io.Writer;
20 import java.util.Arrays;
21 import java.util.HashMap;
22 import java.util.Map;
23
24 import javax.xml.stream.XMLInputFactory;
25 import javax.xml.stream.XMLStreamException;
26 import javax.xml.stream.XMLStreamReader;
27
28 import org.apache.axiom.om.OMElement;
29 import org.apache.axiom.om.impl.builder.StAXOMBuilder;
30 import org.apache.axis2.AxisFault;
31 import org.apache.axis2.context.ConfigurationContext;
32 import org.apache.axis2.context.ServiceContext;
33 import org.apache.axis2.description.AxisService;
34 import org.apache.axis2.description.Parameter;
35 import org.apache.axis2.engine.ServiceLifeCycle;
36 import org.apache.axis2.service.Lifecycle;
37 import org.apache.log4j.Logger;
38 import org.eclipse.emf.common.util.URI;
39 import org.eclipse.emf.ecore.EObject;
40 import org.eclipse.emf.ecore.EPackage;
41 import org.eclipse.emf.ecore.resource.ResourceSet;
42 import org.eclipse.emf.ecore.resource.Resource.Factory;
43 import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
44 import org.eclipse.emf.ecore.xmi.PackageNotFoundException;
45 import org.eclipse.emf.ecore.xmi.XMIResource;
46 import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
47
48 import de.uni_leipzig.wifa.iwi.mr3.common.Comparison;
49 import de.uni_leipzig.wifa.iwi.mr3.common.Match;
50 import de.uni_leipzig.wifa.iwi.mr3.dao.ModelRepositoryDao;
51 import de.uni_leipzig.wifa.iwi.mr3.dao.neo4j.impl.ModelRepositoryDaoNeo4jImpl;
52 import de.uni_leipzig.wifa.iwi.mr3.service.CompareProcessor;
53 import de.uni_leipzig.wifa.iwi.mr3.service.MRException;
54 import de.uni_leipzig.wifa.iwi.mr3.service.ModelRepositorySkeletonInterface;
55 import de.uni_leipzig.wifa.iwi.mr3.service.ServiceHelper;
56
57
58
59
60
61
62
63
64
65 public class ModelRepositoryServiceImpl implements ModelRepositorySkeletonInterface, ServiceLifeCycle, Lifecycle
66 {
67
68 private static final Logger LOG = Logger.getLogger(ModelRepositoryServiceImpl.class);
69
70
71 private static final int BUFFER_SIZE = 1024 * 1024;
72
73
74 private static final String DEFAULT_CONTENT_TYPE = "*";
75
76
77 private static final String DUMMY_URI = "";
78
79
80 private static final String PARAMETER_DB_PATH = "ModelRepository.DatabasePath";
81
82
83 private static final String OS_NAME_WINDOWS = "windows";
84
85
86 private static final String SYSTEM_PARAMETER_OS_NAME = "os.name";
87
88
89 private static final String WINDOWS_DB_PATH = "/modelrepository/database";
90 private static final String UNIX_DB_PATH = "/var/lib" + WINDOWS_DB_PATH;
91
92
93 private static final String PARAMETER_DAO = "dao";
94
95
96 private static final String PARAMETER_COMPARE_PROCESSOR = "compare.processor";
97
98
99 private static final String PARAMETER_HELPER = "service.helper";
100
101
102 private static final Factory RESOURCE_FACTORY = new XMIResourceFactoryImpl();
103
104
105
106
107 private ServiceContext serviceCtx;
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 @Override
124 public void startUp(final ConfigurationContext configctx, final AxisService service)
125 {
126 LOG.debug("starting");
127
128
129
130
131 final ModelRepositoryDaoNeo4jImpl dao = new ModelRepositoryDaoNeo4jImpl();
132 dao.setDatabasePath(getDatabasePath(service));
133 dao.startUp();
134
135
136 final ServiceHelper helper = new ServiceHelperImpl();
137
138
139 final CompareProcessorImpl compareProcessor = new CompareProcessorImpl();
140 compareProcessor.setDao(dao);
141 compareProcessor.setHelper(helper);
142
143 try
144 {
145 service.addParameter(new Parameter(PARAMETER_DAO, dao));
146 service.addParameter(new Parameter(PARAMETER_HELPER, helper));
147 service.addParameter(new Parameter(PARAMETER_COMPARE_PROCESSOR, compareProcessor));
148 LOG.info("started");
149 }
150 catch (final AxisFault e)
151 {
152 LOG.error("error while starting", e);
153 }
154 }
155
156
157
158
159
160
161
162
163
164
165
166 @Override
167 public void shutDown(final ConfigurationContext configctx, final AxisService service)
168 {
169 LOG.debug("shutting down");
170 ((ModelRepositoryDao) service.getParameter(PARAMETER_DAO).getValue()).shutDown();
171 LOG.info("shutted down");
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 @Override
189 public void init(final ServiceContext context) throws AxisFault
190 {
191 LOG.debug("init");
192 serviceCtx = context;
193 }
194
195
196
197
198
199
200
201
202 @Override
203 public void destroy(final ServiceContext context)
204 {
205 LOG.debug("destroy");
206 }
207
208
209
210
211
212
213
214
215
216
217
218
219 private String getDatabasePath(final AxisService service)
220 {
221 final Parameter serviceDbPath = service.getParameter(PARAMETER_DB_PATH);
222 if (serviceDbPath != null)
223 {
224 return serviceDbPath.getValue().toString();
225 }
226 final Parameter globalDbPath = service.getAxisConfiguration().getParameter(PARAMETER_DB_PATH);
227 if (globalDbPath != null)
228 {
229 return globalDbPath.getValue().toString();
230 }
231 return System.getProperty(SYSTEM_PARAMETER_OS_NAME).toLowerCase().indexOf(OS_NAME_WINDOWS) > -1 ? WINDOWS_DB_PATH
232 : UNIX_DB_PATH;
233 }
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251 @Override
252 public void save(final OMElement model, final String uri) throws MRException
253 {
254 if (LOG.isDebugEnabled())
255 {
256 final String nl = System.getProperty("line.separator");
257 final String ln = "----------------------------------";
258 LOG.debug(new StringBuilder(nl).append(ln).append(nl).append(model).append(nl).append(ln));
259 }
260 final ResourceSet rset = new ResourceSetImpl();
261 rset.getResourceFactoryRegistry().getContentTypeToFactoryMap().put(DEFAULT_CONTENT_TYPE, RESOURCE_FACTORY);
262
263 final long startTime = System.currentTimeMillis();
264
265
266 final XMIResource res = (XMIResource) rset.createResource(URI.createURI(DUMMY_URI));
267 while (!res.isLoaded())
268 {
269 final InputStream stream = new BufferedInputStream(new ByteArrayInputStream(model.toString().getBytes()), BUFFER_SIZE);
270 try
271 {
272 res.load(stream, res.getDefaultLoadOptions());
273 res.setURI(URI.createURI(uri));
274
275
276
277
278 final EObject m = res.getContents().get(0);
279
280
281 if (!modelExists(m))
282 {
283 getDao().save(res);
284 }
285
286
287 if (LOG.isInfoEnabled())
288 {
289 LOG.info("Model [" + uri + "] saved after " + (System.currentTimeMillis() - startTime) + " ms");
290 }
291 }
292 catch (final IOException e)
293 {
294
295 final Throwable cause = e.getCause();
296 if (cause instanceof PackageNotFoundException)
297 {
298 final String nsUri = ((PackageNotFoundException) cause).uri();
299 final EObject pkg = getDao().load(nsUri, new HashMap<Object, EObject>());
300 if (null == pkg)
301 {
302 final MRException ex = new MRException("First save the meta model with nsURI: " + nsUri);
303 LOG.warn(ex);
304 throw ex;
305 }
306
307 getHelper().registerAllSubpackages((EPackage) pkg, rset);
308
309 res.unload();
310 }
311 else
312 {
313 final MRException ex =
314 new MRException("Unable to process the model data. For further details, please use the EMF validator!");
315 LOG.warn(ex);
316 throw ex;
317 }
318 }
319 finally
320 {
321 try
322 {
323 if (stream != null)
324 {
325 stream.close();
326 }
327 }
328 catch (final IOException e)
329 {
330 LOG.error(e);
331 }
332 }
333 }
334 }
335
336
337
338
339
340
341
342
343
344
345 private boolean modelExists(final EObject model) throws MRException
346 {
347 if (model instanceof EPackage)
348 {
349 final EPackage pkg = (EPackage) model;
350 if (getDao().modelExists(pkg.getNsURI()))
351 {
352 final MRException ex =
353 new MRException("Package or subpackage with namespace uri [" + pkg.getNsURI()
354 + "] still exists. Please delete it before save.");
355 LOG.warn(ex);
356 throw ex;
357 }
358 for (final EPackage subPkg : pkg.getESubpackages())
359 {
360 return modelExists(subPkg);
361 }
362 }
363 else
364 {
365
366 final String nsUri = model.eClass().getEPackage().getNsURI() + " [" + model.eResource().getURI() + "]";
367 if (getDao().modelExists(nsUri))
368 {
369 final MRException ex =
370 new MRException("Model with identifier " + nsUri + " still exists. Please delete it before save.");
371 LOG.warn(ex);
372 throw ex;
373 }
374 }
375 return false;
376 }
377
378
379
380
381
382
383
384
385
386
387
388
389 @Override
390 public OMElement load(final String nsUri) throws MRException
391 {
392 LOG.debug("loading model with nsURI [" + nsUri + "]");
393
394 final long startTime = System.currentTimeMillis();
395
396 final ResourceSet rset = new ResourceSetImpl();
397 rset.getResourceFactoryRegistry().getContentTypeToFactoryMap().put(DEFAULT_CONTENT_TYPE, RESOURCE_FACTORY);
398
399 final EObject emfModel = getDao().load(nsUri, new HashMap<Object, EObject>());
400
401 final XMIResource resource = (XMIResource) rset.createResource(URI.createURI(DUMMY_URI));
402
403 try
404 {
405 resource.getContents().add(emfModel);
406
407 final StringWriter writer = new StringWriter();
408 final Writer out = new BufferedWriter(writer);
409
410 final Map<Object, Object> saveOptions = resource.getDefaultSaveOptions();
411
412
413 resource.save(out, saveOptions);
414 out.flush();
415
416
417 final StringReader reader = new StringReader(writer.getBuffer().toString());
418
419
420 final XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(reader);
421
422
423 final StAXOMBuilder builder = new StAXOMBuilder(xmlReader);
424 final OMElement axiomModel = builder.getDocumentElement();
425
426 out.close();
427 writer.close();
428
429 if (LOG.isInfoEnabled())
430 {
431 LOG.info("loaded model [" + nsUri + "] after " + (System.currentTimeMillis() - startTime) + " ms");
432 }
433 return axiomModel;
434 }
435 catch (final IllegalArgumentException e)
436 {
437 final MRException ex = new MRException("No model with nsURI [" + nsUri + "]", e);
438 LOG.warn(ex);
439 throw ex;
440 }
441 catch (final IOException e)
442 {
443 final MRException ex = new MRException("error while loading model [" + nsUri + "]", e);
444 LOG.warn(ex);
445 throw ex;
446 }
447 catch (final XMLStreamException e)
448 {
449 final MRException ex = new MRException("error while loading model [" + nsUri + "]", e);
450 LOG.warn(ex);
451 throw ex;
452 }
453 }
454
455
456
457
458
459
460
461
462
463
464
465
466
467 @Override
468 public void delete(final String nsUri, final boolean cascading) throws MRException
469 {
470 LOG.debug("delete model [" + nsUri + "]");
471
472 final long startTime = System.currentTimeMillis();
473
474 getDao().delete(nsUri, cascading);
475
476 if (LOG.isInfoEnabled())
477 {
478 LOG.info("deleted model [" + nsUri + "] after " + (System.currentTimeMillis() - startTime) + " ms.");
479 }
480 }
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499 @Override
500 public String[] getInstanceModels(final String metaNsUri)
501 {
502 final long startTime = System.currentTimeMillis();
503
504 final String[] models = getDao().getInstanceModels(metaNsUri);
505
506 if (LOG.isInfoEnabled())
507 {
508 if (LOG.isDebugEnabled())
509 {
510 LOG.debug("metaNsUri: " + metaNsUri);
511 for (final String model : models)
512 {
513 LOG.debug(" +- " + model);
514 }
515 }
516 LOG.info("got instance models of [" + metaNsUri + "] after " + (System.currentTimeMillis() - startTime) + " ms.");
517 }
518 return models;
519 }
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 @Override
537 public Match[] find(final String[] classifiers, final String expression, final boolean isRegEx, final boolean isCaseSensitive)
538 {
539 if (LOG.isDebugEnabled())
540 {
541 LOG.debug("expression: " + expression);
542 LOG.debug("case sensitive: " + String.valueOf(isCaseSensitive));
543 LOG.debug("regexp: " + String.valueOf(isRegEx));
544 LOG.debug("classifiers: " + Arrays.toString(classifiers));
545 }
546 final long startTime = System.currentTimeMillis();
547
548 final Match[] result = getDao().find(expression, classifiers, isRegEx, isCaseSensitive);
549
550 if (LOG.isInfoEnabled())
551 {
552 LOG.info("search finished after " + (System.currentTimeMillis() - startTime) + " ms.");
553 }
554 return result;
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570 @Override
571 public Comparison compare(final String leftUri, final String rightUri) throws MRException
572 {
573 LOG.debug("comparing models with nsURI [" + leftUri + "] and [" + rightUri + "]");
574
575 return getCompareProcessor().process(leftUri, rightUri);
576 }
577
578
579
580
581
582
583
584
585
586 private ModelRepositoryDao getDao()
587 {
588 return (ModelRepositoryDao) serviceCtx.getAxisService().getParameter(PARAMETER_DAO).getValue();
589 }
590
591
592
593
594
595
596
597
598
599 private CompareProcessor getCompareProcessor()
600 {
601 return (CompareProcessor) serviceCtx.getAxisService().getParameter(PARAMETER_COMPARE_PROCESSOR).getValue();
602 }
603
604
605
606
607
608
609 private ServiceHelper getHelper()
610 {
611 return (ServiceHelper) serviceCtx.getAxisService().getParameter(PARAMETER_HELPER).getValue();
612 }
613 }