| chapter:Customization[Customization] |
| |
| section:ResourceManagers[Managing Resources] |
| |
| section2:ResourceLoader[Resource Loader] |
| |
| The class codeRef[org.eclipse.emf.parsley.resource.ResourceLoader] can be used to handle resource loading. |
| This class uses internally the ref:EmptyResourceInitializer[Empty Resource Initializer]. |
| |
| |
| section2:EmptyResourceInitializer[Empty Resource Initializer] |
| |
| If you need to initialize your model, for the first use, you can define an implementation of codeRef[org.eclipse.emf.parsley.resource.EmptyResourceInitializer]. |
| When the main resource will be found empty, your code will be executed. |
| |
| section2:EditingDomainFinder[Editing Domain Finder] |
| |
| The class codeRef[org.eclipse.emf.parsley.edit.EditingDomainFinder] can be inherited to provide a specific |
| way to find the editign domain. |
| |
| |
| section2:ResourceSaveManager[Resource Save Manager] |
| |
| Resource saving is delegated to codeRef[org.eclipse.emf.parsley.edit.ResourceSaveManager] |
| which, by defaults only saves the passed codeRef[org.eclipse.emf.ecore.resource.Resource]. |
| You can inject your own save manager and implement the method code[precondition(Resource)], for |
| instance, you may want to validate the resource before saving, and in case the validation |
| fails to return code[false]. If the precondition is code[false] the default implementation |
| will not save the resource (and in turn will return code[false]). |
| |
| section3:ValidateResourceSaveManager[Validate Resource Save Manager] |
| |
| We provide an example of custom resource save manager: codeRef[org.eclipse.emf.parsley.edit.ValidateResourceSaveManager], |
| we show here only relevant parts to give an example: |
| |
| code[Java][ |
| public class ValidateResourceSaveManager extends ResourceSaveManager { |
| |
| @Override |
| protected boolean precondition(Resource resource) { |
| return super.precondition(resource) && validateModel(resource); |
| } |
| |
| protected boolean validateModel(Resource resource) { |
| for (EObject eObject : resource.getContents()) { |
| Diagnostic diagnostic = Diagnostician.INSTANCE.validate(eObject); |
| if (diagnostic.getSeverity() == Diagnostic.ERROR) { |
| // SKIPPED: present the errors |
| return false; |
| } else if (diagnostic.getSeverity() == Diagnostic.WARNING) { |
| // SKIPPED: present the warnings |
| } |
| } |
| return true; |
| } |
| } |
| ] |
| |
| |
| section:Providers[Providers] |
| |
| section2:FeaturesProvider[Features Provider] |
| |
| e[This can be done with Parsley DSL too!] |
| |
| todo[TODO: merge delle 2 versioni] |
| |
| section3:FeatureProvider1[Prima versione] |
| |
| To customize the e[feature list] it can be injected a codeRef[org.eclipse.emf.parsley.ui.provider.FeaturesProvider]. |
| The default is to return the list of all the features in the EClass, but the programmer can customize it (for instance, |
| by returning only a superset, or using a different order) on an EClass-based strategy. The customization can be done |
| redefining buildMap and adding mappings. |
| |
| code[Java][ |
| protected void buildMap(EClassToEStructuralFeatureMap map) { |
| super.buildMap(map); |
| map.mapTo(LIBRARY,LIBRARY__NAME, ADDRESSABLE__ADDRESS); |
| } |
| ] |
| |
| In the example we specify that for the EClass e[Library] the feature that are to be displayed are e[name] |
| and e[address]. |
| |
| section3:FeatureProvider2[Seconda versione] |
| |
| |
| When the framework builds components according to the |
| codeRef[org.eclipse.emf.ecore.EStructuralFeature]s of a given |
| codeRef[org.eclipse.emf.ecore.EClass] it relies on an injected |
| codeRef[org.eclipse.emf.parsley.ui.provider.FeaturesProvider]. |
| The default behavior is to simply return all the features of the a given EClass, |
| in the order they are defined in the EClass; |
| you may want to provide a custom implementation by redefining |
| the method code[List<EStructuralFeature> getFeatures(EClass)], or |
| code[List<EStructuralFeature> getFeatures(EObject)], |
| for instance by returning the features ordered according to their name |
| (the following snippet uses an utility class from the framework) |
| |
| code[Java][ |
| public class OrderedEStructuralFeaturesProvider |
| extends FeaturesProvider { |
| |
| @Inject |
| EStructuralFeatureNameComparator comparator; |
| |
| @Override |
| public List<EStructuralFeature> getFeatures(EClass eClass) { |
| List<EStructuralFeature> features = super.getFeatures(eClass); |
| Collections.sort(features, |
| new EStructuralFeatureNameComparator()); |
| return features; |
| } |
| } |
| ] |
| |
| Alternatively, you can set the mappings, i.e., specify the structural |
| features you want to be used given an EClass, by implementing |
| the method code[buildMap], which receives the |
| codeRef[org.eclipse.emf.parsley.ui.provider.FeaturesProvider$EClassToEStructuralFeatureMap] |
| that can be filled with the method code[mapTo]; |
| for instance, using the EMF extended library |
| example, this customization will return only the e[name] and e[address] features |
| for code[Library], the e[firstName], e[lastName] and e[address] for |
| code[Person], and the e[firstName], e[lastName] and e[books] (but |
| not e[address]) for code[Writer] (which inherits from code[Person]). |
| |
| code[Java][ |
| import static org.eclipse.emf.examples.extlibrary.EXTLibraryPackage.Literals.*; |
| import org.eclipse.emf.parsley.ui.provider.EStructuralFeaturesProvider; |
| |
| public class LibraryEStructuralFeaturesProvider extends |
| FeaturesProvider { |
| |
| @Override |
| protected void buildMap(EClassToEStructuralFeatureMap map) { |
| super.buildMap(map); |
| map.mapTo(LIBRARY, |
| LIBRARY__NAME, ADDRESSABLE__ADDRESS); |
| map.mapTo(PERSON, |
| PERSON__FIRST_NAME, PERSON__LAST_NAME, |
| ADDRESSABLE__ADDRESS); |
| map.mapTo(WRITER, |
| PERSON__FIRST_NAME, PERSON__LAST_NAME, |
| WRITER__BOOKS); |
| } |
| } |
| ] |
| |
| Another possibility is to build a map which relies on Strings |
| both for the codeRef[org.eclipse.emf.ecore.EClass] and for |
| the list of codeRef[org.eclipse.emf.ecore.EStructuralFeature]; |
| note that the name of the codeRef[org.eclipse.emf.ecore.EClass] should |
| be obtained by using code[getInstanceClassName()]; you can also |
| combine the two approaches (in that case the map built with |
| code[buildMap] has the precedence): |
| |
| code[Java][ |
| import static org.eclipse.emf.examples.extlibrary.EXTLibraryPackage.Literals.*; |
| import org.eclipse.emf.parsley.ui.provider.FeaturesProvider; |
| |
| public class LibraryEStructuralFeaturesAsStringsProvider extends |
| FeaturesProvider { |
| |
| @Override |
| protected void buildMap(EClassToEStructuralFeatureMap map) { |
| super.buildMap(map); |
| map.mapTo(LIBRARY, LIBRARY__NAME, ADDRESSABLE__ADDRESS); |
| } |
| |
| @Override |
| protected void buildStringMap( |
| EClassToEStructuralFeatureAsStringsMap stringMap) { |
| super.buildStringMap(stringMap); |
| stringMap.mapTo(PERSON.getInstanceClassName(), "firstName", "lastName", |
| "address"); |
| stringMap.mapTo(WRITER.getInstanceClassName(), "firstName", "lastName", |
| "books"); |
| |
| } |
| } |
| ] |
| |
| |
| section3:TableFeaturesProvider[Table Features Provider] |
| |
| As an extension, you can use the codeRef[org.eclipse.emf.parsley.ui.provider.TableFeaturesProvider]: |
| the customizations will be applied only to ref:TableComponent[tables], not to ref:FormComponent[Forms]. |
| |
| |
| section2:PropertyDescriptionProvider[Feature Caption Provider] |
| |
| e[This can be done with Parsley DSL too!] |
| |
| The codeRef[org.eclipse.emf.parsley.ui.provider.FeatureCaptionProvider] provides captions for |
| the features. It can be customized, with injection (see Injection paragraph), to customize the caption label on the |
| left of each control in a form and the headers in a table's columns. |
| The framework use a polimorphic mechanism to find customizations, so that It can |
| be written a method with a specific signature build by the keyword e['text'] followed by the EClass and the EStructuralFeature. |
| All parts of the name are separated by an underscore character and the method must accept a parameter of type EStructuralFeature. |
| |
| In the following example we specify the caption text for the feature 'Author' of Book and the feature 'Name' for |
| Writer. |
| |
| code[Java][ |
| public String text_Book_author(final EStructuralFeature feature) { |
| return "Wrote by:"; |
| } |
| |
| public String text_Writer_name(final EStructuralFeature feature) { |
| return "Name:"; |
| } |
| ] |
| |
| section3:FormPropertyDescriptionProvider[Form Feature Caption Provider] |
| |
| The codeRef[org.eclipse.emf.parsley.ui.provider.FormFeatureCaptionProvider] can be used if you want |
| to define the description only for the form. For example using the ref:TreeFormComponent[Tree |
| Form] your definition will not be used in the tree. |
| |
| In this case you can also define a method the returns directly the control, like in the example |
| below. In such methods there is another parameter that is the parent composite. |
| |
| code[Java][ |
| public Label label_Writer_name(Composite parent, EStructuralFeature feature) { |
| Label label = defaultLabel(parent, feature); |
| label.setBackground(getFormToolkit().getColors().getColor(IFormColors.TITLE)); |
| return label; |
| } |
| ] |
| |
| section2:ViewerLabelProvider[Viewer Label Provider] |
| |
| The Label Provider can be customized by providing a specific implementation of codeRef[org.eclipse.jface.viewers.ILabelProvider] |
| and injecting it in the spefic module e[(TODO)]. |
| EMF Parsley provides such an implementation with the class codeRef[org.eclipse.emf.parsley.ui.provider.ViewerLabelProvider] |
| that is inteded to be surclassed by the programmer to provides specific implementations like in the example below. |
| |
| code[Java][ |
| public class CustomLibraryLabelProvider extends ViewerLabelProvider { |
| |
| @Inject |
| public CustomLibraryLabelProvider(AdapterFactoryLabelProvider delegate) { |
| super(delegate); |
| } |
| |
| public String text(Book book) { |
| return "Book: " + book.getTitle(); |
| } |
| |
| public String image(Book book) { |
| return "book2.png"; |
| } |
| |
| public String text(Borrower b) { |
| return "Borrower: " + b.getFirstName(); |
| } |
| } |
| ] |
| |
| section2:ViewerContentProvider[Viewer Content Provider] |
| |
| The programmer can provide a specific implementation of codeRef[org.eclipse.jface.viewers.IContentProvider] |
| by injecting it in the spefic module e[(TODO)]. EMF Parsley provides an implementation with the class |
| codeRef[org.eclipse.emf.parsley.edit.ui.provider.ViewerContentProvider] that can be easily used to |
| specify the children of all object on the tree, like in the example below. |
| |
| code[Java][ |
| public class CustomLibraryViewerContentProvider extends ViewerContentProvider { |
| |
| @Inject |
| public CustomLibraryViewerContentProvider(AdapterFactory adapterFactory) { |
| super(adapterFactory); |
| } |
| |
| public Object children(Library library) { |
| return library.getBooks(); |
| } |
| |
| public Object children(Book book) { |
| ArrayList<Object> children = new ArrayList<Object>(); |
| Writer author = book.getAuthor(); |
| if (author != null) { |
| children.add(author); |
| } |
| children.addAll(book.getBorrowers()); |
| return children; |
| } |
| } |
| ] |
| |
| section2:ProposalProvider[Proposal Provider] |
| |
| e[This can be done with Parsley DSL too!] |
| |
| Some controls use a list of proposal to help the end user experince: for example the combo box has a |
| list of proposal, but also the simple text can use the proposal to assist and correct the hand-writed |
| values. For each feature it can be specified a list of proposals using a method that starts with the |
| keyword e['proposals'] followed byt the EClass and Feature undescore-character-separated. |
| |
| code[Java][ |
| public List<?> proposals_Book_author(Book book) { |
| List<Object> proposals = new LinkedList<Object>(); |
| Writer writer = EXTLibraryFactory.eINSTANCE.createWriter(); |
| writer.setFirstName("Fake"); |
| writer.setLastName("Writer"); |
| proposals.add(writer); |
| writer = EXTLibraryFactory.eINSTANCE.createWriter(); |
| writer.setFirstName("Fake"); |
| writer.setLastName("Writer2"); |
| proposals.add(writer); |
| return proposals; |
| } |
| ] |
| |
| section2:ViewerContextMenuFactory[Viewer Context Menu Factory] |
| |
| codeRef[org.eclipse.emf.parsley.menus.ViewerContextMenuFactory] |
| |
| section2:TableColumnLabelProvider[Table Column Label Provider] |
| |
| codeRef[org.eclipse.emf.parsley.ui.provider.TableColumnLabelProvider] |
| |
| |
| section:SelectionAndMenu[Selection And Menu] |
| |
| section2:EmfSelectionHelper[Emf Selection Helper] |
| |
| codeRef[org.eclipse.emf.parsley.util.EmfSelectionHelper] |
| |
| |
| section:Builders[Builders] |
| |
| section2:TableViewerBuilder[Table Viewer Builder] |
| |
| codeRef[org.eclipse.emf.parsley.builders.TableViewerBuilder] |
| |
| ul[ |
| item[ref:TableViewerColumnBuilder[TableViewerColumnBuilder]] |
| item[ref:ViewerInitializer[ViewerInitializer]] |
| ] |
| |
| section2:TableViewerColumnBuilder[Table Viewer Column Builder] |
| |
| codeRef[org.eclipse.emf.parsley.builders.TableViewerColumnBuilder] |
| |
| ul[ |
| item[ref:JfaceProviderFactory[JfaceProviderFactory]] |
| item[ref:PropertyDescriptionProvider[PropertyDescriptionProvider]] |
| item[ref:FeaturesProvider[FeaturesProvider]] |
| ] |
| |
| section3:TableViewerEditableColumnBuilder[Table Viewer Editable Column Builder] |
| |
| codeRef[org.eclipse.emf.parsley.builders.TableViewerEditableColumnBuilder] |
| |
| |
| |
| section:Factories[Factories] |
| |
| section2:FormFactory[Form Factory] |
| |
| codeRef[org.eclipse.emf.parsley.factories.FormFactory] |
| |
| ul[ |
| item[ref:FormPropertyDescriptionProvider[FormPropertyDescriptionProvider]] |
| item[ref:FormControlFactory[Form Control Factory]] |
| item[ref:EditingDomainFinder[EditingDomainFinder]] |
| item[ref:JfaceProviderFactory[JfaceProviderFactory]] |
| item[ref:FeaturesProvider[FeaturesProvider]] |
| ] |
| |
| section2:JfaceProviderFactory[Jface Provider Factory] |
| |
| codeRef[org.eclipse.emf.parsley.factories.ColumnLabelProviderFactory] |
| |
| ul[ |
| item[ref:ViewerLabelProvider[ViewerLabelProvider]] |
| item[ref:TableColumnLabelProvider[TableColumnLabelProvider]] |
| ] |
| |
| |
| section2:FormControlFactory[Form Control Factory] |
| |
| e[This can be done with Parsley DSL too!] |
| |
| If you want to customize the controls on the right, it can be injected a specification of the class codeRef[org.eclipse.emf.parsley.binding.FormControlFactory]. |
| Using the same polimorphic mechanism of the labels, the programmer can write a method with the keyword e['control'] |
| followed by the EClass and EStructuralFeature undescore-character-separated. In the signature of the |
| method must be both the e[DataBinding Context] and the e[Feature Observable] that can be used for databinding. |
| |
| code[Java][ |
| public Control control_Writer_name(DataBindingContext dbc,IObservableValue featureObservable) { |
| //Creating the control |
| Text text = getToolkit().createText(getParent(), ""); |
| text.setData(FormToolkit.KEY_DRAW_BORDER, FormToolkit.TREE_BORDER); |
| text.setBackground(getToolkit().getColors().getColor(IFormColors.TITLE)); |
| //Binding the control to the feature observable |
| dbc.bindValue(SWTObservables.observeText(text, SWT.Modify), featureObservable); |
| return text; |
| } |
| ] |
| |
| For more info, see the other parts that are used internally by the e[Form Control Factory]: |
| |
| ul[ |
| item[ref:JfaceProviderFactory[JfaceProviderFactory]] |
| ] |
| |
| |
| |
| section2:TreeFormFactory[Tree Form Factory] |
| |
| codeRef[org.eclipse.emf.parsley.factories.TreeFormFactory] |
| |
| ul[ |
| item[ref:ViewerInitializer[ViewerInitializer]] |
| item[ref:FormFactory[FormFactory]] |
| ] |
| |
| section2:ViewerFactory[Viewer Factory] |
| |
| codeRef[org.eclipse.emf.parsley.factories.ViewerFactory] |
| |
| ul[ |
| item[ref:TableViewerBuilder[TableViewerBuilder]] |
| item[ref:ViewerInitializer[ViewerInitializer]] |
| ] |
| |
| section2:AdapterFactoryEditingDomain[Viewer Factory] |
| |
| AdapterFactoryEditingDomain |
| |
| AdapterFactory |
| |
| section:Viewers[Viewers] |
| |
| section2:ViewerInitializer[Viewer Initializer] |
| |
| codeRef[org.eclipse.emf.parsley.viewers.ViewerInitializer] |
| |
| ul[ |
| item[e[AdapterFactoryEditingDomain]] |
| item[ref:ViewerContextMenuFactory[AdapterFactory]] |
| item[e[ILabelProvider]] |
| item[e[IContentProvider]] |
| ] |