Analysis
Overview
The current model and resources design does not support the needed functionality for changes manipulation. This task's main goal is to present a complete redesign of the internal concepts for resources and sophie 2 model. This will result in a major refactoring of the base and main model modules.
Task requirements
- Complete and stable design which supports all needed functionality.
- Decomposing of this task to smaller weekly tasks.
- Providing a schedule with deadlines for their completion.
- Provide the other developers with a prototype of the new model as soon as possible because they are blocked by this task.
Task result
The result will be prototype source code and detailed documentation of the new design.
Implementation idea
- Use the design draft posted by milo in http://pastebin.asteasolutions.net/f444cc8f1.
- Create a new module for the new resources that separates the new logic so that the old one is working until a full implementation.
Related
(Add links to related tasks that could be useful or helpful.)
How to demo
This task is mainly redesign and its result is mainly documentation of the new design. There will be major quantity of tests provided.
Design
Resume of the current design ideas that are going to support all need functionality for Sophie 2.0 :
ResourceRevision
The resources revision is a version of the resource after application of a change. Revisions know the previous revision – the one they come from but have separate models. The model should be immutable so that it is preserved intact in the previous revisions. The only way to modify this model will be by applying change, resulting in new revisions with a new changed model.
Key
Keys provide a read access to the resource model. Different keys implement different logic for getting values kept in the model. There will be seven kinds of keys for the different types of model values and they will all have a get method.
Children keys - Key used to access the children sub resources of a given resource. It can retrieve a list of the children ResourceRefs and get a key to a child provided a ResourceRef.
Composite keys - Key used to access the sub keys of a given key. For example the BOREDER key is a composite key for its sub keys – COLOR, INSETS… It can retrieve a list of the kept sub keys.
Root keys – keep a key to a resource. It has a sub(T extends Key<?>) method that takes as argument a sub key to get a new key of the same type as the passed one pointing to the same value starting from the root. Example: If the root key is pointing to “PageA/frameA” and the passed key is BORDER the new key that is going to be created will be pointing the value of “PageA/frameA/Border”.
Simple keys – Keys providing the simpler logic for getting the values of the model – using directly the getRaw() method.
Templated keys – Keys that support templating. They know about the Simple key pointing to a ResourceRef TEMPLATE and use it to get value for a template key when the getRaw returns null. The TEMPLATEs value is got from the access and the access is used to open the pointed resource. Then the value is got by it recursively by the template keys get method.
Meta keys – Keys getting values that are not kept only in the model. They implement different logic for every instance and are used for things like getting the revision id or some other value that depends on the state of the whole access.
Security keys – Keys used to get the access options for a certain access.
Change
Every Change should be immutable and have the following properties:
RevisionId revisionId – the id of the revision it initiates.
ResourceRef user – The user that created it.
String viewId – The id of the view it comes from.
String description – Human readable explanatory description of what exactly was changed to be presented to the user when undo/redo or browsing history.
boolean significant – A flag indication whether this change is significant. For example the transitional states of a drag and drop operations or typing of a single letter in a text are not significant changes despite the fact those states should be visible for the user. They should not be incorporated in a single change; however they should be processed as a whole when undoing and redoing. There will be two basic types of changes – Model and Meta changes .
ModelChange
This type of change will affect the model structure. Through these changes developers should be able to add, remove and change values of different properties of the model.
AutoAction
AutoAction is a basic abstracts helper class that have a performAuto() method. When a developer wants to modify the model he should just use a new instance of a AutoAction class and implement an appropriate performAuto() method directly managing the model. This “direct” interaction with the model should internally lead to creation of changes and registration of reads. For this interaction are responsible the ResourceChangers.
ResourceChanger
Every AutoAction class has access to a ResourceChanger which holds the model and can modify it internally without causing any effect on the actual resource model.
When managing the model in the performAuto() method developers should use the two methods getRaw(Key<T> key) and setRaw(Key<T> key, T value)of the ResourceChanger. This will transparently register reads and writes for the appropriate operations and thus the change`s effect could be extracted after the method is complete.
The ResourceChanger should also present several useful helper methods for resource manipulation - makeResource(ResourceRef ref), copyResource(ResourceRef source, ResourceRef destination), moveResource(ResourceRef source, ResourceRef destination), removeResource(ResourceRef ref), makeRedirect(ResourceRef source, ResourceRef destination) and getSub(ResourceRef subRef) which returns an inner Changer and delegates all its logic to its top ResourceChanger.
The ResourceChanger will be abstract class implementing the ResourceReader interface and providing definitions of the other needed for the perfomAuto() methods. It will be extended by two classes - ModelResourceChanger and SubResourceChanger.
The SubResourceChanger would implement simpler logic just delegating to the ResourceChanger it is made by. For they would need to know this parent to delegate to and also the ResourceRef by which they are made so that the delegation is made with the appropriate key.
When a ModelChange is created it should be provided with everything needed to resurrect an AutoAction object so that it could get the resulting effect for any model anytime by resurrecting it and providing it with different ResourceChanger. So a ModelChange keeps the AutoAction class from which to take effect and all external fields it uses.
Meta Changes
Meta changes are the changes that does not change the model directly by setting particular values but change the current revisions by undoing and redoing user operations.
Accesses
The resource model is not accessible by the developers directly. For this are used special classes ResourceAccesses. They are responsible for location and manipulation of resources.
ResourceChannel
ResourceChannel provides fundamental methods for managing ResourceAccesses. It provides methods for opening, closing and getting AccessOptions and AccessInfo. AccessOptions are all the options of the view that is using this access. They identify the view id, user and the write scope of the ResourceChanel. AccessInfo is information about the location and security of a given ResourceChanel.
ResourceReader
The resource reader is interface implemented by all classes that have access to a model. The only method it provides is getRaw(Key<T> key).
ResourceLocator
The locator interface extends the ResourceChannel and adds a method for creation of resources. Only the locators can create resources of a certain type.
ResourceAccess
ResourceAccess is responsible for location and manipulation of a resource. It implements the ResourceChanel and ResourceReader and provides method for registering changes and tracking history. The accesses can be classified in different ways but the common classification is done by the kind of the resources they are managing.
Root accesses are not extending the base class ResourceAccess . They don`t have a particular resource they are responsible for and they are used to access all the other accesses of their type. They implement the ResourceLocator interface and that is the reason they are referred to as 'locators'. Such accesses are the RootServerAccess which manages all top server accesses, RootMemAccess which manages all top mem accesses, RootFileAccess which manages all file accesses. The 'app' access is also a root access. It gives access to all top mem and top file accesses.
Top accesses are used for access to the top level resources. They have a resource model, can register changes to it and keep the correct revision of the resource. They also implement the ResourceChanel interface. They know how to manage their inner accesses and delegate to the root accesses for higher level resources. All top resources will be opened in a top access and every inner access will be created based on a top access.
Inner accesses are used for more convenient manipulation of inner resources to a top resource. They have no model of their own. They get their values from their top resource and delegate all their changes to it also. If you want to access a single frame`s properties you should have the top access of the book it is in opened and a inner access created for the appropriate ResourceRef that delegates to the top.
Accesses have some specific logic for delegation of the method open():
Top Mem Access | Root Mem Access | Inner Mem Access | |
Top Resource | delegate to root | return existing / throw exception | delegate to root |
Inner resource | create, remember | throw exception | delegate to top |
Initial tests can be found at: branches/private/mira/resourcesRefactoring/modules/org.sophie2.base.model.resources.r4/src/test/java/org/sophie2/base/model/resources/r4
Schedule :
This task is going to be completed in 4 weekly tasks:
0. This task - documentation and plan for all other related tasks. This should be done in the first week.
1. Memory accesses implementation along with stable model with immutable operations, implementation of ModelChanges and all related functionality. This should be done by the end of the second week.
2. File accesses implementation along with refactoring of the persistence logic. This should be done by the end of the third week.
3. MetaChanges and undo/redo logic. This should be done by the end of the fourth week.
4. Server accesses and logic for synchronization. This should be done by the end of the fifth week.
Implementation
Prototype of the new resources design is located at branches/private/mira/resourcesRefactoring/modules/org.sophie2.base.model.resources.r4
Testing
(Place the testing results here.)
Comments
(Write comments for this or later revisions here.)
Attachments
-
resourceAccessDiagram.jpg
(523.5 KB) -
added by mira 16 years ago.
UML diagram for the resource accesses hierarchy
- ResourceAccessClassDiagram.png (97.4 KB) - added by boyan 16 years ago.