[[BackLinksMenu]]

[[TicketQuery(summary=GROUP_TEMPLATES_R0, format=table, col=summary|owner|status|type|component|priority|effort|importance, rows=description|analysis_owners|analysis_reviewers|analysis_score|design_owners|design_reviewers|design_score|implementation_owners|implementation_reviewers|implementation_score|test_owners|test_reviewers|test_score|)]]

= Analysis =

== Overview ==
 * Templates allow the user to create book elements suchs as frames, pages and books that have certain pre-defined characteristics.
 * The newly created elements may override the properties of the template.
 * Editing the template should update all objects that it is applied to.
 * Locking a property, prevents any changes to it.

== Task requirements ==
 * Define a library that supports templating a pro-objects.
  * There should be a different behaviour for immutables and mutables.
  * Use composition instead of inheritance to prevent coliding with resources.
 * Define a basic GUI in halos/huds for creating and manipulating templates and locking.
 * Define frames, pages and books templates pallete in the library tab.
 * The frame properties that need to be templated can be seen FRAME_TEMPLATES_R0
 * The page properties that need to be templated can be seen at PAGE_TEMPLATE_BEHAVIOUR_R0

== Task result ==
The result of this task should be source code.

== Implementation idea ==
 * The template and the element are an instance of the same class. For example, the template of a frame is also a frame.
 * Properties that are templated should be defined as auto properties, which will calculate their values based on the template of the object.
 * Page and frame templates should be global for each book.
 * Book templates should be global for the app.


== Related ==
 * book model: [source:/trunk/sophie2-platform/modules/org.sophie2.base.model.book]

== How to demo ==
 * Start Sophie2.
 * Create a page with some frames.
 * Add the page as a template.
 * Create another page and apply the newly created template to it.

= Design =
The main goal is that, making a property templated should require minimum ammount of code. Here is an example:
{{{
@Templated
public RwProp<ImmColor> color() {
	class color extends AutoProperty<ImmColor> {
		@Override
		protected ImmColor compute() {
			return templateSupport().get().getFieldValue(this);
		}

		@Override
		protected void doSet(ImmColor value) {
			templateSupport().get().setFieldValue(this, value);
		}
	}
	return getBean().makeRwProp(color.class);
}
}}}

The main idea is that all templated properties should be made auto, and their values be calculated based on the template or their own value. Typically, not all properties of a pro-object will be needed to be templated, so an anotation should be present, which will specify which ones to be included in the template. The different scenarios of templating a property of a pro-object depend on the following:
 * Whether the property is a list-property or a value-property, e.g. scalar;
 * Whether is is mutable or not.

 * Add template package in base.model.book module. It should provide the functionallity for templating a pro-object. It should contain the following classes:
  * TemplateField:
    * Base class for a templated field, which has some basic properties like the id of the field, locked() (boolean) and useTemplate() (boolean);
    * locked() is used for locking the field, e.g. preventing any changes to it;
    * useTemplate() is used for indicating whether the value from the template should be used.
  * TemplateValueField:
    * Used for templating a value property;
    * Inherits TemplateField;
    * Has ownValue() value property, which contains the own value of the value property;
    * Has derivedValue() auto property, which computes the value that is from the template;
    * Has value() which return the actual value. It should depend on the useTemplate() flag, ownValue(), and derivedValue().
  * TemplateListField:
    * Used for templating a list property;
    * Inherits TemplateField;
    * Has ownList() - a list property with the objects that the property contains;
    * Has derivedList() - an auto list property with the objects that are derived from the template;
    * Has list() - an auto list property which is a union of derivedList() (if useTemplate() is true) and ownList().
  * TemplateSupport:
    * Each pro-object that needs to be templated should contain an instance of this class;
    * It should contain a value list, named fields(), which will contain the actual properties of the templated pro-object.
    * Upon initialization, it should iterate trough all the properties of the templated pro-object, that have the @Templated annotation, and insert TemplateField objects in fields().
    * derive(source) method - if source is immutable, it should just return its value, otherwise the derive() method should be called on it.
    * abstract method computeTemplate(). Each class that has a template support, should define how the templted should be fetched;
    * Helper methods like setFieldValue(), getFieldValue() for manipulating the own values of a TemplateValueField;
    * Helper methods like addProp(), removeProp(), etc., for manipulating the own list of a TemplateListField;    
  * @Templated annotation, used for indicating which property to be templated, as described above;
  * Derivable interface:
    * has method derive(), which in most cases copies the object;
    * all mutable classes that are being templated, should implements this interface.
 * There should be 3 palletes in the the library tab - Frame, Page and Book pallete:
  * For this revision, double clicking on a frame or a page template in the pallete, applies it to the current frame or page;
  * For this revision, double clicking on a book template in the pallete, opens it for editing;
  * For this revision, pressing enter on a book template in the pallete, creates a new one based on the book template.
 * Halos:
   * Add a halo button in the page halo menu which adds the current page as a template;
   * Add a halo button in the page halo menu which toggles the visibility of the frames from the template;
   * Add a halo button in the frame halo menu which adds the current frame as a template;
   * Add a halo button in the frame halo menu which toggles the content of the frame (its own or the one from the template).
 * Huds:
   * In most Huds (BackgroundAndBorderHud, FrameInsetsHud, FrameSizeAndPositionHud, ShadowHud), the following checkboxes should be added:
     * Use template;
     * Lock.
 * Update the classes in base.model.book, that need template support, using the newly created library.

UML class diagram:

[[Image(source:branches/private/jani/sophie2-platform/doc/uml-design-diagrams/TemplateClassDiagram.png)]]

Unit test: [source:/trunk/sophie2-platform/modules/org.sophie2.base.model.book/src/test/java/org/sophie2/base/model/book/template/TemplateTest.java TemplateTest]

= Implementation =
^(Describe and link the implementation results here (from the wiki or the repository).)^

= Testing =
^(Place the testing results here.)^

= Comments =
^(Write comments for this or later revisions here.)