/** * */ package profile.sysml.application; import java.io.IOException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; 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.ResourceSet; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.papyrus.sysml.SysmlPackage; import org.eclipse.papyrus.sysml.modelelements.ModelelementsPackage; import org.eclipse.papyrus.sysml.activities.ActivitiesPackage; import org.eclipse.papyrus.sysml.allocations.AllocationsPackage; import org.eclipse.papyrus.sysml.blocks.BlocksPackage; import org.eclipse.papyrus.sysml.constraints.ConstraintsPackage; import org.eclipse.papyrus.sysml.interactions.InteractionsPackage; import org.eclipse.papyrus.sysml.portandflows.PortandflowsPackage; import org.eclipse.papyrus.sysml.requirements.RequirementsPackage; import org.eclipse.papyrus.sysml.statemachines.StatemachinesPackage; import org.eclipse.papyrus.sysml.usecases.UsecasesPackage; import org.eclipse.papyrus.sysml.util.SysmlResource; import org.eclipse.uml2.uml.Model; import org.eclipse.uml2.uml.Package; import org.eclipse.uml2.uml.Profile; import org.eclipse.uml2.uml.UMLFactory; import org.eclipse.uml2.uml.UMLPackage; import org.eclipse.uml2.uml.UMLPlugin; import org.eclipse.uml2.uml.resources.util.UMLResourcesUtil; /* * Dependancy notes: * ResourceSet requires: * org.eclipse.emf.common_.jar * org.eclipse.emf.ecore_.jar * * UML Models requires: * org.eclipse.emf.ecore.xmi_.jar * org.eclipse.emf.mapping.ecore2xml_.jar * org.eclipse.uml2.common_.jar * org.eclipse.uml2.types_.jar * org.eclipse.uml2.uml_.jar * org.eclipse.uml2.uml.profile.standard_.jar * */ /**Utility class for working with SysML models. * @author M. Fischer * @version 0.0.0.1 */ public class SysmlResourcesUtilities { public static Model createSysmlModel() throws IOException, URISyntaxException { Model domain = UMLFactory.eINSTANCE.createModel(); domain.setName("Domain"); domain.createNestedPackage("Use Cases"); domain.createNestedPackage("Behavior"); domain.createNestedPackage("Structure"); domain.createNestedPackage("Parametrics"); domain.createNestedPackage("IO Definitions"); domain.createNestedPackage("Viewpoints"); domain.createNestedPackage("Value Types"); Package system = domain.createNestedPackage("System"); system.createNestedPackage("Behavior"); system.createNestedPackage("Structure"); system.createNestedPackage("Requirements"); return domain; } /**Recursively searches parent to find the package specified by * qualifiedName. * @param parent - {@link Package} to search. * @param qualifiedName - The fully qualified name to search for. * @return {@link Package} or null if not found * TODO:should we throw a not found exception instead? * @since 0.0.0.1 */ public static Package getPackage(Package parent,String qualifiedName) { if(!qualifiedName.isEmpty()) { int index = qualifiedName.indexOf("::"); String rootName = (index >= 0) ? qualifiedName.substring( 0,index) : qualifiedName; for(Object obj : EcoreUtil.getObjectsByType(parent. getPackagedElements(), UMLPackage.Literals.PACKAGE)) { /* * TODO:should we play it safe and type check? * what's the use of the getObjectsByType call * if we do? */ Package pkg = (Package)obj; if(pkg.getName().equals(rootName)) { if(index >= 0) { String name = qualifiedName. substring(index+2); return getPackage(pkg,name); } else return pkg; } } return null; } else return null; //TODO:should we throw an exception? } /**Initialize a {@link ResourceSet} object for reading SysML * models. * @param set - The {@link ResourceSet} to initialize * @throws URISyntaxException * @throws MalformedURLException */ public static Profile init(ResourceSet resourceSet) throws URISyntaxException, MalformedURLException { /* * Register UML package registry and pathmaps */ UMLResourcesUtil.init(resourceSet); /* * Register Sysml package * * Notice that just by referencing the package the static initializer will register the package (and its sub packages) in the Global registry. * */ SysmlPackage sysmlPackage = SysmlPackage.eINSTANCE; /* * Register Sysml profile URI mapping : from pathmap based URI to actual URL in the classpath */ URI sysmlProfileURI = URI.createURI(SysmlResource.SYSML_PROFILE_URI); URL sysmlProfileURL = SysmlPackage.class.getResource("/model/"+sysmlProfileURI.lastSegment()); Map uriMap = resourceSet.getURIConverter().getURIMap(); uriMap.put(URI.createURI(SysmlResource.SYSML_PROFILE_URI),URI.createURI(sysmlProfileURL.toString())); /* * load the Sysml profile in the resource set (using the pathmap URI) */ Resource sysmlProfileResource = resourceSet.getResource(URI.createURI(SysmlResource.SYSML_PROFILE_URI),true); Profile sysmlProfile = (Profile) EcoreUtil.getObjectByType(sysmlProfileResource.getContents(), UMLPackage.Literals.PACKAGE); /* * Because the Sysml profile is a statically generated profile, we need to register mapping from Sysml package nsURI to actual locations * in the loaded profile. * * We also register profiles defined in nested packages */ Map mappings = UMLPlugin.getEPackageNsURIToProfileLocationMap(); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,sysmlPackage); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,ModelelementsPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,BlocksPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,PortandflowsPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,ConstraintsPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,ActivitiesPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,AllocationsPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,RequirementsPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,InteractionsPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,StatemachinesPackage.eINSTANCE); addEPackageNsURIToProfileLocationMapping(mappings,sysmlProfile,UsecasesPackage.eINSTANCE); return sysmlProfile; } /** * Maps the statically generated profile package to its corresponding dynamically loaded package * */ private static void addEPackageNsURIToProfileLocationMapping(Map mappings, Profile profile, EPackage staticPackage) { mappings.put(staticPackage.getNsURI(), EcoreUtil.getURI(getCorrespondingDynamicPackage(profile,staticPackage))); } /** * Find the loaded dynamic package in a Profile that corresponds to the statically defined specified package */ private static Package getCorrespondingDynamicPackage(Package profilePackage, EPackage staticPackage) { /* * Use URIs to match the packages * * TODO not the safer method, but there is no public API to know the correspondence */ if (profilePackage.getURI().equals(staticPackage.getNsURI())) return profilePackage; /* * look in nested packages too */ for (Package nested : profilePackage.getNestedPackages()) { Package dynamicPackage = getCorrespondingDynamicPackage(nested,staticPackage); if (dynamicPackage != null) { return dynamicPackage; } } return null; } }