ODFDOMCodeGenerator

From Apache OpenOffice Wiki
Jump to: navigation, search

The ODFDOMCodeGenerator is a java application to create source code for elements and attributes that are defined using relaxng schema. It is used in the ODFDOM project to generate the java source files for the elements available in the OpenDocument format.

Usage

To generate source code files, start the application with

  java -jar ODFDOMCodeGenerator.jar your-schema.rng your-config.xml your-template.xml /your/target/directory

Please not, if you use the ODFDOM project, you can change the setting 'gen-flat-odf-schema' inside the user.properties file to 'true' and the next build will use the 'schema/OpenDocument-schema-v1.1.rng' schema, the 'codegen/config.xml' config file, the 'codegen/javacodetemplate.xml' template file and the src directory of the project as the target directory. This will override all generated code files in your project.

The config file

The config file must be an xml file with the following structure

  <?xml version="1.0" encoding="UTF-8"?>
  <config>
  <elements>
  <element .../>
  <element .../>
  ...
  </elements>
  <data-types>
  <data .../>
  <data .../>
  ...
  </data-types>
  <attributes>
  <attribute .../>
  <attribute .../>
  <attribute .../>
  ...
  </attributes>
  </config>

Element

The <element> element supports the following attributes

Name

The mandatory attribute 'name' selects the element from the relaxng schema with its qualified name (qname).

Rename

The optional attribute 'rename' changes the variable 'elementname' for this element. This can be used f.e. to give an element like <text:a> a more readable implementation name like <text:anchor>

Base

The optional attribute 'base' changes the variable 'elementbasename' for this element.

Family

The optional attribute 'family' changes the variable 'elementstylefamily' for this element.

Attribute

The <attribute> element supports the following attributes

Name

The mandatory attribute 'name' selects the attribute from the relaxng schema with its qname.

Element

The optional attribute 'element' selects only the attributes with the qname given by the attribute 'name' with the elements qname.

Rename

The optional attribute 'rename' changes the variable 'attributename' for the selected attributes. This can be used f.e. to avoid generating getter/setter methods which names collide with base class methods.

Type-name

The optional attribute 'type-name' changes the variable 'conversiontype' for the selected attributes. This can be used f.e. to have different attributes from multiple elements with the same defined values to use a shared class for conversions.

Data

The <data> element supports the following attributes

Name

The mandatory attribute 'name' selects the data type by its qname. Data types are the types defined in the relaxng schema by the <data> elements inside the <attribute> element. The name can also be the name of a <ref> element. In that case the processing of the relaxng schema stops at this <ref> element and the configuration from this element is used.

Value-type

The mandatory attribute 'value-type' changes the variable 'valuetype' for attributes using this data-type.

Conversion-type

The optional attribute 'conversion-type' changes the variable 'conversion-type' for attributes using this data-type. If this attribute is not available, the variable 'conversion-type' will have the same value as the variable 'valuetype'.

The template file

The template file must be a valid xml file with the element <template> as the root element. It can contain the following elements

Code

The <code> element outputs the characters inside this element to the current output file. The characters are scanned for expressions before written to the file.

<code>
  // this element generates a comment
</code>  

Define

The <define> element does not execute its child elements but remembers them with the given name for later use with the <ref> element.

The mandatory attribute 'name' gives the name for this define.

<define name="header">
  <code>
  // This file uses the gpl
  // Do not edit this file as it is automaticaly generated!
  </code>
</define>

Ref

The <ref> element executes the child elements of a <define> element with the same name.

The mandatory attribute 'name' selects the <define> by its attribute 'name'.

  <ref name="header"/>

If

The <if> element executes its child elements only if the evaluated expression from its attribute 'test' is a non empty string and not the string constant 'false'.

The mandatory attribute 'test' is evaluated as an expression.

  <if test="elementname='text:a'>
  <code>
    // interface for links
    public String getLink();
    public void setLink( String newLink );
  </code>
  </if>

Else

The <else> element is always ignored, except if it is a child element inside an <if> element and the test attribute was evaluated to 'false' or an empty string.

  <if test="elementbasename=''">
  <code>
  class %{elementname} extends DefaultElement
  </code>
  <else>
  <code>
  class %{elementname} extends %{elementbasename}
  </code>
  </else>
  </if>

Set

The <set> element changes all variables with the names of the given attributes to their values. The values are scanned for expressions before assignement.

  <set elementname="Hyperlink"/>
  <set elementclassname="Odf%{elementname}Element"/>
  <code>
  class %{elementclassname} extends OdfElement
  {
  }
  </code>

will output

  class OdfHyperlinkElement extends OdfElement
  {
  }

Foreach

The <foreach> element executes its child elements once for all objects of the given type from the relaxng schema.

The mandatory attribute 'type' must have one of the following values

'element'

All elements that are defined in the relaxng are iterated. For each element the following variables will be set

  • 'elementqname' is the qualified name of the current element.
  • 'elementname' is the same as 'elementqname' by default. The configuration file can override this.
  • 'elementstylefamily' is empty by default. The configuration file can override this.

'attribute'

All attributes of the currently selected element as defined in the relaxng schema are iterated. For each attribute the following variables will be set

  • 'attributeqname' is the qualified name of the current attribute
  • 'attributename' is the same as 'attributeqname' by default. The configuration file can override this.
  • 'valuetype' is the data type of the <data> element for this attribute. If this attribute is defined by <value> elements, it is set to 'enum'. The configuration file can override this.
  • 'conversiontype' is the same as 'valuetype' by default. The configuration file can override this.
  • 'defaultvalue' is the default value for this attribute as defined by the relaxng schema.

'value'

All values for the currently selected atteribute as defined in the relaxng schmea are iterated. For each value the following variable 'value' will be set. This only works for attributes that are defined using <value> elements in the relaxng schema.

'namespace'

All namespaces used in the relaxng schema are iterated. For each namespace the following variables will be set

  • 'namespaceprefix' is the prefix of the current namespace
  • 'namespaceuri' is the uri of the current namespace

Select

The <select> element works the same as the <foreach> element but instead of iterating all objects of the given type it selects only one object by its qname with the mandatory attribute 'name'. Can only be used for types 'element', 'attribute' and 'namespace'.

File

The <file> element opens a new text file for writing. The following attributes are supported

Path

The mandatory attribute 'path' specifies the path of the new file.

Name

The mandatory attribute 'name' specifies the name of the new file.

Extension

The mandatory attribute 'extension' specifies the extension of the new file.

Expressions

Expressions can be part of characters inside <code> elements and inside some attributes. If embedded inside other text they are distinguished by putting them inside %{...} constructs. Expressions can contain variable names, contant strings, operators and functions

Variables

Variables must start with a us-ascii character ('a-z' or 'A-Z) or one of the following characters '_' '.' and contain more of the same characters and also digits.

The following example

  <set testvar="World"/>  
  <code>Hello %{testvar}!</code>

outputs

Hello World!  

Constant strings

Constand strings must be delimeted by either ' or " like c++ or java strings.

The following example

  <set testvar="yes"/>
  <if test="testvar='yes'">
  <code>
  Yes!
  </code>
  <else>
  <code>
  No!
  </code>
  </else>
  </if>

outputs

  Yes!

Operators

The following operators are supported (given from lowest to highes priority)

not

The not operator returns 'true' of the following string expression is not empty and not 'false' or 'false' otherwise.

The following example

  <set testvar="yes"/>
  <code>
  %{ testvar } or %{ not testvar }
  </code>

outputs

  yes or false

+

The + operator concatenates two string expressions.

The following example

  <code>
  %{ 'Hello' + ' ' + "World" + "!" }
  </code>

outputs

  Hello World!

or

The or operator returns 'true' if the previous string expression is not empty and not 'false' or the next string expression is not empty and not 'false'.

  <code>
  %{ 'true' or 'false' }
  </code>

outputs

  true

and

The or operator returns 'true' if the previous string expression is not empty and not 'false' and the next string expression is not empty and not 'false'.

  <code>
  %{ 'true' and 'false' }
  %{ 'true' and 'true' }
  </code>

outputs

  false
  true

Equals

The '=' operator returns 'true' if the previous string expression is equal to the next string expression or 'false' otherwise.

  <code>
  %{ 'true' = 'false' }
  %{ 'hello' = 'hello' }
  </code>

outputs

  false
  true

Unequals

The '!=' operator returns 'false' if the previous string expression is equal to the next string expression or 'true' otherwise.

  <code>
  %{ 'true' != 'false' }
  %{ 'hello' != 'hello' }
  </code>

outputs

  true
  false

Functions

Functions start with a name followed by a pair of brackets with a list of coma seperated parameters inside. The following functions are supported

toupper

The function toupper returns the given string as an upercase version

  <code>
  %{ toupper('true') }
  </code>

outputs

  TRUE

tolower

The function tolower returns the given string as a lowercase version.

  <code>
  %{ toupper('TRUE') }
  </code>

outputs

  true

prefix

The function 'prefix' returns the namespace prefix from a qualified name.

local_name

The function 'local_name' returns the local name from a qualified name.

  <set qname='text:section'/>
  <code>
  %{ prefix(qname) }
  %{ local_name(qname) }
  </code>

outputs

  text
  section

identifier

The function 'identifier' converts the given string into a valid java/c++ identifier. If the given string is a qualified name, it first removes the prefix. Then all '-' Characters will be removed and all characters following '-' will be converted to upercase. If the result begins with a non valid character, a '_' will be inserted as the first character.

  <set qname='text:section'/>
  <code>
  %{ identifier('text:anchor-position') }
  %{ identifier('300') }
  </code>

outputs

  AnchorPosition
  _300

endswith

The function 'endswith' returns true if the first parameter ends with the second.

  <code>
  %{ endswith('foobar','bar') }
  %{ endswith('foobar','foo') }
  </code>

outputs

  true
  false

startswith

The function 'startswith' returns true if the first parameter starts with the second.

  <code>
  %{ startswith('foobar','bar') }
  %{ startswith('foobar','foo') }
  </code>

outputs

  false
  true

startswith

The function 'startswith' returns true if the first parameter starts with the second.

  <code>
  %{ startswith('foobar','bar') }
  %{ startswith('foobar','foo') }
  </code>

outputs

  false
  true

replace

The function 'replace' replaces all occurrences of the first parameter with the second parameter inside the third parameter.

  <code>
  %{ replace('USA','World','Hello USA!') }
  </code>

outputs

  Hello World!
Personal tools