/*******************************************************************************
* Copyright (c) 2015-16 Obeo, Inria
* 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:
* - William Piers <william.piers@obeo.fr>
* - Philippe Merle <philippe.merle@inria.fr>
*******************************************************************************/
package org.occiware.clouddesigner.occi;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.occiware.clouddesigner.occi.util.Occi2Ecore;
import org.occiware.clouddesigner.occi.util.OcciHelper;
public class OCCIKindResolver
{
/**
* Store mapping from EMF namespace to OCCI Extension.
*/
private static Map<String, Extension> namespace2extension = new HashMap<String, Extension>();
/**
* Store mapping from EClass to OCCI Kind.
*/
private static Map<EClass, Kind> eclass2kind = new HashMap<EClass, Kind>();
/**
* Resolve the kind of a given entity.
* @param entity the given entity.
* @return the resolved kind.
*/
public static Kind resolveKind(final Entity entity)
{
// Get the Eclass of the given entity.
EClass entityEClass = entity.eClass();
Extension extension = null;
String kindTermToSearch = Occi2Ecore.convertEcoreClassName2OcciCategoryTerm(entityEClass.getName());
// Search the kind associated to the entity's eClass.
Kind entityKind = eclass2kind.get(entityEClass);
// If kind not found then
if (entityKind == null) {
// Search the extension associated to the ePackage of the entity's eClass.
String metamodelURI = entityEClass.getEPackage().getNsURI();
extension = namespace2extension.get(metamodelURI);
// If extension not found then
if (extension == null) {
// Search URI of the extension into the OCCI extension registry.
String scheme = Occi2Ecore.convertEcoreNamespace2OcciScheme(metamodelURI);
String extensionURI = OCCIRegistry.getInstance().getExtensionURI(scheme);
// If extension URI not found then
if(extensionURI == null) {
// This is no way to resolve the kind of the given entity :-(
// TODO: perhaps compute extensionURI of the ePackage of the entity's eClass.
// Use OCCI Core resource, link or entity kind instances.
extensionURI = OCCIRegistry.getInstance().getExtensionURI(OcciCoreConstants.OCCI_CORE_SCHEME);
if(entity instanceof org.occiware.clouddesigner.occi.Resource) {
kindTermToSearch = OcciCoreConstants.OCCI_CORE_RESOURCE_TERM;
} else if(entity instanceof Link) {
kindTermToSearch = OcciCoreConstants.OCCI_CORE_LINK_TERM;
} else {
kindTermToSearch = OcciCoreConstants.OCCI_CORE_ENTITY_TERM;
throw new Error("Should never happens! entity=" + entity);
}
}
// Here extensionURI is set.
assert(extensionURI != null);
// Compute the resource set where loading the extension.
ResourceSet resourceSet = null;
Resource entityResource = entity.eResource();
// If entity not in a resource.
if(entityResource != null) {
// Reuse the resource set containing the resource containing the given entity.
resourceSet = entityResource.getResourceSet();
} else {
// Create a new resource set.
resourceSet = new ResourceSetImpl();
}
// Load the extension.
Resource extensionResource = resourceSet.getResource(URI.createURI(extensionURI), true);
extension = (Extension) extensionResource.getContents().get(0);
// Map the metamodelURI to the found extension for optimizing next searches.
namespace2extension.put(metamodelURI, extension);
}
// Here extension was loaded.
assert(extension != null);
// Search the entity's kind into the found extension.
entityKind = OcciHelper.getKindByTerm(extension, kindTermToSearch);
if(entityKind != null) {
// Map the entity's eClass to the found kind for optimizing next searches.
eclass2kind.put(entityEClass, entityKind);
}
}
// Update the configuration of the entity.
Configuration owningConfiguration = OcciHelper.getConfiguration(entity);
if(extension != null && owningConfiguration != null) {
EList<Extension> useList = owningConfiguration.getUse();
if (!useList.contains(extension)) {
// add the found extension to the use of the configuration owning the given entity.
try {
useList.add(extension);
} catch(Exception exc) {
// TODO: Should never happen :-(
exc.printStackTrace(System.err);
}
}
}
// Return the found entity's kind.
return entityKind;
}
}