• Keine Ergebnisse gefunden

4.3 Database Classes

4.3.2 Detailed Implementation Notes

In this section, we have another, more detailed look at some classes presented before, that contain some algorithms worth commenting. Hopefully this results in a better understanding of the mechanisms at work.

CMComponent

Since classCMComponentis a central class of our software architecture, we will discuss it further. The most important task of the class is the generation of XML. It provides methods to render all constructs of OMS Java as XML elements. There are two methods, that will produce an XML representation.

toXMLElement() This method converts the given component object into an XML ele-ment namedwebobject. Then it adds all attributes of the component asproperty elements to the representation. The associated content object are included next and finally the method checks for the presence of a special content attribute that will be appended if present. This method is used whenever the full representation of an object is required.

toXMLSummary() As suggested by the name of this method, it only produces a summari-zed representation of the component. This representation includes the content objects, but leaves out the attributes and possible special content objects. This is used to save space when the omitted data is not required.

Again there is a small difference to the document type definition used normally in the OMS Java framework. The attribute name of a component is not only represented as aproperty element as required by this DTD, but is also included as an attribute to the webobject element. This shortcut has been introduced to make references to such components from within templates easier.

Another important feature is the handling of the associated content objects. There are two methods involved in this task. There is a number of methods to retrieve content objects from the database and append them to the XML representation. Most important however is the method setAttributeValuewhich deals with setting attributes values for this object.

This method had to be modified in order to allow correct updates of the content objects. The problem here is, that the client who sends the updates does not know about the separation of component and content. Consequently the component has to delegate the update affecting its content to the appropriate content object.

Finally there is one important method, that has to be called to include the associated template of a component into the stylesheet. The methodinsertXSLTemplatefirst tries to retrieve the template from the database. If the attempt is successful (i.e. if there is a default template), the template will be included in the stylesheet if not already present. This method has to be called whenever a component is rendered to XML, or else the server will not be able to transform it for the target platform.

CMContainer

ClassCMContaineris discussed here to show how the process of generating XML has been modified to incorporate the concept of a container. The main novelty is the inclusion of the components associated as children of the container. This process begins after the rendering of the common properties of a component, which is done by a call to the superclass’ version oftoXMLElement().

After these data has been included, methodaddChildren()starts with creating the special component element to which it appends all the contained components. To respect the order given to the container by the according attribute, it first tries to include the components specified in this ranking. Only then are the remaining components included.

Similar to its ancestorCMComponent, this class defines a method to handle the inclusion of templates. As there can be a special, context dependent template associated with component contained in a container, methodinsertContainerXSLTemplate()has to be called whenever a component is added to the XML representation of a container. To cater for the case that there is no such template, the method also tries to find a default template as fall-back value.

CMMixed

This class representing the data type mixed content is a special case of a container. The semantics of the represented data type however made it necessary to change the process of XML generation further. As described, mixed content in our system is a string with references to other components, that should be embedded into the text. This requirement means, that the components in the container (i.e. the referenced objects) do not need to be appended to the container, but have to be inlined into the text.

To implement this behaviour, methodaddContents()in charge of adding the associated contents to an arbitrary component has been overwritten to add the mixed content object and at the same time inline the referenced components. Method inlineObjects() is responsible for parsing the text, finding the referenced objects and inlining them into the text. Note that to prevent the objects from being added to the container as well, method addChildren()is overridden and left blank.

CMContent

Content objects are represented by instances of class CMContent and its subclasses. To influence how the attributes of the content object are included into the representation of the XML element of the component, there is the methodappendXMLElements(). When creating the XML element the component will call this method with the element as parameter to allow the component to insert its properties. In this way, the separation of the component

and its content can be made transparent to the client while still allowing the content object to decide by itself how its going to be rendered.

CMWorkflowGatekeeper

Although the concept of gatekeepers is a simple one, the special case of the workflow gate-keeper deserves some explanation. To show how the gategate-keeper works, we introduce a small example. First of all there has to be a sample workflow. For the sake of the example we choose the very simple case shown in figure 4.2.

Figure 4.2: Sample Workflow

An object in a system having this workflow can have the following life cycle. When the object is created and worked on by its author, it is in state Test. As soon as the object is ready for publishing, the author migrates it to state Approval. Now it can be approved by the author’s supervisor and moved to state Approved or Rejected. Objects in state Approved are the only objects visible to the client. Components having state Rejected are sent back into the control of their author to be modified according to the specification of the supervisor.

This requirement is enforced by the workflow gatekeeper. To classify which states allow a component to pass the gatekeeper, classCMWorkflowGatekeeperprovides three collec-tions as attributes. These collection serve to specify which workflow state should be visible to what group of people. The three collections are owner, supervisor and browser. Components having a workflow state in the first collection are visible to the author only. The second collection contains the workflow states of the objects visible to the supervisor and the ow-ner. Collection browser contains the workflow states of the components visible to everyone.

In our example we would insert state Approved into collection browser, to get the describe behaviour.

When checking a component, the workflow gatekeeper retrieves all workflow states associa-ted with the object from the database and ensures that at least one of these states is contained in the collection browser. If this condition holds the object passes the gatekeeper and is included in the XML document. Although this concept supports personalized views of the website for different users, this concept has not been implemented since a mechanism for user management and object ownership is not yet provided by the OMS Java framework.

CMDBUtils

Class CMDBUtilis a collection of useful methods that implement often used functionality which cannot be attributed to one single object type. These methods are described here in

detail.

ensureType() This method is used to ensure that the value of a given attribute matches the type expected by the OMS Java framework. Since the method is used when upda-ting the database, the value is given as a string found in the parameter list of the update request. If the value expected by the object management system is not of type string, the method will convert the string to the required type using the reflection application programming interface.

getAttribute() Given an OMS Java instance and an attribute name, this method will try to find the object representing the according attribute. This should not be confused with the lookup of the value of the attribute.

getXSLTemplates() There are two versions of this method at the moment. The first with one parameter retrieves the default template associated with an object. The second is given a container as a second argument and thus will retrieve the context dependent template associated with the component.

getBestLanguage() The task of this method is to calculate the best possible language among a collection of languages. It is given a default language, that is configured for the website and the desired language stated in the request by the user-agent. As languages consist of a language together with a country, there is the possibility that the request is over- or underspecified. The method first tries to find an exact match. If this fails, it tries to find a language available, that matches the language part only. Finally the last resort is to check if the default language is present and return that language.

lookupPage() Looks up a page based on a given path and a separator char. The method returns a so-called page context containing the page, if found, its directory and the parent directory of the page’s directory.

lookupDirectory() This method looks up a directory given by its name. There are two versions of the method one searching through all directories and one that takes a collection of directories it should search in. The second version is for instance used to look up a directory among the subdirectories of the current directory.

vectorizeCollection() Takes a collection and constructs a vector with the elements contained in the collection. This is used, when rendering the components of a container according to the order attribute. As described this is a two phase process. First the components for which the order is known will be rendered. Then the remaining components are included in the XML document. To be able to tell which components have been rendered using theorderattribute, we construct a vector using this method and remove all elements, after being included in the document. At the end, the vector contains only the remaining components for which no order has been specified. By traversing the vector they will be appended to the document as well.

getTypeString() This utility method returns the name of the type of a template when given the according mime type. It is used to map the mime types requested by the user-agent to types in the database. This method will have to be changed, when extending the system to further template types in the future.