Skip to content

Commit

Permalink
changed the melange resource to load tfsm model as extended
Browse files Browse the repository at this point in the history
  • Loading branch information
ftanguy committed Mar 6, 2015
1 parent 5dc2af3 commit 06c99d3
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 64 deletions.
2 changes: 1 addition & 1 deletion plugins/fr.inria.diverse.melange.resource/plugin.xml
Expand Up @@ -5,7 +5,7 @@
<extension
point="org.eclipse.emf.ecore.protocol_parser">
<parser
class="fr.inria.diverse.melange.resource.MelangeResourceFactory"
class="fr.inria.diverse.melange.resource.MelangeResourceFactoryImpl"
protocolName="melange">
</parser>
</extension>
Expand Down
@@ -1,94 +1,140 @@
package fr.inria.diverse.melange.resource

import fr.inria.diverse.melange.resource.loader.DozerLoader
import java.io.IOException

import java.util.Map

import org.eclipse.emf.common.util.URI

import org.eclipse.emf.ecore.EPackage
import org.eclipse.emf.ecore.resource.Resource

import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl

import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl

import org.eclipse.xtend.lib.annotations.Delegate

/**
* Just don't read this
*/
class MelangeResourceFactory implements Resource.Factory
import org.eclipse.emf.ecore.plugin.RegistryReader
import org.eclipse.emf.common.util.EList
import org.eclipse.emf.ecore.EObject
import org.eclipse.emf.ecore.resource.ResourceSet
import org.eclipse.emf.ecore.resource.impl.ResourceImpl
import org.eclipse.emf.ecore.util.EcoreUtil

class MelangeResourceFactoryImpl implements Resource.Factory
{
override Resource createResource(URI uri) {
if (!#["resource", "plugin"].contains(uri.segments.head)) {
throw new MelangeResourceException('''Melange resource only supports melange:/resource/ and melange:/plugin/ URIs''')
}

val splits = uri.query?.split("=")

// Loading through a viewpoint
if (splits !== null && splits.size == 2 && splits.head == "mt")
return new MelangeResource(uri)
// Loading through a viewpoint / metamodel
if (splits !== null && splits.size == 2 && #["mt", "mm"].contains(splits.head))
return new MelangeResourceImpl(uri)
// Nothing special: fallback to XMI resource creation
else {
val fallbackUri = URI::createFileURI(uri.toString.replaceFirst("melange:/", ""))
return new XMIResourceImpl(fallbackUri)
// val fallbackUri = URI::createURI(uri.toString.replaceFirst("melange:/", "platform:/"))
// return new XMIResourceImpl(fallbackUri)
return new XMIResourceImpl(uri)
}
}
}

class MelangeResource implements Resource$Internal
class MelangeResourceImpl extends XMIResourceImpl
{
@Delegate Resource$Internal xmiResource
String expectedMt
String expectedMm

new(URI melangeUri) {
super()

val path = melangeUri.toString.replaceFirst("melange:/", "")
val fallbackUri = path.substring(0, path.lastIndexOf("?"))
val rs = new ResourceSetImpl
xmiResource = rs.getResource(URI::createFileURI(fallbackUri), true) as Resource$Internal
expectedMt = melangeUri.query.split("=").get(1)
super(melangeUri)
val query = melangeUri.query.split("=")
if (query.head == "mt")
expectedMt = query.get(1)
else if (query.head == "mm")
expectedMm = query.get(1)
}

override getContents() throws RuntimeException {
val objs = xmiResource.getContents()

if (objs.empty)
return objs

val actualPkgUri = objs.head.eClass.EPackage.nsURI
val pair = actualPkgUri -> expectedMt
val adapterCls = ModelTypeAdapter$Registry::INSTANCE.get(pair)

if (adapterCls !== null) {
try {
val adapter = adapterCls.newInstance => [adaptee = xmiResource]
return adapter.contents
} catch (InstantiationException e) {
throw new MelangeResourceException('''Cannot instantiate adapter type «adapterCls»''', e)
} catch (IllegalAccessException e) {
throw new MelangeResourceException('''Cannot access adapter type «adapterCls»''', e)
}
}

throw new MelangeResourceException('''No adapter class registered for «pair»''')
override load(Map<?, ?> options) throws IOException
{
if (!this.loaded)
{
super.load(options)
//EcoreUtil::resolveAll(resourceSet)
// val loader = new DozerLoader
// val expectedPkg = EPackage$Registry.INSTANCE.getEPackage(expectedMm)
// val res = loader.loadBaseAsExtended(this, expectedPkg)
// getContents().clear()
// getContents().addAll(res.contents)
this.loaded = true
}
}

override getAllContents() {
// FIXME: Should perform adaptation here
println("FIXME: Should perform adaptation here")
return xmiResource.allContents
}

override getEObject(String uriFragment) {
// FIXME: Should perform adaptation here
println("FIXME: Should perform adaptation here")
return xmiResource.getEObject(uriFragment)
}

// override getContents() throws RuntimeException {
// createWrappedResource()
// val objs = wrappedResource.getContents()
//
// if (objs.empty)
// return objs
//
// val actualPkgUri = objs.head.eClass.EPackage.nsURI
//
// if (expectedMt !== null) {
// val pair = actualPkgUri -> expectedMt
// val adapterCls = ModelTypeAdapter.Registry::INSTANCE.get(pair)
//
// if (adapterCls !== null) {
// try {
// val adapter = adapterCls.newInstance => [adaptee = wrappedResource]
// return adapter.contents
// } catch (InstantiationException e) {
// throw new MelangeResourceException('''Cannot instantiate adapter type «adapterCls»''', e)
// } catch (IllegalAccessException e) {
// throw new MelangeResourceException('''Cannot access adapter type «adapterCls»''', e)
// }
// }
//
// throw new MelangeResourceException('''No adapter class registered for «pair»''')
// }
// else if (expectedMm !== null) {
// if (contents == null)
// {
// val fallbackUri = URI.melangeURIToPlatformURI
// val rs = getResourceSet()
// //wrappedResource = new ResourceSetImpl().getResource(fallbackUri, true) as Resource.Internal
// wrappedResource = rs.getResource(fallbackUri, true) as Resource
//
// contents = objs
// }
// return contents
// }
// else
// {
// return objs
// }
// }

// override getAllContents() {
// // FIXME: Should perform adaptation here
//// throw new UnsupportedOperationException("FIXME: Should perform adaptation here")
// return wrappedResource.allContents
// }

// override getEObject(String uriFragment) {
// // FIXME: Should perform adaptation here
//// throw new UnsupportedOperationException("FIXME: Should perform adaptation here")
// return wrappedResource.getEObject(uriFragment)
// }

override save(Map<?, ?> options) throws IOException {
// FIXME: Should perform adaptation here
println("FIXME: Should perform adaptation here")
xmiResource.save(options)
throw new UnsupportedOperationException("FIXME: Should perform adaptation here")
// xmiResource.save(options)
}

// private def URI melangeURIToPlatformURI(URI uri) {
// val path = uri.toString.replaceFirst("melange:/", "platform:/")
// val fallbackUri = path.substring(0, path.lastIndexOf("?"))
// return URI::createURI(fallbackUri)
// }
}

class MelangeResourceException extends RuntimeException {
Expand Down
Expand Up @@ -19,6 +19,10 @@ import org.dozer.loader.api.BeanMappingBuilder
import org.dozer.loader.api.FieldsMappingOptions

import static extension fr.inria.diverse.melange.resource.loader.EcoreHelper.*
import org.dozer.config.BeanContainer
import org.dozer.util.DozerClassLoader
import java.net.URL
import org.dozer.loader.api.TypeMappingOptions

class DozerLoader implements ExtensionsAwareLoader
{
Expand Down Expand Up @@ -81,10 +85,54 @@ class DozerLoader implements ExtensionsAwareLoader

return newRes
}


// public def Resource loadBaseAsExtended(URI baseModelURI, EPackage expectedPackage) throws PackageCompatibilityException {
// val baseResource = loadModel(baseModelURI, true) // Just propagate thrown exceptions if any
// val rs = baseResource.resourceSet
//
// pkgBase = baseResource.contents.head.eClass.EPackage
//
// val mapper = new DozerBeanMapper
// val builder = new BaseToExtendedBuilder(pkgBase, expectedPackage)
//
// val extendedURI = baseModelURI.appendSegment("extended")
// val extendedResource = rs.createResource(extendedURI)
//
// mapper.addMapping(builder)
// baseResource.contents.forEach[o |
// extendedResource.contents += mapper.map(o, pkgExtended.EClassifiers.findFirst[name == o.eClass.name].implementationClass) as EObject
// ]
// extendedResource.contents.addAll(baseResource.contents)
// return extendedResource
// }

public def Resource loadBaseAsExtended(Resource baseResource, EPackage expectedPackage) throws PackageCompatibilityException
{
val resourceSet = new ResourceSetImpl

val basePackage = baseResource.contents.head.eClass.EPackage
val mapper = new DozerBeanMapper
val builder = new BaseToExtendedBuilder(basePackage, expectedPackage)

val extendedURI = URI.createURI("modelAsExtended")
val extendedResource = resourceSet.createResource(extendedURI)

mapper.addMapping(builder)
baseResource.getContents().forEach[o |
extendedResource.getContents() += mapper.map(o, expectedPackage.EClassifiers.findFirst[name == o.eClass.name].implementationClass) as EObject
]
//extendedResource.contents.addAll(baseResource.contents)
return extendedResource
}

private def loadModel(String uri, boolean loadOnDemand) {
return loadModel(URI.createURI(uri), loadOnDemand)
}

private def loadModel(URI uri, boolean loadOnDemand) {
val rs = new ResourceSetImpl
val res = rs.getResource(URI.createURI(uri), loadOnDemand)
val res = rs.getResource(uri, loadOnDemand)

return res
}
Expand Down Expand Up @@ -151,14 +199,22 @@ class BaseToExtendedBuilder extends BeanMappingBuilder
}

override protected configure() {

val classLoader = new OsgiDozerClassLoader
BeanContainer.getInstance.classLoader = classLoader

pkgBase.EClassifiers.filter(EClass).forEach[cls |
val extendedCls = pkgExtended.EClassifiers.filter(EClass).findFirst[name == cls.name]

val baseImpl = cls.implementationClass
val extendedImpl = extendedCls.implementationClass
classLoader.updateContext(baseImpl, extendedImpl)

// borner la recherche
val map = mapping(
baseImpl,
extendedImpl
extendedImpl,
TypeMappingOptions.oneWay()
)

cls.EReferences
Expand All @@ -176,4 +232,44 @@ class BaseToExtendedBuilder extends BeanMappingBuilder
]
]
}

}

public class OsgiDozerClassLoader implements DozerClassLoader {

private ClassLoader _cl1;
private ClassLoader _cl2;

override loadClass(String className) {
try {
return _cl1.loadClass(className);
} catch (ClassNotFoundException e1) {
try {
return _cl2.loadClass(className);
} catch (ClassNotFoundException e2) {
return null;
}
}
}

override loadResource(String uri)
{
var url = _cl1.getResource(uri);
if (url == null)
{
url = _cl2.getResource(uri);
}
if (url == null)
{
url = class.classLoader.getResource(uri);
}
return url;
}

def updateContext(Class<?> class1, Class<?> class2)
{
_cl1 = class1.classLoader
_cl2 = class2.classLoader
}

}
Expand Up @@ -7,9 +7,11 @@ class EcoreHelper
// FIXME: How ugly is that!
static def Class<?> getImplementationClass(EClassifier cls) {
val clsInterface = cls.instanceClass

try {
return Class.forName('''«clsInterface.package.name».impl.«clsInterface.simpleName»Impl''')
val className = '''«clsInterface.package.name».impl.«clsInterface.simpleName»Impl'''
val c = clsInterface.classLoader.loadClass(className)
return c
// return Class.forName('''«clsInterface.package.name».impl.«clsInterface.simpleName»Impl''')
} catch (Exception e) {
// ...
}
Expand Down

0 comments on commit 06c99d3

Please sign in to comment.