|
|
|
Latest Published
|
Table des matières The main goal of Apogee is to display and manage repositories on top of the Eclipse Workbench. Apogee provides a common API to map different repository models into the own Apogee model. The Apogee model objects are light weight objects that usually wraps the underlying repository objects and adapt them to a representation recognized by the Apogee platform. The API is experimental and may change in the future. This section is explaining how the API is currently designed, what are the motivations that lead to the current design, and how the API may change in future. We will call « repository objetcs » the objetcs that need to be displayed in the repository tree view as parent nodes or leaf nodes. All repositories objects should be adapted into one or more interfaces understood by the Apogee model. For now there is a central interface that contains all aspects required by Apogee to dispaly and manage an object : « org.nuxeo.apogee.core.model.INode » This interface defines the nodes that will be shown in the Apogee object tree. Apogee nodes are light weight objects that points to real repository objects. You can see them as proxy objects. Apogee nodes are immutable objects so you the INode interface doesn't provide methods to edit node contents, properties or to change the tree structure. This can be done by geting a mutable node object for the node you want to edit: IMutableNode mutableNode = node.edit(); try {mutableNode.lock(); mutableNode.setProperty("propName", "propValue"); IMutableNode mutableChild = mutableNode.addChild("childName", "childType");mutableChild.setContent(content); mutableNode.commit(); } catch (CoreException) {e.printStackTrace(); } finally {mutableNode.unlock(); } Apogee nodes must provide a name that uniquely identifies them in the parent container. This is primary used to retrieve a child object by its name but it may be also used as the object label when displaying it int the repository view. Also, Apogee nodes must provide a global unique identificator as a form of an URI. This can be used do distinguish objects between different repositories (that may be based on different object models). The URI may also be used in the future to define relations between objects (using an RDF engine) public String getURI(); public String getName(); Each object should provide type information so that Apogee can handle and display objects differently based on their types. An object must have a primary type and may have multiple auxiliar types called facets that can be used to decorate a typed object in order to define new behaviors on that type without changing it's primary type. Types and facets are uniquely identified by string Ids. These types and facets are usually specific to each underlying repository. public INodeType getType(); public boolean hasFacet(String name); The INodeType API is experimental and may change in the future: public interface INodeType {public String getId(); public boolean isProtected(); public boolean isHidden(); public boolean isLeaf(); public boolean hasContent(); public ImageDescriptor getIcon(); public String getLabel(); } Beside its type and facets an object may define special attributes (or flags) used to control the way they are managed and displayed by Apogee. Currently there the following attributes are defined:
These attributes are by default initialized using the node type information but may also be detected at runtime by implementing custom INode classes implementation. Attributes are exposed by the INode interface as follow: public boolean isProtected(); public boolean isHierarchyItem(); public boolean isContainer(); public boolean hasContent(); The goal of the Apogee type support is to be able to implement most of the object behaviors using node types that can be defined in configuration files or eclipse extension points. This way when mapping a repository model into Apogee most of the work a programmer should done will be to contribute extension points (XML declarations) instead of extending default Apopgee node implementations and writing custom code. Anyway, not all the cases can be covered using a static mapping so there are cases when the programmer will need to extend default implementation of the node class. Apogee nodes are living inside tree structures (repository tree views) so that they should provides methods to traverse, locate children objects and build UI views for repository trees. The methods exposed by INode to navigate and build the tree view are: public INode[] getChildren() throws CoreException; public INode getChild(String name) throws CoreException; public INode getParent(); The getParent() method is returning the parent of the object in the Apogee tree view that may differ from the real parent of the underlying node. This is because Apogee may build and display views that differs in structure from the underlying repository tree. Apogee nodes must provide a way to (read-only) access their properties and/or the underlying content if any. This is done by providing the following methods: public IContentDescriptor getContents() throws CoreException; public Map getProperties() throws CoreException; public Object getProperty(String name)throws CoreException; The content is retrieved as an IContentDescriptor that describes how content can be retrieved what type the contents have and how it is encoded if any encoding is used. public interface IContentDescriptor {public void setContentType(String contentType); public String getContentType(); public String getEncoding(); public void setEnconding(String encoding); public IContentSource getContent(); public void setContent(IContentSource contents); } The content data is provided as an IContentSource that handle retrieval of the content from where is is located. This may be a file in the local file system, an URL, an in memory structure or any other supported content source. New content sources may be defined by the programmer. public interface IContentSource {public InputStream open() throws IOException; public void close(); public byte[] getContentsAsByteArray() throws IOException; public String getContentsAsString() throws IOException; } Each Apogee node should also provides basic UI information about how to be rendered in the tree view. This information consist on what label, icon, font and colors to use when rendering the tree node corresponding to this object. public String getLabel(); public String decorateLabel(String text); public ImageDescriptor getImageDescriptor(); public ImageDescriptor decorateImage(ImageDescriptor img); public Color getBgColor(); public Color getFgColor(); public Font getFont(); Actions on nodes are performed by repository controllers that are described by the interface «org.nuxeo.apogee.core.controller.IController» The controller can be retrieved using the following INode method: public IController getController(); The controller interface is not yet finished so I will not describe it in details here. The ideea is that Apogee is not aware on what actions are supported by the underlying repositories so it should provide a generic way to execute actions. public void execute(ICommand command) throws CoreException; Also, the controller may provide shortcut methods for standard actions like: copy, move, checkout, checkin, publish, lock, unlock. Programmers should be able to define new actions and execute them using the controller API. Actions are modeled as objects: public interface ICommand {public String getId(); public int getFlags(); public void setFlags(int flags); public void clearFlags(int flag); public void setMonitor(IProgressMonitor monitor); public IProgressMonitor getMonitor(); public void setStatus(IStatus status); public IStatus getStatus(); public Object getData(); public void setData(Object data); public void setParameter(String key, Object value); public Object getParameter(String key); public void setParameter(int index, Object value) throws IndexOutOfBoundsException; public Object getParameter(int index) throws IndexOutOfBoundsException; public void setCallback(ICommandCallback callback); public ICommandCallback getCallback(); } Apogee actions are supporting:
We've seen that Apogee nodes are immutable and updating a node is done by getting a mutable instance of the node. Mutable nodes are heavy weight objects (that keeps track of the modification on the node) and when modifications are commited they call the node controller for doing the actual repository update using the IController method: public void commit(IMutableNode object) throws CoreException; As commands, mutable nodes supports asynchronous or synchronous commits and progress monitoring. public interface IMutableNode {public INode getNode(); public void setNode(INode node); public boolean isDirty(); public boolean isNew(); public void setParent(INode node); public INode getParent(); public void setName(String name); public String getName(); public void remove(); public Object getProperty(String name); public void setProperty(String name, Object value); public IContentDescriptor getContent(); public void setContent(IContentDescriptor content); public IMutableNode addChild(String name, String type); public void commit() throws CoreException; public void commit(IProgressMonitor monitor) throws CoreException; public void commit(ICommitCallback cb, IProgressMonitor monitor) throws CoreException; public void rollback() throws CoreException; public void cancel(); public void lock() throws CoreException; public void unlock() throws CoreException; public void isLocked() throws CoreException; } This API will be improved in future, the trend is to group methods by functionailities and to move them in different interfaces – in order to preserve the INode as simple as possible For example the methods providing the UI capabilities may be moved into an interface ILabelProvider and the methods providing access to object contents in an interface IcontentProvider. These interfaces may be retrieved from the INode API or by using eclipse adapter mechanism. |
|
|