Skip to content

ExtensionPoint

UrsZeidler edited this page Mar 18, 2017 · 9 revisions

generation and launch config extension point

With the 1.1.0 release two extension points are introduced to register your own model to text transformation and provide a launch configuration for it.

This way it is possible to add your own acceleo transformation to the generation process. For an introduction on acceleo see here, for the launch configuration see here.

The de.urszeidler.eclipse.solidity.um2solidity.m2t extension point let you register an acceleo generator to be a part of the uml2solidity generation process.

Configuration Markup:

<!ELEMENT extension (acceleo_generator)*>
<!ATTLIST extension
point CDATA #REQUIRED
id    CDATA #IMPLIED
name  CDATA #IMPLIED>

<!ELEMENT acceleo_generator EMPTY>
<!ATTLIST acceleo_generator
generator_id          CDATA #REQUIRED
generator_name        CDATA #REQUIRED
generator_description CDATA #IMPLIED
generator_target      CDATA #REQUIRED
generator_class       CDATA #REQUIRED
estimated_work        CDATA #IMPLIED>
  • generator_id - The generator_id is used identify the generator also it is the constance for the preferences for checking if the generator is used in the running generation process.
  • generator_name - The name of the transformation.
  • generator_description - A small description.
  • generator_target - The generation_target is used to get the preference for the target folder where the generated files should be stored.
  • generator_class - The class of the acceleo generator which provides the model to text transformation.
  • estimated_work - An optional integer to indicate the work which is needed for the generator, it is used for the progress monitor. The default value is 10.

The de.urszeidler.eclipse.solidity.um2solidity.m2t.laucherTab let you register a launch configuration used to configure the model to text transformation.

Configuration Markup:

<!ELEMENT extension (uml2solidityLauchTab*)>
<!ATTLIST extension
point CDATA #REQUIRED
id    CDATA #IMPLIED
name  CDATA #IMPLIED>

<!ELEMENT uml2solidityLauchTab EMPTY>
<!ATTLIST uml2solidityLauchTab
id        CDATA #REQUIRED
tab_class CDATA #REQUIRED
tab_order CDATA #IMPLIED>

This extension point adds launcher tabs to the uml2solidity laucher configuration. There are used to controll the generation process and provide the parameters for a transformation.

  • id -
  • tab_class - The tab must extends the AbstractUml2SolidityLaunchConfigurationTab the tab must provide at least a boolean field to en/disable the generation and the tab configuration name must correspond to the id of the registered accele_generator.
  • tab_order - The position the tab should be placed, when left out 10 is used. Choose a number higher as 10 as the first are reserved.

There is a simple example project to illustrate the usage. See registering the transformation and the launch config in the plugin.xml.

Register a transformation:

   <extension
         point="de.urszeidler.eclipse.solidity.um2solidity.m2t">
      <acceleo_generator
            generator_class="de.urszeidler.eclipse.solidity.generation.example.template.GenerateUseCasesDoc"
            generator_id="de.urszeidler.eclipse.solidity.generation.example.useCaseDoc"
            generator_name="generate usecase doc"
            generator_target="de.urszeidler.eclipse.solidity.generation.example.usecaseDocTarget">
      </acceleo_generator>
   </extension>

Besides the Generator class the important attributes are the generator_id and the generator_target. Both must correspond to attributes in the launch config. The generator class is generated by acceleo when the transformation contains a [comment @main/] tag. The acceleo file is here.

Note that we include two other transformations uml2service and generateMarkDown the uml2service gives you access to the launch configuration parameters and a lot of other useful queries while generateMarkDown contains some helper functions for text generation.

Register a launch config tab:

   <extension
         point="de.urszeidler.eclipse.solidity.um2solidity.m2t.laucherTab">
      <uml2solidityLauchTab
            id="de.urszeidler.eclipse.solidity.generation.example.uml2solidityLauchTab1"
            tab_class="de.urszeidler.eclipse.solidity.generation.example.launch.UmlDocLaunchConfigurationTab">
      </uml2solidityLauchTab>
   </extension>

Here the tab_class is the important attributes. It defines a tab for the launch configuration. This tab is used to define the parameters for your model to text transformation.

There are at least two parameters the launch configuration tab must provide, a boolean value defining if the transformation should run and a string value defining the target of the generation. These two parameters are defines by the de.urszeidler.eclipse.solidity.um2solidity.m2t extensions point. The value of the generator_id defines the name of the boolean parameter and the value id the generator_target attributes the name of the target folder parameter.

public class UmlDocLaunchConfigurationTab extends AbstractUml2SolidityLaunchConfigurationTab {
	private static final String GENERATE_UML_DOC_TARGET = "de.urszeidler.eclipse.solidity.generation.example.usecaseDocTarget";
	private static final String GENERATE_UML_DOC = "de.urszeidler.eclipse.solidity.generation.example.useCaseDoc";
	private static final String GENERATE_UML_DOC_IMAGE_URL = "GENERATE_UML_DOC_IMAGE_URL";
	private Text targetText;
	private Button btnGenerateUmlDoc;
	private Text imageUrlText;

	/**
	 * @wbp.parser.entryPoint
	 */
	@Override
	public void createControl(Composite parent) {
		Composite mainComposite = new Composite(parent, SWT.NONE);
		mainComposite.setLayout(new GridLayout(1, true));
		setControl(mainComposite);
		
		Group grpUmlDoc = new Group(mainComposite, SWT.NONE);
		grpUmlDoc.setText("uml use case doc");
		grpUmlDoc.setLayout(new GridLayout(3, false));
		grpUmlDoc.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		btnGenerateUmlDoc = new Button(grpUmlDoc, SWT.CHECK);
		btnGenerateUmlDoc.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 2, 1));
		btnGenerateUmlDoc.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				validatePage();
			}
		});
		btnGenerateUmlDoc.setText("generate uml doc");
		new Label(grpUmlDoc, SWT.NONE);
		
		Label lblNewLabel = new Label(grpUmlDoc, SWT.NONE);
		lblNewLabel.setText("document target");
		
		targetText = new Text(grpUmlDoc, SWT.BORDER);
		targetText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				validatePage();
			}
		});
		targetText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
		
		Button btnNewButton = new Button(grpUmlDoc, SWT.NONE);
		btnNewButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				handleChooseContainer(targetText, "select target container");
			}
		});
		btnNewButton.setText("select");
		
		Label lblNewLabel_1 = new Label(grpUmlDoc, SWT.NONE);
		lblNewLabel_1.setText("image url");
		
		imageUrlText = new Text(grpUmlDoc, SWT.BORDER);
		imageUrlText.addModifyListener(new ModifyListener() {
			public void modifyText(ModifyEvent e) {
				validatePage();
			}
		});
		imageUrlText.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
		
	}

	@Override
	public void setDefaults(ILaunchConfigurationWorkingCopy configuration) {
		configuration.setAttribute(GENERATE_UML_DOC, false);
		configuration.setAttribute(GENERATE_UML_DOC_TARGET, "doc");
		configuration.setAttribute(GENERATE_UML_DOC_IMAGE_URL, "");
	}

	@Override
	public void initializeFrom(ILaunchConfiguration configuration) {
		try {
			btnGenerateUmlDoc.setSelection(configuration.getAttribute(GENERATE_UML_DOC, false));
			targetText.setText(configuration.getAttribute(GENERATE_UML_DOC_TARGET, "doc"));
			imageUrlText.setText(configuration.getAttribute(GENERATE_UML_DOC_IMAGE_URL, ""));
		} catch (CoreException e) {
			Activator.logError("Error while initialize launch config.", e);
		}
	}

	@Override
	public void performApply(ILaunchConfigurationWorkingCopy configuration) {
		configuration.setAttribute(GENERATE_UML_DOC, btnGenerateUmlDoc.getSelection());
		configuration.setAttribute(GENERATE_UML_DOC_TARGET, targetText.getText());
		configuration.setAttribute(GENERATE_UML_DOC_IMAGE_URL, imageUrlText.getText());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.debug.ui.ILaunchConfigurationTab#getName()
	 */
	@Override
	public String getName() {
		return "uml usecase doc";
	}
}	

See how the configuration attributes correspond to the defined values of the de.urszeidler.eclipse.solidity.um2solidity.m2t extension points. We use another parameter which will be used inside of the model to text transformation. The parameter is called GENERATE_UML_DOC_IMAGE_URL and it takes a string for the use case image url.

[comment encoding = UTF-8 /]
[**
 * The documentation of the module generateUseCasesDoc.
 */]
[module generateUseCasesDoc('http://www.eclipse.org/uml2/5.0.0/UML')]

[import de::urszeidler::eclipse::solidity::util::uml2service /]
[import de::urszeidler::eclipse::solidity::templates::generateMarkDown /]

[**
 * The documentation of the template generateElement.
 * @param aModel
 */]
[template public generateElement(aModel : Model)]
[comment @main/]
[file (aModel.name+'-usecases.md', false, 'UTF-8')]
# [aModel.name/] use cases

[printImageUrl(aModel)/]

## actors

|Actor name|use cases|doc|
|---|---|---|
[for (a : Actor | Actor.allInstances())]
|[a.name/]|[for (uc : UseCase | useCasesForActor(a))separator (', ')][uc.name/][/for]|[a.printSingleLineDoc()/]|
[/for]


## use cases

[for (uc : UseCase | UseCase.allInstances())]
### [uc.name/]

[uc.printDoc()/]
used by: [for (a : Actor | actorsForUseCase(uc))separator (', ')][a.name/][/for]

[/for]
[/file]
[/template]


[template public printImageUrl(m : Model) ? (not (m.getImageUrl().oclIsUndefined() or m.getImageUrl()=''))]
![ '[' /]modelImage[ ']' /]([m.getImageUrl()/]) 
[/template]

[query public useCasesForActor(actor : Actor) : Sequence(UseCase) = Usage.allInstances()
	->select(u: Usage| u.client->includes(actor))
	->collect(u: Usage| u.supplier)->flatten()
	->selectByType(UseCase)
	->asSequence()
   /]

[query public actorsForUseCase(uc : UseCase) : Sequence(Actor) = Usage.allInstances()
	->select(u: Usage| u.supplier->includes(uc))
	->collect(u: Usage| u.client)->flatten()
	->selectByType(Actor)
	->asSequence()
   /]

[query public getImageUrl(element : NamedElement) : String = getConfigurationParameter(element, 'GENERATE_UML_DOC_IMAGE_URL') /]

To access the parameter from the launch configuration the de::urszeidler::eclipse::solidity::util::uml2service transformation provides two queries.

  • getBooleanConfigurationParameter(class : NamedElement, parameterId : String) : Boolean
  • getConfigurationParameter(class : NamedElement, parameterId : String) : String

It is good style to create an own query access a parameter as this enables code completion also, with a sounding name, it is much easier to understand and use. In our example we use this query to access the parameter:

[query public getImageUrl(element : NamedElement) : String = getConfigurationParameter(element, 'GENERATE_UML_DOC_IMAGE_URL') /]

With this query we access the parameter provided by the launch configuration.

Clone this wiki locally