Resource Adaptation: Difference between revisions
m Created page with '== Problem Statement == No language can define itself. There have to be extra-language mechanisms for defining basic concepts of the language. For computers to understand the l...' |
No edit summary |
||
| Line 1: | Line 1: | ||
TODO: | |||
* Fix all TODOs | |||
== Problem Statement == | == Problem Statement == | ||
Revision as of 15:14, 29 September 2010
TODO: * Fix all TODOs
Problem Statement
No language can define itself. There have to be extra-language mechanisms for defining basic concepts of the language. For computers to understand the language, this means some code. Here is a basic example:
public class ShapeFactory {
public static Shape create(Graph g, Resource r) {
ShapeResources sr = ShapeResource.getInstance(g);
if(g.isInstanceOf(r, sr.Rectangle)) {
...
return new Rectangle2D.Double(...);
}
else if(g.isInstanceOf(r, sr.Ellipse)) {
...
return new Ellipse2D.Double(...);
}
...
else {
throw new IllegalArgumentException("Resource is not a shape or the implementation does not support it.");
}
}
}
This works as long as there is only a fixed set of shapes. Addition of every new shape needs modification to the code. We would like to have something like:
- A declaration telling that instances of Shape can be adapted to objects of Shape class.
- For each concrete subtype of Shape, a code creating an object of the corresponding Shape class.
- Declarations connecting subtypes and code snippets.
- Utility that implements the creation pattern.
Solution
Declarations are written into adapters.xml-file that has to be located in the plugin root: <source lang="xml">
<?xml version="1.0" encoding="UTF-8"?>
<adapters>
<target interface="org.simantics.form.model.IWidgetModel">
<baseType uri = "http://www.simantics.org/Form-1.0/Widget"/>
<type uri = "http://www.simantics.org/Form-1.0/Label"
class = "org.simantics.form.model.adapters.LabelAdapter"/>
<type uri = "http://www.simantics.org/Form-1.0/InputText"
class = "org.simantics.form.model.adapters.InputTextAdapter"/>
...
</target>
<target interface="org.simantics.form.model.ILayoutModel">
<baseType uri = "http://www.simantics.org/Form-1.0/Layout"/>
<type uri = "http://www.simantics.org/Form-1.0/GridLayout"
class = "org.simantics.form.model.adapters.GridLayout">
<graph/>
<this/>
</type>
<adapter uri="http://www.simantics.org/Form-1.0/FormLayout"
adapterClass="org.simantics.form.model.adapters.FormLayoutAdapter" />
</target>
</adapters>
</source>
Each <target>...</target> section defines adaption to given interface.
<baseType> gives one or more types where all classes implementing the adaption have been inherited from.
<type> defines direct adaptation from instances of given type (uri) by construction the specified class (class) through Java Reflection API's whereas <adapter> defines adaptation from instances of given type (uri) by using the given adapter (adapterClass). The adapter has
to implement the following interface:
public interface Adapter<T> {
void adapt(AsyncReadGraph g, Resource r, AsyncProcedure<T> procedure);
}
In addition the adapter may contain this kind of definitions:
<resource uri="http://www.simantics.org/Layer0-1.0/OrderedSetElements" class="org.simantics.layer0.utils.binaryPredicates.OrderedSetElementsPredicate"/>
This means that the resource defined by the uri is always adapted to an instance of the given class.
The main difference between <type>/<resource> definitions and <adapter> definitions is that <type>/<resource> adaptation cannot be used for complex adaptation since both can only be used to adapt to instances of the defined adapter class and nothing else. <adapter> on the other hand can perform more complex analysis and return any instance of the adaptation target interface.
Defined adapters can be used with the following synchronous methods, where clazz-parameter refers to the interface in the adapter declaration:
public interface ReadGraph {
....
<T> T adapt(Resource resource, Class<T> clazz) throws AdaptionException, ValidationException, ServiceException;
<T> T adaptUnique(Resource resource, Class<T> clazz) throws AdaptionException, ValidationException, ServiceException;
<T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException;
<T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException;
...
}
For details, see ReadGraph interface.
In addition to <adapter>-elements, the file may contain <installer>-elements, with class-attribute referring to an implementation of the interface:
public interface AdapterInstaller {
void install(ReadGraph g, AdaptionService service) throws Exception;
}
where
public interface AdaptionService {
<T> void adapt(AsyncReadGraph g, Resource r, Class<T> clazz, boolean possible, AsyncProcedure<T> procedure);
<T> void adaptNew(AsyncReadGraph g, Resource r, Class<T> clazz, boolean possible, AsyncProcedure<T> procedure);
<T> void declareAdapter(Resource type, Class<T> clazz);
<T> void addAdapter(Resource type, Class<T> clazz, Adapter<T> adapter);
<T> void addInstanceAdapter(Resource resource, Class<T> clazz, Adapter<T> adapter);
}
The class installs adapters by using method addAdapter (and addInstanceAdapter).
You should use the xml-file to define your adapters if possible. The installer-mechanism is provided for cases where you want to install an adapter that is constructed with special parameters.
Adapter Parameters
Certain parameters can be specified for adapters defined with <type> and <resource> elements. These arguments will be directly forwarded to a constructor matching this argument list in your adapter implementation class.
- <this/>
The resource that is being adapted.
- <graph/>
ReadGraphfor reading the graph database during construction of the adapted class instance.
- <bundle/>
Bundleclass instance which identifies the bundle in which this adapter is defined. Can also be used to specify the referenced bundle explicitly using its symbolic name, e.g.<bundle>bundle.id</bundle>.
- <string>FOO</string>
Any string constant contained as text within the <string> tag. Passed to the constructor as a
java.lang.Stringinstance. TODO explain to argument.
- <single/>
TODO explain.
- <atMostOne/>
TODO explain.
- <related/>
TODO explain.
- <orderedSet/>
TODO explain.