DynamicContainer

From Event-B
Revision as of 11:59, 25 November 2009 by imported>Colin (New page: ===Instructions for creating an extension=== * Design an EMF meta model (ecore) of your extension's abstract syntax. The model should NOT deal with ownership of the extension (i.e. where ...)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Instructions for creating an extension

  • Design an EMF meta model (ecore) of your extension's abstract syntax. The model should NOT deal with ownership of the extension (i.e. where the extension is contained in the existing meta-models)
  • Load and configure the gen model (this should be set for extensible providers) <still under investigation since extending provider would be the container which is defined dynamically now>
  • Generate the code and edit code
  • Customise the package initialiser with the code shown below to make your package extensible
  • Add an extension to define the containment of the extension (the containment will be added dynamically to the meta-model being extended)
  • Add extensions to declare new kinds of Rodin elements and attributes
  • Write Java interfaces and classes for each new Rodin element
  • Add extensions to declare synchronisers to persist your new meta-classes into Rodin elements.
  • Write Java classes for each synchroniser


example code to make a package extensible (the example is for the core package... core package should be changed to the name of your package)

public static CorePackage init() {
               ........
       //Link in any extensions
       getExtensions(theCorePackage,theMachinePackage,theContextPackage);
      	
      // Mark meta-data to indicate it can't be changed
      theCorePackage.freeze();

      return theCorePackage;
}

/**
 * Method to get all extensions from extension registry.
 * Extensions can link additional EMF model content to this core model by defining a new EReference
 * (usually a containment) which holds instances of a new metaclass.
 * 
 * @custom
*/
private static final String extensionId = "org.eventb.emf.core.metamodel_extension";

private static void getExtensions(EPackage theCorePackage,EPackage theMachinePackage,EPackage theContextPackage) {
      IExtensionRegistry extensionRegistry = Platform.getExtensionRegistry();
      IExtensionPoint extensionPoint = extensionRegistry.getExtensionPoint(extensionId);
      org.eclipse.core.runtime.IExtension[] extensions = extensionPoint.getExtensions();

      for (org.eclipse.core.runtime.IExtension extension : extensions) {
             try {
                    EPackage extenderPackage = null;
                    IConfigurationElement [] elements = extension.getConfigurationElements();
                    for (IConfigurationElement element : elements) {
                           if ("ePackage".equals(element.getName())){
                                   //String packageName = element.getAttribute("name");
                                  Registry packageRegistry = EPackage.Registry.INSTANCE;
                                  String extender_eNS_URI = element.getAttribute("eNS_URI");
                                  extenderPackage = packageRegistry.getEPackage(extender_eNS_URI);
                           }
                    }
                    if (extenderPackage==null){
                           EventbcoreEditPlugin.INSTANCE.logError(null, "extending ePackage not found during Event-B EMF metamodel extension");
                    }else{
                           for (IConfigurationElement element : elements) {
                                  if ("eReference".equals(element.getName())){
                                         String eReferenceName = element.getAttribute("name");
                                         String parentName = element.getAttribute("parent");
                                         boolean containment = Boolean.parseBoolean(element.getAttribute("containment"));
                                         String eTypeName = element.getAttribute("eType");
                                         String required = element.getAttribute("required");
                                         String singular = element.getAttribute("singular");
                                         Object parent=null;
                                         if ((parent = theCorePackage.getEClassifier(parentName)) == null)
                                                if ((parent = theContextPackage.getEClassifier(parentName))==null)									
                                                       if ((parent = theMachinePackage.getEClassifier(parentName))==null);

                                         if (parent instanceof EClass){
                                                EClass eType = (EClass)extenderPackage.getEClassifier(eTypeName);
                                                EReference eReference = EcoreFactory.eINSTANCE.createEReference();
                                                eReference.setName(eReferenceName);
                                                eReference.setEType(eType);
                                                eReference.setContainment(containment);
                                                eReference.setUpperBound(ETypedElement.UNBOUNDED_MULTIPLICITY); //change to set from required and singular
                                                ((EClass)parent).getEStructuralFeatures().add(eReference);
                                         }
                                  }
                           }
                    }
             }
             catch (Exception e) {
                    EventbcoreEditPlugin.INSTANCE.logError(e, "failed getting Event-B EMF extensions");
             }
      }
}


example metamodel-extension (containment definition)

  <extension
        point="org.eventb.emf.core.metamodel_extension">
     <ePackage
           eNS_URI="http://emf.eventb.org/models/records"
           name="RecordsPackage">
     </ePackage>
     <eReference
           containment="true"
           eType="AbstractRecord"
           name="records"
           parent="Context"
           required="false"
           singular="false">
     </eReference>
  </extension>