Difference between revisions of "SiDIFTemplates"

From BITPlan royal-family Wiki
Jump to navigation Jump to search
(transfered by WikiBackup wikiTask at 2017-10-03T16:43:22Z)
 
m (transfered by WikiBackup wikiTask at 2019-10-10T16:22:34Z)
 
(9 intermediate revisions by the same user not shown)
Line 36: Line 36:
 
@// show the wikiDocumentation for this category
 
@// show the wikiDocumentation for this category
 
{{#ask: [[Topic name::@(topic.name)]] | ?Topic wikiDocumentation= | mainlabel=-}}
 
{{#ask: [[Topic name::@(topic.name)]] | ?Topic wikiDocumentation= | mainlabel=-}}
@(topic.pluralName) may be added and edited with the form [[has default form::@(topic.name)]]
+
@(topic.pluralName) may be added and edited with the form [[Form:@(topic.name)]]
 
* [[List of @(topic.pluralName)]]
 
* [[List of @(topic.pluralName)]]
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:1024px">
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:1024px">
Line 69: Line 69:
 
== @topic.pluralName ==
 
== @topic.pluralName ==
 
{{#forminput:form=@topic.name|button text=add @topic.name}}
 
{{#forminput:form=@topic.name|button text=add @topic.name}}
 +
{{#ask: [[Concept:@topic.name]]|format=count}} @topic.pluralName:
 
@("{{")#ask: [[Concept:@topic.name]]
 
@("{{")#ask: [[Concept:@topic.name]]
 +
|mainlabel=@(topic.name)
 
@for (Property property:topic.propertiesByIndex()) {
 
@for (Property property:topic.propertiesByIndex()) {
 
| ?@topic.name @(property.name) = @property.name
 
| ?@topic.name @(property.name) = @property.name
 
}
 
}
 
@askSort(topic)
 
@askSort(topic)
 +
| limit=@topic.listLimit
 
@("}}")
 
@("}}")
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:1024px">
 
<div class="toccolours mw-collapsible mw-collapsed" style="width:1024px">
Line 350: Line 353:
 
@("}}")@//#switch
 
@("}}")@//#switch
 
@("{{#switch:") {{{viewmode|}}}
 
@("{{#switch:") {{{viewmode|}}}
 +
|hidden=
 
|masterdetail=
 
|masterdetail=
 
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
 
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
Line 389: Line 393:
 
@// do not add subobjects to category - this would make selecting the default form difficult
 
@// do not add subobjects to category - this would make selecting the default form difficult
 
@if ("property".equals(topic.defaultstoremode)) {
 
@if ("property".equals(topic.defaultstoremode)) {
[[Category:@topic.name]]
+
[[Category:@(topic.name)]]@("{{#default_form:")@(topic.name)@("}}")
 
}
 
}
 
}
 
}
Line 495: Line 499:
  
 
     /**
 
     /**
     * get the propertySidif of the given property
+
     * get the SiDIF representation of the given property
 
     *  
 
     *  
     * @@param name
+
     * @@param name - the name of the property
     * @@param value
+
     * @@param value - the value of the property
     * @@return
+
    * @@param type - the type of the property
 +
     * @@return - the SiDIF Sting representation of the property
 
     */
 
     */
 
     public static String propertySiDIF(String name, String value, String type) {
 
     public static String propertySiDIF(String name, String value, String type) {
       // default is an empty string - no property line for emtpy values
+
       // default is a comment line which can be filled by uncommenting
       String result = "";
+
       String result = String.format("# is is %s of it\n",name);;
 
       // if the value is not empty
 
       // if the value is not empty
 
       if ((value != null) && (!("".equals(value.trim())))) {
 
       if ((value != null) && (!("".equals(value.trim())))) {
Line 514: Line 519:
 
         // create a SIDIF Property line like
 
         // create a SIDIF Property line like
 
         // "John" is lastname of it
 
         // "John" is lastname of it
         result += quote + value + quote + " is " + name + " of it\n";
+
         // convert double quotes to single quotes - FIXME - should we escape instead?
 +
        value=value.replace("\"","'");
 +
        result = String.format("%s%s%s is %s of it\n",quote,value,quote,name);
 
       }
 
       }
 
       // return the SiDIF property line
 
       // return the SiDIF property line
Line 575: Line 582:
 
     /**
 
     /**
 
     * convert this @topic.name to a WikiSon string
 
     * convert this @topic.name to a WikiSon string
 +
    * @@return the WikiSon representation of this @(topic.name)
 
     */
 
     */
 
     public String toWikiSon() {
 
     public String toWikiSon() {
Line 583: Line 591:
 
       wikison+="}}\n";
 
       wikison+="}}\n";
 
       return wikison;
 
       return wikison;
 +
    }
 +
 +
    /**
 +
    * convert this @topic.name to a SiDIF string
 +
    * @@return the SiDIF representation of this @(topic.name)
 +
    */
 +
    public String toSiDIF() {
 +
      String siDIF = String.format("%s isA @(topic.name)\n",this.pageid);
 +
@for(Property property:topic.getProperties()) {
 +
      siDIF+=propertySiDIF("@(property.name)",@(property.name),"@(property.type)");
 +
}
 +
      return siDIF;
 
     }
 
     }
 
   
 
   
Line 708: Line 728:
 
}
 
}
 
@javacode(context)
 
@javacode(context)
 +
@("<")@("/source>")
 
</source>
 
</source>
  
Line 781: Line 802:
 
|topic=Concept:@topic.pageid
 
|topic=Concept:@topic.pageid
 
@("}}")
 
@("}}")
[[has default form::Property]]
 
 
This is a Property with type @("{{#show: {{FULLPAGENAMEE}} | ?Property type#- }}")
 
This is a Property with type @("{{#show: {{FULLPAGENAMEE}} | ?Property type#- }}")
 
</pre>
 
</pre>
Line 813: Line 833:
 
@// macro to show BITPlan copyright
 
@// macro to show BITPlan copyright
 
@def copyright() {<!--
 
@def copyright() {<!--
   -- Copyright (C) 2015-2016 BITPlan GmbH
+
   -- Copyright (C) 2015-2019 BITPlan GmbH
 
   --  
 
   --  
 
   -- Pater-Delp-Str. -- 1
 
   -- Pater-Delp-Str. -- 1
Line 926: Line 946:
 
@def bitplanumlci(int fontSize) {
 
@def bitplanumlci(int fontSize) {
 
' BITPlan Corporate identity skin params
 
' BITPlan Corporate identity skin params
' Copyright (c) 2015-2016 BITPlan GmbH
+
' Copyright (c) 2015-2017 BITPlan GmbH
 
' see http://wiki.bitplan.com/PlantUmlSkinParams#BITPlanCI
 
' see http://wiki.bitplan.com/PlantUmlSkinParams#BITPlanCI
 
' skinparams generated by com.bitplan.restmodelmanager
 
' skinparams generated by com.bitplan.restmodelmanager
Line 959: Line 979:
 
title @topic.name
 
title @topic.name
 
note as @(topic.name)DiagramNote
 
note as @(topic.name)DiagramNote
Copyright (c) 2015-2016 BITPlan GmbH
+
Copyright (c) 2015-2017 BITPlan GmbH
 
[[http://www.bitplan.com]]
 
[[http://www.bitplan.com]]
 
end note
 
end note

Latest revision as of 17:22, 10 October 2019

Overview

This page contains Simple Data Interchange Format (SiDIF) templates. These templates can be used as a template for a Template:Wikitask. For convenience there is a template Template:TopicWikitasks that creates a set of wikitasks for some of the templates below.

Templates

category

@include(wiki.SiDIFTemplates.defs)
@// macro to create pageschema from simela triples 
@def pageschema(Topic topic) {
@escape("xml") {
<PageSchema>
  <semanticforms_Form name="@topic.name">
    <standardInputs freeTextLabel="Free text"/>
  </semanticforms_Form>
  <Template name="@topic.name" format="standard">
  @for (Property property:topic.propertiesByIndex()) {
    <Field name="@property.name">
      <semanticforms_FormInput>
        <InputType>text</InputType>
      </semanticforms_FormInput>
      <semanticmediawiki_Property name="@(topic.name) @(property.name)">
        <Type>Text</Type>
      </semanticmediawiki_Property>
    </Field>
  }
  </Template>
</PageSchema>
}
}
@// generate the category for the given topic
@def category(Topic topic) {
__NOTOC__
@// show the wikiDocumentation for this category
{{#ask: [[Topic name::@(topic.name)]] | ?Topic wikiDocumentation= | mainlabel=-}}
@(topic.pluralName) may be added and edited with the form [[Form:@(topic.name)]]
* [[List of @(topic.pluralName)]]
<div class="toccolours mw-collapsible mw-collapsed" style="width:1024px">
@topic.name @(i18n("description"))
<div class="mw-collapsible-content">
@uml("uml",topic)
* [[Help:@topic.name]]
* [[Concept:@topic.name]]
* [[:Template:@topic.name]]
* [[:Form:@topic.name]]
=== Properties ===
@for (Property property:topic.propertiesByIndex()) {
* [[Property:@(topic.name) @(property.name)]]
}
</div>
</div>
}
@// contextSetting handling
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@category(contextSetting.getMaintopic())

listof

@include(wiki.SiDIFTemplates.defs)
@// generate the list of page for the given topic
@def listof(Topic topic) { 
__NOCACHE__
@topicheader(topic)
== @topic.pluralName ==
{{#forminput:form=@topic.name|button text=add @topic.name}}
{{#ask: [[Concept:@topic.name]]|format=count}} @topic.pluralName:
@("{{")#ask: [[Concept:@topic.name]]
|mainlabel=@(topic.name)
@for (Property property:topic.propertiesByIndex()) {
| ?@topic.name @(property.name) = @property.name
}
@askSort(topic)
| limit=@topic.listLimit
@("}}")
<div class="toccolours mw-collapsible mw-collapsed" style="width:1024px">
=== SiDIF ===
<div class="mw-collapsible-content">
@("{{")#ask: [[Concept:@topic.name]]
| ?#=pageid
@for (Property property:topic.propertiesByIndex()) {
| ?@topic.name @property.name = @property.name
}
| mainlabel=-
| format=template
| named args=yes
| template=@topic.name
| userparam=sidif
| limit=@topic.listLimit
@("}}")
</div>
</div>
[[:Category:@topic.name]]
}
@// contextSetting handling
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@listof(contextSetting.getMaintopic())

concept

@include(wiki.SiDIFTemplates.defs)
@// generate the given topic as a concept
@def topic(Topic topic) {
__NOCACHE__
@("{{")Topic
|name=@topic.name
|pluralName=@if (topic.pluralName) {@(topic.pluralName)} else { @(topic.name)s }
|icon=@topic.icon
|iconUrl=@topic.iconUrl
|documentation=@topic.documentation
|wikiDocumentation=@topic.wikiDocumentation
|defaultstoremode=@topic.defaultstoremode
|listLimit=@topic.listLimit
|cargo=@topic.cargo
|context=@topic.context
|storemode=property
@("}}")
@("{{")Topic
|viewmode=masterdetail
|storemode=none
@("}}")
{{#forminput:form=Property|button text=add Property}}
=== Documentation ===
@topic.wikiDocumentation
@uml("uml",topic)

@("{{")#concept:
@if (topic.conceptProperty) {
 [[@(topic.name) @(topic.conceptProperty.name)::+]]
} else {
 [[Category:@topic.name]]
}
 |@(topic.pluralName)
@seealso(topic)
@("}}")
[[Category:@topic.name]]
}
@// contextSetting handling
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@topic(contextSetting.getMaintopic())

propertiesdefs

@include(wiki.SiDIFTemplates.defs)
@// properties for a specific Topic
@def property(Topic topic, Property property) {
@{
  String topicWithConcept=topic.pageid;
  if (topicWithConcept.startsWith("Konzept:")) {
    topicWithConcept=topicWithConcept.replace("Konzept:","Concept:");
  }
  if (!topicWithConcept.startsWith("Concept:")) {
     topicWithConcept="Concept:"+topicWithConcept;
  }
}
@("{{")Property
|name=@property.name
|label=@property.label
|documentation=@property.documentation
|type=Special:Types/@property.type
|index=@property.index
|sortPos=@property.sortPos
|primaryKey=@property.primaryKey
|mandatory=@property.mandatory
|namespace=@property.namespace
|size=@property.size
|uploadable=@property.uploadable
|defaultValue=@property.defaultValue
|inputType=@property.inputType
|allowedValues=@property.allowedValues
|values_from=@property.values_from
|showInGrid=@property.showInGrid
|isLink=@property.isLink
|topic=@(topicWithConcept)
|storemode=property
@("}}")
[[Has type::@property.type]]
This is a Property with type @("{{#show: {{FULLPAGENAMEE}} | ?Property type#- }}")
}
@// properties for the given topic
@def properties(Topic topic) {
== properties of @(topic.name) ==
@for (Property property:topic.getProperties()) {
=== [[Property:@(topic.name) @(property.name)]] ===
<pre>
@(property(topic,property))
</pre>
}
}

properties

@include(wiki.SiDIFTemplates.propertiesdefs)
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@properties(contextSetting.getMaintopic())

instances

@// This is a rythm template
@// the args are the standard wikiTask arguments
@import org.sidif.triple.TripleQuery
@import org.sidif.triple.Triple
@args() {
  String title 
  String logo
  org.sidif.wiki.WikiTask wikiTask
  org.sidif.triple.TripleStore tripleStore
}
@// here some java code is declared and executed
@// the resulting variables can be used as template variables later
@{
 TripleQuery query=tripleStore.query();
 TripleQuery topics=query.query(null,"isA","Topic");
 String maintopic=wikiTask.getParams();
}
@def wikison(TripleQuery query,String topicName, String name) {
@("{{")@topicName
@{ TripleQuery properties=query.query(name,null,null) }
|name=@name
@for (Triple property:properties.getTriples()) {
|@property.getPredicate()=@property.getObject()
}
|storeMode=subobject
@("}}")
}
@def wikison1toN(TripleQuery query,String topicName,String link,String linkTopicName) {
@{TripleQuery instances=query.query(null,"isA",topicName) }
@for (Triple instance:instances.getTriples()) {
@wikison(query,topicName,instance.getSubject().toString())
@{TripleQuery linstances=query.query(null,link,instance.getSubject().toString()) }
  @for (Triple linstance:linstances.getTriples()) {
   @wikison(query,linkTopicName,linstance.getSubject().toString())
  }
}
}
@wikison1toN(query,maintopic,"answer","ZAnswer")
[[Category:@maintopic]]

form

@include(wiki.SiDIFTemplates.defs)
@// generate a level 1 section to use the headertabs feature
@def headerTabSection(Topic masterTopic,String title) {
@if (masterTopic.withHeaderTabs()) {
@("{{{section")|@(title)|level=1|hidden@("}}}")
= @(title) =
}
}
@// get the multiple String
@// generate the form for the given topic
@def form(Topic topic) {
<noinclude>
This is the @("{{smartMediaWiki}}")-Form for "@(topic.name)".

Create a new @(topic.name) by entering a new pagename for a @(topic.name)
into the field below. 

If you enter an existing @(topic.name) pagename - you will edit the @(topic.name)
with that pagename.
@("{{")#forminput:form=@(topic.name)|values from concept=@(topic.name)@("}}")
</noinclude><includeonly>
<div id="wikiPreview" style="display: none; padding-bottom: 25px; margin-bottom: 25px; border-bottom: 1px solid #AAAAAA;"></div>
@headerTabSection(topic,topic.name)
@formtemplate(topic,"subobject".equals(topic.defaultstoremode))
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
@if ((topicLink.targetTopic!=null) && ("true".equals(topicLink.targetMultiple))) {
@headerTabSection(topic,topicLink.targetRole)
@formtemplate(topicLink.targetTopic,"true".equals(topicLink.targetMultiple))
}
}
@if (topic.withHeaderTabs()) {
<headertabs/>
}
@("{{{section|Freitext|level=1|hidden}}}")
=Freitext=
@("{{{standard input|free text|rows=10}}}")
@("{{{standard input|summary}}}")

@("{{{standard input|changes}}}")

@("{{{standard input|save}}}")
@("{{{standard input|cancel}}}")
</includeonly>
}@// avoid newline
@// contextSetting handling
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@form(contextSetting.getMaintopic())

template

@include(wiki.SiDIFTemplates.defs)
@// show the given property Label
@def String propertyLabel(Property property) {
  if ((property.label!=null) && (!"".equals(property.label.trim()))) {return property.label;} else {return property.name;}
}
@// show the given Property
@def showProperty(Property property) {
@{ 
   String linkPre=""; 
   String linkPost="";
   String namespace=""; 
   if ((property.type!=null) && (property.type.endsWith("Page"))) { linkPre="[[";linkPost="]]";}
   // do not do namespace handling at this time
   // use map namespace from mediawik-japi!
   // if (property.namespace!=null)  { namespace=property.namespace+":";}
}@{{#if:{{{@(property.name)|}}}|@(linkPre)@(namespace)@("{{{")@(property.name)@("|}}}")@(linkPost)|}}
}
@// set the given Property
@def setProperty(Property property){
@(property.name)=@("{{{")@(property.name)|@("}}}")
}
@// sidif - newline relevant
@def sidif(Topic topic) {
@("{{#if:{{{?pageid|}}}|{{#replace:{{#replace:{{{?pageid}}}|#|}}|-|_}}") isA @(topic.name)<br>@("|}}")@for (Property property:topic.propertiesByIndex()){@// avoid newline
@("{{#if:{{{")?@(property.name)@("|}}}|")"@("{{{")?@(property.name)@("}}}")" is @property.name of it <br>|@("}}")}
}

@// includeonly part of wiki template
@def includeonly(Topic topic, boolean withComment) {
@("{{#switch:"){{{userparam|}}}|sidif=@sidif(topic)
|#default=@("{{#switch:"){{{storemode|}}}
|none=
|subobject=@("{{#subobject:-")
|isA=@(topic.name)
@for (Property property:topic.propertiesByIndex()) {
|@(topic.name) @setProperty(property)
}
@("}}")@//#subobject
|#default=@("{{#set:")
|isA=@(topic.name)
@for (Property property:topic.propertiesByIndex()) {
|@topic.name @setProperty(property)
}
@("}}")@//#set
@("}}")@//#switch
@("{{#switch:") {{{viewmode|}}}
|hidden=
|masterdetail=
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
@if (topicLink.targetTopic) {
= @(topicLink.targetRole) =
@("{{")#ask:[[Concept:@(topicLink.targetTopic.name)]][[@(topicLink.targetTopic.name) @(topicLink.sourceRole)::@("{{FULLPAGENAME}}")]]
@for (Property property:topicLink.targetTopic.propertiesByIndex()) {
| ?@(topicLink.targetTopic.name) @property.name = @property.name
}
@askSort(topicLink.targetTopic)
@("}}")
}
}
|tableheader=@("{{{!}}") class='wikitable'
@{String delim="!";}
@for (Property property:topic.propertiesByIndex()) {@(delim)@(property.name)@{delim="!!";}}
@("\n{{!}}-")
|tablerow=
@{delim="{{!}}"}
@for (Property property:topic.propertiesByIndex()) {@(delim){{{@(property.name)|}}}@{delim="{{!}}{{!}}"}}
@("\n{{!}}-")
|tablefooter=@("{{!}}}")
|labelfield=
@for (Property property:topic.propertiesByIndex()) {@(property.name)=@(showProperty(property))<br>}
|#default=@("{{{!}}") class='wikitable'
! colspan='2' @("{{!}}")@(topic.name)
@("{{!}}-")
@("{{#switch:"){{{storemode|}}}|property=
! colspan='2' style='text-align:left' {{!}} {{Icon|name=edit|size=24}}{{Link|target=Special:FormEdit/@(topic.name)/{{FULLPAGENAME}}|title=edit}}
@("{{!}}-")
@("}}")
@for (Property property:topic.propertiesByIndex()) {@("!")@(propertyLabel(property))
@("{{!}}")&nbsp;@(showProperty(property))
@("{{!}}")-
}
@("{{!}}}")
@("}}")@//#switch
@("}}")@//#switch
@// do not add subobjects to category - this would make selecting the default form difficult
@if ("property".equals(topic.defaultstoremode)) {
[[Category:@(topic.name)]]@("{{#default_form:")@(topic.name)@("}}")
}
}
@// wikiSonUsage
@def wikiSonUsage(Topic topic,String modeLine) {
<pre>@("{{")@topic.name
@for (Property property:topic.propertiesByIndex()) {
|@property.name=
}
|@modeLine
@("}}")
</pre>
}@// avoid newline
@// noinclude part of wiki template
@def noinclude(Topic topic) {
This is the template {{Link|target=Template:@topic.name|title=@topic.name}}.
It belongs to the concept/topic {{Link|target=:Concept:@topic.name}}<br>
You may find examples for the use of this template via the {{Link|target=List of @(topic.pluralName)}}.
=== Usage ===
@{ String[] storeModes={"subobject","property","none"};}
@for (String storeMode:storeModes) {
==== storemode @storeMode ====
@wikiSonUsage(topic,"storemode="+storeMode)
}
@{ String[] viewModes={"tableheader","tablerow","tablefooter","labelfield"};}
@for (String viewMode:viewModes) {
==== viewmode @viewMode ====
@wikiSonUsage(topic,"viewmode="+viewMode)
}
=== Source (pretty printed) ===
@("<source") lang='html4strict'>
@includeonly(topic,true)
@("<")@("/source>")
=== Source ===
Click on "Edit" to edit the noinclude-part Source of this Template.
[[Category:Template]]
}@// avoid newline
@def template(Topic maintopic) {<noinclude>
@copyright()
@noinclude(maintopic)
</noinclude><includeonly>@includeonly(maintopic,false)</includeonly>}@// avoid newline
@// contextSetting handling
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@template(contextSetting.getMaintopic())

javacodegen

@include(wiki.SiDIFTemplates.defs)
=== java code ===
@("<source lang='java' id='javacode'>")
@verbatim() {
@// This is a rythm template
@// the args are the standard wikiTask arguments
@import org.sidif.triple.TripleQuery
@import org.sidif.triple.Triple
@import com.alibaba.fastjson.JSON
@args() {
  String title 
  String logo
  org.sidif.wiki.WikiTask wikiTask
  org.sidif.triple.TripleStore tripleStore
}
}
@// user code section
@// smartGenerator compatible like:
@// // >>>{User defined import section}{::com::bitplan::ooa::OOAAssociation}{S37C96C0C016C}
@def printUserCode(String codetype,String key,String modelID) {

    // >>>@("{")@(codetype)@("}")@("{")@(key)@("}")@("{")@(modelID)@("}")
    // <<<@("{")@(codetype)@("}")@("{")@(key)@("}")@("{")@(modelID)@("}")
}
@// first character to Upper
@def String firstToUpper(String string) {
    StringBuffer sb = new StringBuffer(string);
    sb.replace(0, 1, string.substring(0, 1).toUpperCase());
    return sb.toString();
}
@// generate javacode for the given topic
@def javacode(Context context) {
@("@def static {")

  /**
   * Base class
   */
  static abstract class TopicBase {
    // each Topic has a pageid - for non subobject thats the pagename
    public String pageid;

    /**
     * get a WikiSon version of the given name value
     * 
     * @@param name
     * @@param value
     * @@return - the string representation
     */
    public String toWikiSon(String name, String value) {
      String result = "<!-- " + name + " is null-->\n";
      if (value != null)
        result = "|" + name + "=" + value + "\n";
      return result;
    }

    /**
     * get the SiDIF representation of the given property
     * 
     * @@param name - the name of the property
     * @@param value - the value of the property
     * @@param type - the type of the property
     * @@return - the SiDIF Sting representation of the property
     */
    public static String propertySiDIF(String name, String value, String type) {
      // default is a comment line which can be filled by uncommenting
      String result = String.format("# is is %s of it\n",name);;
      // if the value is not empty
      if ((value != null) && (!("".equals(value.trim())))) {
        // do we need to quote the result?
        String quote = "";
        // this depends on the Type
        if ("Text".equals(type)) {
          quote = "\"";
        }
        // create a SIDIF Property line like
        // "John" is lastname of it
        // convert double quotes to single quotes - FIXME - should we escape instead?
        value=value.replace("\"","'");
        result = String.format("%s%s%s is %s of it\n",quote,value,quote,name);
      }
      // return the SiDIF property line
      return result;
    }

    /**
     * get me as a String
     * 
     * @@param name
     * @@param value
     * @@return
     */
    public static String propertySiDIF(String name, String value) {
      String result = propertySiDIF(name, value, "Text");
      return result;
    }

    /**
     * check if the given boolean String value is true
     * 
     * @@param value
     * @@return true if the value is not null and has true/TRUE as it's string
     *         content
     */
    public boolean isTrue(String value) {
      boolean result = false;
      if (value != null && value.toLowerCase().equals("true")) {
        result = true;
      }
      return result;
    }

    /**
     * initialize
     */
    public void init(TripleQuery query) {
    }
  } // TopicBase
@for(Topic topic:context.getTopics()) {
 /**
  * @topic.name
  * @topic.documentation
  */
  public static class @topic.name extends TopicBase @("{")
  
@for(Property property:topic.getProperties()) {
    public String @property.name;
}

@for(Property property:topic.getProperties()) {
    public String get@(firstToUpper(property.name))() { return @property.name; }
    public void set@(firstToUpper(property.name))(String p@(firstToUpper(property.name))) { @property.name=p@(firstToUpper(property.name)); }
}
    /**
     * convert this @topic.name to a JSON string
     */
    public String toJson() { return JSON.toJSONString(this); }

    /**
     * convert this @topic.name to a WikiSon string
     * @@return the WikiSon representation of this @(topic.name)
     */
    public String toWikiSon() {
      String wikison= "{{@topic.name\n";
@for(Property property:topic.getProperties()) {
      wikison+=toWikiSon("@property.name",@property.name);
}
      wikison+="}}\n";
      return wikison;
    }

    /**
     * convert this @topic.name to a SiDIF string
     * @@return the SiDIF representation of this @(topic.name)
     */
    public String toSiDIF() {
      String siDIF = String.format("%s isA @(topic.name)\n",this.pageid);
@for(Property property:topic.getProperties()) {
      siDIF+=propertySiDIF("@(property.name)",@(property.name),"@(property.type)");
}
      return siDIF;
    }
 
    /**  
     * get the pageid for this topic
     */
    public String getPageid() { return pageid; };

    /**
     * default constructor for @topic.name
     */
    public @(topic.name)() {}

    /**
     * construct a @topic.name from the given Triple
     * @("@")param query - the TripleQuery to get the triples from
     * @("@")param p@(topic.name)Triple - the triple to construct me from
     */
    public @(topic.name)(TripleQuery query,Triple p@(topic.name)Triple) @("{")
      this(query,p@(topic.name)Triple.getSubject().toString());
    @("} // constructor")

    /**
     * construct a @topic.name from the given pageId
     * @("@")param query - the TripleQuery to get the triples from
     * @("@")param pageid - pageid
     */
    public @(topic.name)(TripleQuery query,String pageid) @("{")
      this.pageid=pageid;
    @for(Property property:topic.getProperties()) {
      Triple @(property.name)Triple=query.selectSingle(pageid,"@property.name",null);
      if (@(property.name)Triple==null)
        @(property.name)Triple=query.selectSingle(pageid,"Property:@(topic.name)_@property.name",null);
      if (@(property.name)Triple!=null) 
        @(property.name)=@(property.name)Triple.getObject().toString();
    }
      init(query);
    @("}") // constructor for @topic.name
    @printUserCode("user defined topic code",topic.name,topic.name)
  @("}") // class @topic.name
  /**
   * Manager for @topic.name
   */
  public static class @(topic.name)Manager extends TopicBase @("{")
 
    public String topicName="@(topic.name)";
    public transient List<@topic.name> m@(topic.name)s=new ArrayList<@(topic.name)>();
    public transient Map<String,@topic.name> m@(topic.name)Map=new LinkedHashMap<String,@(topic.name)>();

    /**
     * get my @(topic.pluralName)
     */
    public List<@topic.name> get@(topic.pluralName)() {
      List<@topic.name> result=this.m@(topic.name)s;
      return result;
    }

    /**
     *  add a new @(topic.name) 
     */
    public @(topic.name) add(@(topic.name) p@(topic.name)) {
      m@(topic.name)s.add(p@(topic.name));
      m@(topic.name)Map.put(p@(topic.name).getPageid(),p@(topic.name));
      return p@(topic.name);
    }

    /**
     *  add a new @(topic.name) from the given triple
     */
    public @(topic.name) add(TripleQuery query,Triple p@(topic.name)Triple) {
      @topic.name l@topic.name=new @(topic.name)(query,p@(topic.name)Triple);
      add(l@(topic.name));
      return l@(topic.name);
    }

    // reinitialize my m@(topic.name) map
    public void reinit() {
      m@(topic.name)Map.clear();
      for (@(topic.name) l@(topic.name):m@(topic.name)s) {
        m@(topic.name)Map.put(l@(topic.name).getPageid(),l@(topic.name));
      }
    }

    // convert this manager to json format 
    public String toJson() { return JSON.toJSONString(this); }
    
    // get a new manager from the given json string
    public static @(topic.name)Manager fromJson(String json) {
      @(topic.name)Manager result=JSON.parseObject(json, @(topic.name)Manager.class);
      result.reinit();
      return result;
    }

    // default constructor for @(topic.name) Manager
    public @(topic.name)Manager() {}

    // add @(topic.pluralName) from the given query
    public void add@(topic.pluralName)(TripleQuery p@(topic.name)Query,TripleQuery query) {
      if (p@(topic.name)Query!=null) {
        for (Triple l@(topic.name)Triple:p@(topic.name)Query.getTriples()) {
          add(query,l@(topic.name)Triple);
        }
      }
    }

    // construct me from the given triple Query query
    public @(topic.name)Manager(TripleQuery query) @("{")
      // first query the SiDIF bases triplestore
      TripleQuery l@(topic.name)Query=query.query(null,"isA","@topic.name");
      add@(topic.pluralName)(l@(topic.name)Query,query);
      // then the SMW triplestore
      l@(topic.name)Query=query.query(null,"Property:IsA","@topic.name");
      add@(topic.pluralName)(l@(topic.name)Query,query);
      init(query);
    @("}") // constructor for @topic.name Manager
    @printUserCode("user defined topicmanager code",topic.name,topic.name)
  @("}") // class @topic.name Manager
}
@// end static
@("}")
}
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
  Context context=ContextFactory.getInstance().getContext(contextSetting);
}
@javacode(context)
@("<")@("/source>")

help

@include(wiki.SiDIFTemplates.defs)
@def help(Topic topic) {
[[File:Help_Icon.png|right]]
== Help for @(topic.name) ==
@topicheader(topic)
=== Documentation ===
@topic.wikiDocumentation
=== Example @(topic.pluralName) ===
{{#ask: [[Concept:@(topic.name)]]
}}
=== Properties ===
{{#ask: [[Concept:Property]][[Property topic::Concept:@(topic.name)]]
| ?Property documentation = documentation
| ?Property type = type
| ?Property name = name
| ?Property label = label
| ?Property allowedValues = allowedValues
| ?Property mandatory = mandatory
| ?Property uploadable = uploadable
|format=table
}}

@uml("uml",topic)
@seealso(topic)
[[Category:@topic.name]]
}
@{
  ContextSetting contextSetting=ContextSetting.fromWikiTask(wikiTask);
}
@help(contextSetting.getMaintopic())

debug

@include(wiki.SiDIFTemplates.java)
@for (Topic topic:mTopicManager.mTopics) {
== @(topic.pageid) ==
=== Concept property ===
@if (topic.conceptProperty) {
* @topic.conceptProperty.pageid name=@topic.conceptProperty.name
}
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
=== source TopicLink @(topicLink.name) ===
* @topicLink.sourceMultiple @topicLink.source @(topicLink.sourceRole)
* @topicLink.targetMultiple @topicLink.target @(topicLink.targetRole)
}
@for (TopicLink topicLink:topic.targetTopicLinks.mTopicLinks) {
=== target TopicLink @(topicLink.name) ===
* @topicLink.sourceMultiple @topicLink.source @(topicLink.sourceRole)
* @topicLink.targetMultiple @topicLink.target @(topicLink.targetRole)
}
@for (Property property:topic.getProperties()) {
=== Property @(property.name) ===
<pre>
[[Has type::@property.type]]
@("{{")Property
|name=@property.name
|documentation=@property.documentation
|type=Special:Types/@property.type
|label=@property.label
|primaryKey=@property.primaryKey
|mandatory=@property.mandatory
|uploadable=@property.uploadable
|size=@property.size
|defaultValue=@property.defaultValue
|inputType=@property.inputType
|allowedValues=@property.allowedValues
|topic=Concept:@topic.pageid
@("}}")
This is a Property with type @("{{#show: {{FULLPAGENAMEE}} | ?Property type#- }}")
</pre>
}
}

tripletable

@include(wiki.SiDIFTemplates.java)
@// macro to show a table of triples
@def tripletable(String title,List<org.sidif.triple.Triple> triples) {
=== @title ===
{| class="wikitable sortable"
! subject !! predicate !! object
|-
@for (org.sidif.triple.Triple triple:triples) {
|@triple.getSubject() || @triple.getPredicate() || @triple.getObject()
|-
}
|}
}
@// FIXME - will given compile error in java debug mode as of 2016-11-18
@//@tripletable("all triples",query.getTriples())
@//@tripletable("topics",topics.getTriples())

defs

@include(wiki.SiDIFTemplates.java)
@// macro to show BITPlan copyright
@def copyright() {<!--
  -- 	Copyright (C) 2015-2019 BITPlan GmbH
  -- 
  -- 	Pater-Delp-Str. -- 1
  -- 	D-47877 -- Willich-Schiefbahn
  -- 
  -- 	http://www.bitplan.com
  --
  -- 
-->@// avoid newline
}
@// error handling - get a stack trace
@def String getStackTrace (Throwable t) {
  StringWriter sw = new StringWriter();
  t.printStackTrace(new PrintWriter(sw));
  return sw.toString();
}
@// macro to to internationalize generator results
@def String i18n(String text) {
  String targetLang=wikiTask.getWiki().getSiteInfo().getLang();
  return text;
}
@// macro for the topic header of a topic
@def topicheader(Topic topic) {
{{#ask: [[Topic name::@(topic.name)]]
|mainlabel=-
|?Topic icon = icon
|? = Topic
|?Topic name = name
|?Topic pluralName = pluralName
|?Topic documentation = documentation
}}
}
@//prepare the sort part of ask
@def askSort(Topic topic) {
@{
  List<Property> sortProperties=topic.sortProperties();
  String sort="";
  String order="";
  String delim="";
  for (Property property:sortProperties) {
    String direction;
    if (property.sortAscending()) {
      direction="ascending";
    } else {
      direction="descending";
    }
    sort=sort+delim+topic.name+" "+property.name;
    order=order+delim+direction;
    delim=",";
  }
}
@if(sort) {
|sort=@sort
}
@if(order) {
|order=@order
}
}
@// macro for the form template of a topic
@def formtemplate(Topic topic,boolean isMultiple) {
@{
  String multiple="";
  if (isMultiple) {
    multiple="|multiple";
  }
}
<!-- @(topic.name) -->
@("{{{")for template|@(topic.name)@(multiple)@("}}}")
@("{|") class="wikitable"
! colspan='2'| @topic.name
|-
@for (Property property:topic.propertiesByIndex()) {
! @property.label: 
<!-- @property.type @property.name -->
@{ 
  String allowedValues=""; if (property.allowedValues!=null)       { allowedValues="|values="+property.allowedValues; }
  String mandatory="";     if ("true".equals(property.mandatory))  { mandatory="|mandatory"; }
  String uploadable="";    if ("true".equals(property.uploadable)) { uploadable="|uploadable"; }
  String values_from="";   if (property.values_from!=null)         { values_from="|values from "+property.values_from; }
  String defaultValue="";  if (property.defaultValue!=null)        { defaultValue="|default="+property.defaultValue; }
  String size="";          if (property.size!=null)                { size="|size="+property.size; }
  String inputtype="";     if (property.inputType!=null)           { inputtype="|input type="+property.inputType; }
  if ("textarea".equals(property.inputType)) {
     inputtype+="|editor=wikieditor";
  }
}
| @("{{{")field|@(property.name)|property=@(topic.name) @(property.name)@(inputtype)@(size)@(mandatory)@(uploadable)@(values_from)@(allowedValues)@(defaultValue)@("}}}")
|-
}
@("|}")
@("{{{")field|storemode|default=@(topic.defaultstoremode)|hidden@("}}}")
@("{{{end template}}}")
<!-- @(topic.name) -->
}
@// macro to to show relevant links for a topic
@def seealso(Topic topic) {
see also
* [[List of @(topic.pluralName)]]
* [[Help:@topic.name]]
* [[Concept:@topic.name]]
* [[:Category:@topic.name]]
* [[:Template:@topic.name]]
* [[:Form:@topic.name]]
topic links:
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
@if (topicLink.targetTopic) {
* [[:Category:@(topicLink.targetTopic.name)]]
}
}
}
@// macro to create skin params for BITPlan corporate identity 
@def bitplanumlci(int fontSize) {
' BITPlan Corporate identity skin params
' Copyright (c) 2015-2017 BITPlan GmbH
' see http://wiki.bitplan.com/PlantUmlSkinParams#BITPlanCI
' skinparams generated by com.bitplan.restmodelmanager
@{ String skinparams[] = {"note", "component", "package", "usecase","activity","classAttribute","interface","class","object"};  }
@for (String skinparam:skinparams) {
skinparam @skinparam {
  BackGroundColor #FFFFFF
  FontSize @fontSize
  ArrowColor #FF8000
  BorderColor #FF8000
  FontColor black
  FontName Technical
}
}
hide Circle
' end of skinparams '
}
@// macro to create Relation
@def plantUmlRelation(TopicLink topicLink) {
@{
  String sourceMany="1";
  String targetMany="1";
  if ("true".equals(topicLink.sourceMultiple)) sourceMany="*";
  if ("true".equals(topicLink.targetMultiple)) targetMany="*";
}
@(topicLink.source) "@(topicLink.sourceRole) (@(sourceMany))" -- "@(topicLink.targetRole)(@(targetMany))" @(topicLink.target)
}
@// macro to create uml from simela triples
@def uml(String title,Topic topic) {
=== @title ===
<uml>
title @topic.name
note as @(topic.name)DiagramNote
Copyright (c) 2015-2017 BITPlan GmbH
[[http://www.bitplan.com]]
end note
note as @(topic.name)Note
@(topic.documentation)
end note
class @topic.name @("{")
@for (Property property:topic.propertiesByIndex()) {
  @(property.type) @(property.name)
}
@("}")
@(topic.name)Note .. @(topic.name)
@for (TopicLink topicLink:topic.sourceTopicLinks.mTopicLinks) {
@plantUmlRelation(topicLink)
}
@for (TopicLink topicLink:topic.targetTopicLinks.mTopicLinks) {
@plantUmlRelation(topicLink)
}
@bitplanumlci(12)
</uml>
}

dialogdefs

@import java.net.URLEncoder
@// JQuery imports
@def jquery(String indent) {
@(indent)<!--  JQuery Code for resthtmlview -->
@(indent)<script src="/resthtmlview/js/jquery-1.10.2.min.js" type="text/javascript"></script>
@(indent)<script src="/resthtmlview/js/jquery-ui-1.10.0.custom.js"></script>
@(indent)<script src="/resthtmlview/js/i18n/grid.locale-en.js" type="text/javascript"></script>
@(indent)<script src="/resthtmlview/js/ui.multiselect.js" type="text/javascript"></script>
@(indent)<script src="/resthtmlview/js/jquery.ui.message.js" type="text/javascript"></script>
@(indent)<script src="/resthtmlview/js/jquery.jqGrid.min.js" type="text/javascript"></script>
@(indent)<script src="/resthtmlview/js/redactor.min.js" type="text/javascript"></script>
@(indent)<!-- load jQuery and tablesorter scripts -->
@(indent)<script src="/resthtmlview/js/jquery.tablesorter.min.js"></script>
@(indent)<script src="/resthtmlview/js/jquery.tablesorter.widgets.js"></script>
@(indent)<script src="/resthtmlview/js/jquery.metadata.js"></script>
 
@(indent)<!--  JQuery Styles for resthtmlview -->
@(indent)<link href="/resthtmlview/css/form.css" type="text/css" media="screen" rel="stylesheet">
@(indent)<link href="/resthtmlview/css/messages.css" type="text/css" media="screen" rel="stylesheet">
@(indent)<link href="/resthtmlview/css/bitplanfadetogrey/jquery-ui-1.10.1.custom.css" type="text/css" media="screen" rel="stylesheet">
@(indent)<link href="/resthtmlview/css/ui.jqgrid.css" type="text/css" media="screen" rel="stylesheet" />
@(indent)<link href="/resthtmlview/css/ui.multiselect.css" type="text/css" media="screen" rel="stylesheet" /> 
@(indent)<!-- Tablesorter: required -->
@(indent)<link href="/resthtmlview/css/theme.blue.css" rel="stylesheet">
@(indent)<link href="/resthtmlview/css/searchFilter.css" type="text/css" media="screen" rel="stylesheet" /> 
@(indent)<link href="/resthtmlview/css/redactor.css" type="text/css" media="screen" rel="stylesheet" />
}
@// CSS Style definitions
@def style(String indent) {
@(indent)<style>
@(indent)  body { height:100% }
@(indent)  #container {
@(indent)    background-color: #f0f0f0; /* lightblue background */
@(indent)    width: 100%; /* Container has full width */
@(indent)    margin: auto; /* center container */
@(indent)    min-height: 100%; /* minimum height 100 % (for modern browsers) */
@(indent)    height: auto !important; /* important Behel (for modern browsers */
@(indent)    height: 100%; /* IE shall work as specified */
@(indent)    overflow: hidden !important; /* firefox scrollbar */
@(indent)  }
@(indent)</style>
}
@// dialog definition
@def dialog(String indent) {
@(indent)<script type="text/javascript">
@(indent)  $(document).ready(function() {
@(indent)    var wWidth = $(window).width();
@(indent)    var wHeight = $(window).height();
@(indent)    var dTopy = wHeight * 0.25; // top at 25% of window height
@(indent)    var dTopx = wWidth * 0.25; // left at 25% of window width
@(indent)    var dWidth = 'auto'; //this will make the dialog 98% of the window size
@(indent)    var dHeight = 'auto';
@(indent)    $( "#dialog" ).dialog({
@(indent)      // position : [ dTopx, dTopy ],
@(indent)      width : dWidth,
@(indent)      height : dHeight,
@(indent)      modal : true,
@(indent)      // title: ""+wWidth+"x"+wHeight+" "+dTopx+":"+dTopy,
@(indent)      my: "center",
@(indent)      at: "center",
@(indent)      of: window,
@(indent)      show : {
@(indent)        effect : "blind",
@(indent)        duration : 500
@(indent)      },
@(indent)      hide : {
@(indent)	       effect : "fade",
@(indent)	       duration : 500
@(indent)      }
@(indent)    });

@(indent)    // tabs
@(indent)    $( "#tabs" ).tabs();

@(indent)    // tablesorter
@(indent)    $.extend( $.tablesorter.defaults, {
@(indent)      theme: 'blue',
@(indent)      widthFixed: false
@(indent)    });

@(indent)    $(".sortable").tablesorter();

@(indent)  });
@(indent)</script>
}
@// display the given stockicon
@def String stockicon(String name,int size,String alt,String title) {
  String iconhref="/stockicons/"+size+"x"+size+"/shadow/"+name+".png";
  String img="<img src='"+iconhref+"' alt='"+alt+"' title='"+title+"' width='"+size+"px' height='"+size+"px' >";
  return img;
}
@// url encode the given txt
@def String urlEncode(String txt) {
  String result=URLEncoder.encode(txt, "UTF-8");
  return result;
}
@def selectall() {
  <script>
/**
 * http://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular- 
 * expression
 *  examples:
 *
 *  var matches = getRegexMatches(/(dog)/, "dog boat, cat car dog");
 *  console.log(matches);
 *
 *  var matches = getRegexMatches(/(dog|cat) (boat|car)/, "dog boat, cat car");
 *  console.log(matches);
 */
function getRegexMatches(regex, string) {
    if(!(regex instanceof RegExp)) {
      return "ERROR";
    }
    else {
      if (!regex.global) {
        // If global flag not set, create new one.
        var flags = "g";
        if (regex.ignoreCase) flags += "i";
        if (regex.multiline) flags += "m";
        if (regex.sticky) flags += "y";
        regex = RegExp(regex.source, flags);
      }
    }
    var matches = [];
    var match = regex.exec(string);
    while (match) {
      if (match.length > 2) {
        var group_matches = [];
        for (var i = 1; i < match.length; i++) {
          group_matches.push(match[i]);
        }
        matches.push(group_matches);
      }
      else {
        matches.push(match[1]);
      }
      match = regex.exec(string);
    }
    return matches;
}

/**
 * get the select_row or select_col checkboxes dependening on the selectType row/col
 */
function getSelectCheckboxes(selectType) {
  var regex=new RegExp("select_"+selectType+"_");
  var result= $('input').filter(function() {return this.id.match(regex);});
  return result;
}

/**
 * matrix selection logic 
 * the goal is to provide select all / select row x / select col x
 * checkboxes that will allow to 
 *   select all: select all grid elements 
 *   select row: select the grid elements in the given row
 *   select col: select the grid elements in the given col
 *
 *   There is a naming convention for the ids and css style classes of the the selectors and elements:
 *   select all -> id: selectall
 *   select row -> id: select_row_row e.g. select_row_2
 *   select col -> id: select_col_col e.g. select_col_3 
 *   grid element -> class checkBoxClass col_col row_row e.g. checkBoxClass row_2 col_3
 */
function checkSelectStates() {
	// get the list of grid checkbox elements
  // all checkboxes
  var all = $('.checkBoxClass');
  // all select row check boxes
  var rows = getSelectCheckboxes('row');
  // all select columnn check boxes
  var cols = getSelectCheckboxes('col');
  // console.log("rows: "+rows.length+", cols:"+cols.length+" total: "+all.length);
  // get the total number of checkboxes in the grid
  var allLen=all.length;
  // get the number of checkboxes in the checked state
  var filterLen=all.filter(':checked').length;
  // console.log(allLen+"-"+filterLen);
  // if all checkboxes are in the checked state  
  // set the state of the selectAll checkbox to checked to be able
  // to deselect all at once, otherwise set it to unchecked to be able to select all at once
  if (allLen == filterLen) {
    $("#selectall").prop("checked", true);
  } else {
    $("#selectall").prop("checked", false);
  }
        // now check the completeness of the rows
  for (row = 0; row < rows.length; row++) {
    var rowall=$('.row_'+row);
    var rowchecked=rowall.filter(':checked');
    if (rowall.length == rowchecked.length) {
      $("#select_row_"+row).prop("checked", true);
    } else {  
      $("#select_row_"+row).prop("checked", false);
    }
  }
  // now check the completeness of the cols
  for (col = 0; col < cols.length; col++) {
    var colall=$('.col_'+col);
    var colchecked=colall.filter(':checked');
    if (colall.length == colchecked.length) {
      $("#select_col_"+col).prop("checked", true);
    } else {  
      $("#select_col_"+col).prop("checked", false);
    }
  }
}
$(document).ready(function () {
	  
    // handle click event for Select all check box
    $("#selectall").click(function () {
       // set the checked property of all grid elements to be the same as
       // the state of the SelectAll check box
       var state=$("#selectall").prop('checked');
       $(".checkBoxClass").prop('checked', state);
       getSelectCheckboxes('row').prop('checked', state);
       getSelectCheckboxes('col').prop('checked', state);
    });

    // handle clicks within the grid
    $(".checkBoxClass").on( "click", function() {
    	checkSelectStates();
    });
     
    $('.checkboxSelect').on( "click", function() {
      var matchRowColArr=getRegexMatches(/select_(row|col)_([0-9]+)/,this.id);
      var matchRowCol=matchRowColArr[0];
      // console.log(matchRowCol);
      if (matchRowCol.length==2) {
        var selectType=matchRowCol[0];  // e.g. row
        var selectIndex=matchRowCol[1]; // e.g. 2
        // console.log(this.id+" clicked to select "+selectType+" "+selectIndex);
        // e.g. .row_2
        $("."+selectType+"_"+selectIndex)
         .prop('checked', $("#select_"+selectType+"_"+selectIndex).prop('checked'));
        checkSelectStates();
      }
    });
    
  });
  </script>
}

java

The debugging version of the SiDIF Templates

@// This is a rythm template
@// the args are the standard wikiTask arguments
@import org.sidif.triple.TripleQuery
@import org.sidif.triple.TripleStore
@import org.sidif.triple.Triple
@import org.sidif.wiki.SMW_Triples
@import com.alibaba.fastjson.JSON
@// import instead of src
@import com.bitplan.topic.TopicStatic.YT
@import com.bitplan.topic.TopicStatic.Context
@import com.bitplan.topic.TopicStatic.Topic
@import com.bitplan.topic.TopicStatic.Property
@import com.bitplan.topic.TopicStatic.SMW_Type
@import com.bitplan.topic.TopicStatic.TopicLink
@import com.bitplan.topic.TopicStatic.ContextManager
@import com.bitplan.topic.TopicStatic.TopicManager
@import com.bitplan.topic.TopicStatic.PropertyManager
@import com.bitplan.topic.TopicStatic.SMW_TypeManager
@import com.bitplan.topic.TopicStatic.TopicLinkManager
@import com.bitplan.topic.ContextFactory
@import com.bitplan.topic.ContextSetting
@args() {
  String title 
  String logo
  org.sidif.wiki.WikiTask wikiTask
  org.sidif.triple.TripleStore tripleStore
}

javasrc

the interpreted version of the java code needs to be updated from Concept:Topic/Java with the usercode sections being added from org.sidif.wiki in src/main/java com.bitplan.topic.TopicStatic.java.

@// This is a rythm template
@// the args are the standard wikiTask arguments
@import org.sidif.triple.TripleQuery
@import org.sidif.triple.TripleStore
@import org.sidif.triple.Triple
@import org.sidif.wiki.SMW_Triples
@import com.alibaba.fastjson.JSON
@import java.util.Map.Entry;
@import java.util.logging.Logger;
@import java.util.logging.Level;
@import com.bitplan.topic.ContextFactory
@import com.bitplan.topic.ContextSetting
@args() {
  String title 
  String logo
  org.sidif.wiki.WikiTask wikiTask
  org.sidif.triple.TripleStore tripleStore
}

@def static {

  /**
   * Base class
   */
  public static abstract class TopicBase {

    protected static Logger LOGGER = Logger.getLogger("org.sidif.wiki");

    /**
     * initialize
     */
    public void init(TripleQuery query) {
    }

    /**
     * get the propertySidif of the given property
     * 
     * @param name
     * @param value
     * @return
     */
    public static String propertySiDIF(String name, String value, String type) {
      // default is an empty string - no property line for emtpy values
      String result = "";
      // if the value is not empty
      if ((value != null) && (!("".equals(value.trim())))) {
        // do we need to quote the result?
        String quote = "";
        // this depends on the Type
        if ("Text".equals(type)) {
          quote = "\"";
        }
        // create a SIDIF Property line like
        // "John" is lastname of it
        result += quote + value + quote + " is " + name + " of it\n";
      }
      // return the SiDIF property line
      return result;
    }

    /**
     * get me as a String
     * 
     * @param name
     * @param value
     * @return
     */
    public static String propertySiDIF(String name, String value) {
      String result = propertySiDIF(name, value, "Text");
      return result;
    }

    /**
     * check if the given boolean String value is true
     * 
     * @param value
     * @return true if the value is not null and has true/TRUE as it's string
     *         content
     */
    public boolean isTrue(String value) {
      boolean result = false;
      if (value != null && value.toLowerCase().equals("true")) {
        result = true;
      }
      return result;
    }

  } // TopicBase

  public static class YTManager {
    List<YT> yTs;

    /**
     * @param yts
     *          the yts to set
     */
    public void setYTs(List<YT> yts) {
      this.yTs = yts;
    }

    /**
     * get the technical aspects
     * 
     * @return
     */
    public List<YT> getYTs() {
      if (yTs == null) {
        yTs = Arrays.asList(YT.yts);
      }
      return yTs;
    }

    /**
     * convert this YT to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    // get a new manager from the given json string
    public static YTManager fromJson(String json) {
      YTManager result = JSON.parseObject(json, YTManager.class);
      return result;
    }
  }

  /**
   * technical aspects of Y-Principle
   * 
   * @author wf
   *
   */
  public static class YT {

    // Y-Principle technical aspects
    public static YT yts[] = {
        new YT("Category", "Category", "category",
            "/images/d/d6/Category_Icon.png"),
        new YT("Concept", "Concept", "concept", "/images/2/25/Concept_Icon.png"),
        new YT("Form", "Form", "form", "/images/e/e5/Form_icon.jpg"),
        new YT("Help", "Help", "help", "/images/7/7a/Help_Icon.png"),
        new YT("Listof", "List of", "listof", "/images/7/7f/List_Icon.png"),
        new YT("Template", "Template", "template",
            "/images/6/61/Icon_template.png"),
        new YT("Properties", "Properties", "properties",
            "/images/6/6a/Element_into_input.png"),
        new YT("Java", "Java", "javacodegen", "/images/3/38/Java_icon.png") };

    /**
     * get the YT with the given name
     * 
     * @param ytname
     */
    public static YT getYT(String ytname) {
      for (YT yt : yts) {
        if (yt.name.equals(ytname)) {
          return yt;
        }
      }
      return null;
    }

    public String name;
    public String label;
    public String iconUrl;
    public String template;

    // default constructor for json
    public YT() {
    };

    /**
     * construct me with name label and icon url
     * 
     * @param name
     * @param label
     * @param iconUrl
     */
    public YT(String name, String label, String template, String iconUrl) {
      super();
      this.name = name;
      this.label = label;
      this.template = template;
      this.iconUrl = iconUrl;
    }

    /**
     * a part where name and label is different
     * 
     * @param name
     * @param label
     */
    public YT(String name, String label) {
      this(name, label, name.toLowerCase(), "File:" + name + ".png");
    }

    /**
     * a part where name and label is the same
     * 
     * @param name
     */
    public YT(String name) {
      this(name, name);
    }

    /**
     * convert this YT to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    /**
     * get the page Title for the given topic name
     * 
     * @param topicname
     * @return
     */
    public String getPageTitle(Topic topic) {
      String result = this.name + ":" + topic.name;
      if ("Listof".equals(name)) {
        result = "List_of_" + topic.pluralName.replace(" ", "_");
      }
      if ("Properties".equals(name)) {
        result = "Concept:" + topic.name.replace(" ", "_") + "/Properties";
      }
      if ("Java".equals(name)) {
        result = "Concept:" + topic.name.replace(" ", "_") + "/Java";
      }
      return result;
    }
  }

  /**
   * Context
   * A Context groups some topics like a Namespace/Package
   */
  public static class Context extends TopicBase {
    public String pageid;
    public String name;

    public String getName() {
      return name;
    }

    public void setName(String pName) {
      name = pName;
    }

    /**
     * convert this Context to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    /**
     * get the pageid for this topic
     */
    public String getPageid() {
      return pageid;
    };

    /**
     * default constructor for Context
     */
    public Context() {
    }

    /**
     * construct a Context from the given Triple
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pContextTriple
     *          - the triple to construct me from
     */
    public Context(TripleQuery query, Triple pContextTriple) {
      this(query, pContextTriple.getSubject().toString());
    } // constructor

    /**
     * construct a Context from the given pageId
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pageid
     *          - pageid
     */
    public Context(TripleQuery query, String pageid) {
      this.pageid = pageid;
      Triple nameTriple = query.selectSingle(pageid, "name", null);
      if (nameTriple == null)
        nameTriple = query.selectSingle(pageid, "Property:Context_name", null);
      if (nameTriple != null)
        name = nameTriple.getObject().toString();
      init(query);
    } // constructor for Context

    // >>>{user defined topic code}{Context}{Context}
    /**
     * initialize
     */
    public void init(TripleQuery query) {
      if (this.name == null) {
        this.name = this.pageid;
      }
    }

    /**
     * return me as a SiDIF string
     * 
     * @return
     */
    public String asSiDIF() {
      String result = "";
      result += "#\n";
      result += "# Context:" + getName() + "\n";
      result += "#\n";
      result += getPageid() + " isA Context\n";
      result += propertySiDIF("name", name);
      for (Entry<String, Topic> topicEntry : this.topics.mTopicMap.entrySet()) {
        result += topicEntry.getValue().asSiDIF();
      }
      return result;
    }

    // 1:n relation to topics
    public TopicManager topics = new TopicManager();

    /**
     * accessor for 1:n relation to topics
     * 
     * @return
     */
    public List<Topic> getTopics() {
      return topics.mTopics;
    }

    /**
     * recreate topics from a given list
     * 
     * @param pTopics
     */
    public void setTopics(List<Topic> pTopics) {
      topics = new TopicManager();
      topics.mTopics = pTopics;
      for (Topic topic : pTopics) {
        topics.mTopicMap.put(topic.getName(), topic);
      }
    }

    /**
     * get the Topic by the given topicName
     * 
     * @param topicName
     * @return
     */
    public Topic byName(String topicName) {
      Topic result = this.topics.byName(topicName);
      return result;
    }
    // <<<{user defined topic code}{Context}{Context}
  } // class Context

  /**
   * Manager for Context
   */
  public static class ContextManager extends TopicBase {

    public String topicName = "Context";
    public transient List<Context> mContexts = new ArrayList<Context>();
    public transient Map<String, Context> mContextMap = new TreeMap<String, Context>();

    /**
     * add a new Context
     */
    public Context add(Context pContext) {
      mContexts.add(pContext);
      mContextMap.put(pContext.getName(), pContext);
      return pContext;
    }

    /**
     * add a new Context from the given triple
     */
    public Context add(TripleQuery query, Triple pContextTriple) {
      Context lContext = new Context(query, pContextTriple);
      add(lContext);
      return lContext;
    }

    // reinitialize my mContext map
    public void reinit() {
      mContextMap.clear();
      for (Context lContext : mContexts) {
        mContextMap.put(lContext.getName(), lContext);
      }
    }

    // convert this manager to json format
    public String toJson() {
      return JSON.toJSONString(this);
    }

    // get a new manager from the given json string
    public static ContextManager fromJson(String json) {
      ContextManager result = JSON.parseObject(json, ContextManager.class);
      result.reinit();
      return result;
    }

    // default constructor
    public ContextManager() {
    }

    // construct me from the given triple Query query
    public ContextManager(TripleQuery query) {
      // first query the SiDIF bases triplestore
      TripleQuery lContextQuery = query.query(null, "isA", "Context");
      for (Triple lContextTriple : lContextQuery.getTriples()) {
        add(query, lContextTriple);
      }
      // then the SMW triplestore
      lContextQuery = query.query(null, "Property:IsA", "Context");
      for (Triple lContextTriple : lContextQuery.getTriples()) {
        add(query, lContextTriple);
      }
      init(query);
    } // constructor for Context Manager

    // >>>{user defined topicmanager code}{Context}{Context}
    public transient TopicManager mTopicManager;
    public transient PropertyManager mPropertyManager;

    /**
     * run pass 2 to link topics to context and properties to topics
     * 
     * @return
     */
    public List<String> pass2() {
      List<String> result = new ArrayList<String>();
      for (Topic topic : mTopicManager.mTopics) {
        if (topic.context == null) {
          LOGGER.log(Level.SEVERE, "topic " + topic.getName() + " pageid "
              + topic.getPageid() + " has a null context");
        } else {
          Context context = this.mContextMap.get(topic.context);
          if (context != null) {
            context.topics.add(topic);
          } else {
            result.add("Context '" + topic.context + "' not found");
          }
        }
      }
      // FIXME - do we really need to do this?
      for (Property property : mPropertyManager.mPropertys) {
        String propertyHint = "property " + property.getName() + " pageid "
            + property.getPageid();
        if (property.topic == null) {
          LOGGER.log(Level.SEVERE, propertyHint + " has a null topic");
        } else {
          // FIXME ... remove non name parts ...
          Topic topic = mTopicManager.mTopicMap.get(property.topic);
          if (topic != null) {
            if (!topic.properties.mPropertyMap.containsKey(property.getName())) {
              result.add("property '" + propertyHint + "  not found in topic "
                  + topic.getName());
            } else {
              topic.properties.add(property);
            }
          } else {
            result.add("Topic '" + property.topic + "' for " + propertyHint
                + "  not found in ");
          }
        }
      }
      return result;
    }

    /**
     * construct me from a tripleStore
     * 
     * @param tripleStore
     */
    public ContextManager(TripleStore tripleStore) {
      this(tripleStore.query());
      mTopicManager = new TopicManager(tripleStore.query());
      mPropertyManager = new PropertyManager(tripleStore.query());
      mTopicManager.configureTopics();
      pass2();
    }

    /**
     * get my contexts
     * 
     * @return
     */
    public List<Context> getContexts() {
      List<Context> result = this.mContexts;
      return result;
    }

    /**
     * get the given context by name
     * 
     * @param name
     * @return
     */
    public Context byName(String name) {
      Context result = this.mContextMap.get(name);
      return result;
    }

    /**
     * return me as a SiDIF representation
     * 
     * @return
     */
    public String asSiDIF() {
      String result = "";
      for (Entry<String, Context> contextEntry : this.mContextMap.entrySet()) {
        result += contextEntry.getValue().asSiDIF();
      }
      return result;
    }
    // <<<{user defined topicmanager code}{Context}{Context}
  } // class Context Manager

  /**
   * Topic
   * A Topic is a Concept/Class/Thing/Entity
   */
  public static class Topic extends TopicBase {
    public String pageid;
    public String name;
    public String pluralName;
    public String icon;
    public String iconUrl;
    public String documentation;
    public String wikiDocumentation;
    public String defaultstoremode;
    public String listLimit;
    public String cargo;
    public String context;
    public String headerTabs;

    public String getName() {
      return name;
    }

    public void setName(String pName) {
      name = pName;
    }

    public String getPluralName() {
      return pluralName;
    }

    public void setPluralName(String pPluralName) {
      pluralName = pPluralName;
    }

    public String getIcon() {
      return icon;
    }

    public void setIcon(String pIcon) {
      icon = pIcon;
    }

    public String getIconUrl() {
      return iconUrl;
    }

    public void setIconUrl(String pIconUrl) {
      iconUrl = pIconUrl;
    }

    public String getDocumentation() {
      return documentation;
    }

    public void setDocumentation(String pDocumentation) {
      documentation = pDocumentation;
    }

    public String getWikiDocumentation() {
      return wikiDocumentation;
    }

    public void setWikiDocumentation(String pWikiDocumentation) {
      wikiDocumentation = pWikiDocumentation;
    }

    public String getDefaultstoremode() {
      return defaultstoremode;
    }

    public void setDefaultstoremode(String pDefaultstoremode) {
      defaultstoremode = pDefaultstoremode;
    }

    public String getListLimit() {
      return listLimit;
    }

    public void setListLimit(String pListLimit) {
      listLimit = pListLimit;
    }

    public String getCargo() {
      return cargo;
    }

    public void setCargo(String pCargo) {
      cargo = pCargo;
    }

    public String getContext() {
      return context;
    }

    public void setContext(String pContext) {
      context = pContext;
    }

    public String getHeaderTabs() {
      return headerTabs;
    }

    public void setHeaderTabs(String pHeaderTabs) {
      headerTabs = pHeaderTabs;
    }

    /**
     * convert this Topic to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    /**
     * get the pageid for this topic
     */
    public String getPageid() {
      return pageid;
    };

    /**
     * default constructor for Topic
     */
    public Topic() {
    }

    /**
     * construct a Topic from the given Triple
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pTopicTriple
     *          - the triple to construct me from
     */
    public Topic(TripleQuery query, Triple pTopicTriple) {
      this(query, pTopicTriple.getSubject().toString());
    } // constructor

    /**
     * construct a Topic from the given pageId
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pageid
     *          - pageid
     */
    public Topic(TripleQuery query, String pageid) {
      this.pageid = pageid;
      Triple pluralNameTriple = query.selectSingle(pageid, "pluralName", null);
      if (pluralNameTriple == null)
        pluralNameTriple = query.selectSingle(pageid,
            "Property:Topic_pluralName", null);
      if (pluralNameTriple != null)
        pluralName = pluralNameTriple.getObject().toString();
      Triple cargoTriple = query.selectSingle(pageid, "cargo", null);
      if (cargoTriple == null)
        cargoTriple = query.selectSingle(pageid, "Property:Topic_cargo", null);
      if (cargoTriple != null)
        cargo = cargoTriple.getObject().toString();
      Triple documentationTriple = query.selectSingle(pageid, "documentation",
          null);
      if (documentationTriple == null)
        documentationTriple = query.selectSingle(pageid,
            "Property:Topic_documentation", null);
      if (documentationTriple != null)
        documentation = documentationTriple.getObject().toString();
      Triple wikiDocumentationTriple = query.selectSingle(pageid,
          "wikiDocumentation", null);
      if (wikiDocumentationTriple == null)
        wikiDocumentationTriple = query.selectSingle(pageid,
            "Property:Topic_wikiDocumentation", null);
      if (wikiDocumentationTriple != null)
        wikiDocumentation = wikiDocumentationTriple.getObject().toString();
      Triple defaultstoremodeTriple = query.selectSingle(pageid,
          "defaultstoremode", null);
      if (defaultstoremodeTriple == null)
        defaultstoremodeTriple = query.selectSingle(pageid,
            "Property:Topic_defaultstoremode", null);
      if (defaultstoremodeTriple != null)
        defaultstoremode = defaultstoremodeTriple.getObject().toString();
      Triple nameTriple = query.selectSingle(pageid, "name", null);
      if (nameTriple == null)
        nameTriple = query.selectSingle(pageid, "Property:Topic_name", null);
      if (nameTriple != null)
        name = nameTriple.getObject().toString();
      Triple iconTriple = query.selectSingle(pageid, "icon", null);
      if (iconTriple == null)
        iconTriple = query.selectSingle(pageid, "Property:Topic_icon", null);
      if (iconTriple != null)
        icon = iconTriple.getObject().toString();
      Triple contextTriple = query.selectSingle(pageid, "context", null);
      if (contextTriple == null)
        contextTriple = query.selectSingle(pageid, "Property:Topic_context",
            null);
      if (contextTriple != null)
        context = contextTriple.getObject().toString();
      Triple iconUrlTriple = query.selectSingle(pageid, "iconUrl", null);
      if (iconUrlTriple == null)
        iconUrlTriple = query.selectSingle(pageid, "Property:Topic_iconUrl",
            null);
      if (iconUrlTriple != null)
        iconUrl = iconUrlTriple.getObject().toString();
      Triple headerTabsTriple=query.selectSingle(pageid,"headerTabs",null);
      if (headerTabsTriple==null)
        headerTabsTriple=query.selectSingle(pageid,"Property:Topic_headerTabs",null);
      if (headerTabsTriple!=null) 
        headerTabs=headerTabsTriple.getObject().toString();
      init(query);
    } // constructor for Topic

    // >>>{user defined topic code}{Topic}{Topic}
    PropertyManager properties = new PropertyManager();
    transient public TopicLinkManager sourceTopicLinks = new TopicLinkManager();
    transient public TopicLinkManager targetTopicLinks = new TopicLinkManager();
    transient public Property conceptProperty; // the Property to be used when
                                               // selecting a

    // Concept

    /**
     * get the Properties
     * 
     * @return
     */
    public List<Property> getProperties() {
      return properties.mPropertys;
    }

    /**
     * add Properties from the given query
     * 
     * @param propertyQuery
     * @param query
     */
    public void addProperties(TripleQuery propertyQuery, TripleQuery query) {
      if (propertyQuery != null) {
        for (Triple property : propertyQuery.getTriples()) {
          properties.add(query, property);
        }
      }
    }

    /**
     * initialize me with the given query
     * 
     * @Override
     */
    public void init(TripleQuery query) {
      // pass2 does this in a query indepent way ...
      // SiDIF style property query ...
      TripleQuery propertyQuery = query.query(null, "addsTo", pageid);
      addProperties(propertyQuery, query);
      // pass2 does this in a reverse way - this could also be done but then
      // propertyNames would have to be fixed ...
      propertyQuery = query.query(null, "Property:Property_topic", pageid);
      addProperties(propertyQuery, query);

      addTopicLinks(query, sourceTopicLinks, "source");
      addTopicLinks(query, targetTopicLinks, "target");

      if (name == null) {
        name = pageid;
      }
      if (pluralName == null) {
        pluralName = name + "s";
      }

      // add Properties for targetTopicLinks
      // this is the referenced to the "neighbour" Topic
      for (TopicLink topicLink : targetTopicLinks.mTopicLinks) {
        Property property = new Property();
        property.pageid = topicLink.sourceRole;
        property.documentation = topicLink.sourceDocumentation;
        property.name = property.pageid;
        property.label = property.name;
        property.type = "Page";
        property.isLink = "true";
        // make sure the form shows the neighbour concept as an option
        String sourceName = topicLink.source;
        // remove "Concept:" prefix !!! FIXME - this is language dependent
        // and a horrible work around for the time being
        sourceName = sourceName.replace("Concept:", "");
        sourceName = sourceName.replace("Konzept:", "");
        property.values_from = "concept=" + sourceName;
        property.inputType = "dropdown";
        properties.mPropertys.add(property);
      }
    }

    /**
     * add the topicLinks
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param tm
     *          - the TopicLinkManager to add the topic links to
     * @param predicate
     *          - the predicate to be used for linking
     */
    public void addTopicLinks(TripleQuery query, TopicLinkManager tm,
        String predicate) {
      TripleQuery linkQuery = query.query(null, predicate, pageid);
      if (linkQuery != null) {
        for (Triple linkTriple : linkQuery.getTriples()) {
          String link = linkTriple.getSubject().toString();
          TopicLink topiclink = new TopicLink(query, link);
          tm.mTopicLinks.add(topiclink);
        }
      }
    }

    /**
     * check my source TopicLinks and set the targetTopic by looking it up
     */
    public void linkTargetTopics(TopicManager tm) {
      for (TopicLink sourceTopicLink : sourceTopicLinks.mTopicLinks) {
        String topicTarget = sourceTopicLink.target; // e.g. Concept:Property;
        topicTarget = topicTarget.replace("Concept:", ""); // remove Concept
                                                           // part
        topicTarget = topicTarget.replace("Koncept:", ""); // remove Concept
                                                           // part
        Topic targetTopic = tm.byName(topicTarget);
        if (targetTopic != null) {
          sourceTopicLink.targetTopic = targetTopic;
        }
      }
    }

    /**
     * set the concept Property for the given target Property
     */
    public void setConceptProperty() {
      for (Property property : properties.mPropertys) {
        if ("true".equals(property.mandatory)
            || "true".equals(property.primaryKey)) {
          conceptProperty = property;
          break;
        }
      }
    }

    /**
     * get the Properties sorted by index
     * 
     * @return
     */
    public List<Property> propertiesByIndex() {
      List<Property> properties = new ArrayList<Property>(
          this.properties.mPropertys);
      Collections.sort(properties, new Comparator<Property>() {
        public int compare(Property p1, Property p2) {
          Integer p1i = Integer.MAX_VALUE;
          Integer p2i = Integer.MAX_VALUE;
          try {
            p1i = Integer.parseInt(p1.index);
          } catch (NumberFormatException nfe) {
          }
          ;
          try {
            p2i = Integer.parseInt(p2.index);
          } catch (NumberFormatException nfe) {
          }
          ;
          int result = p1i.compareTo(p2i);
          return result;
        }
      });
      return properties;
    }

    /**
     * return me as a SiDIF string
     * 
     * @return
     */
    public String asSiDIF() {
      String result = "";
      result += "#\n";
      result += "#" + getName() + "\n";
      result += "#\n";
      result += name + " isA Topic\n";
      result += propertySiDIF("name", name);
      result += propertySiDIF("pluralName", pluralName);
      result += propertySiDIF("documentation", documentation);
      result += propertySiDIF("wikiDocumentation", wikiDocumentation);
      result += propertySiDIF("icon", icon);
      result += propertySiDIF("iconUrl", iconUrl);
      result += propertySiDIF("defaultstoremode", defaultstoremode);
      result += propertySiDIF("listLimit", this.listLimit, "Boolean");
      result += propertySiDIF("cargo", cargo, "Boolean");
      result += propertySiDIF("headerTabs", this.headerTabs, "Boolean");
      result += propertySiDIF("context", this.context);
      List<Property> propertiesByIndex = this.propertiesByIndex();
      for (Property property : propertiesByIndex) {
        if (!isTrue(property.isLink))
          result += getName() + "_" + property.getName() + " addsTo it\n";
      }
      int pindex = 0;
      result += "# properties of " + name + "\n";
      ;
      for (Property property : propertiesByIndex) {
        if (!isTrue(property.isLink)) {
          pindex++;
          result += "# property " + property.getName() + "\n";
          result += getName() + "_" + property.getName() + " isA Property\n";
          result += propertySiDIF("name", property.name);
          result += propertySiDIF("label", property.label);
          result += propertySiDIF("type", property.type);
          if (property.index == null)
            property.index = "" + pindex;
          result += propertySiDIF("index", property.index, "Number");
          result += propertySiDIF("sortPos", property.sortPos, "Number");
          result += propertySiDIF("primaryKey", property.primaryKey, "Boolean");
          result += propertySiDIF("mandatory", property.mandatory, "Boolean");
          result += propertySiDIF("namespace", property.namespace);
          result += propertySiDIF("size", property.size, "Number");
          result += propertySiDIF("uploadable", property.uploadable, "Boolean");
          result += propertySiDIF("defaultValue", property.defaultValue);
          result += propertySiDIF("inputType", property.inputType);
          result += propertySiDIF("allowedValues", property.allowedValues);
          result += propertySiDIF("documentation", property.documentation);
          result += propertySiDIF("values_from", property.values_from);
          result += propertySiDIF("showInGrid", property.showInGrid, "Boolean");
          result += propertySiDIF("isLink", property.isLink, "Boolean");
          // FIXME maybe use later again
          // result += propertySiDIF("pageid", property.pageid);

          result += propertySiDIF("topic", getName());
        }
      }
      return result;
    }
    // <<<{user defined topic code}{Topic}{Topic}
  } // class Topic

  /**
   * Manager for Topic
   */
  public static class TopicManager extends TopicBase {

    public String topicName = "Topic";
    public List<Topic> mTopics = new ArrayList<Topic>();
    public transient Map<String, Topic> mTopicMap = new TreeMap<String, Topic>();

    /**
     * add a new Topic
     */
    public Topic add(Topic pTopic) {
      mTopics.add(pTopic);
      mTopicMap.put(pTopic.getName(), pTopic);
      return pTopic;
    }

    /**
     * add a new Topic from the given triple
     */
    public Topic add(TripleQuery query, Triple pTopicTriple) {
      Topic lTopic = new Topic(query, pTopicTriple);
      add(lTopic);
      return lTopic;
    }

    // convert this manager to json format
    public String toJson() {
      return JSON.toJSONString(this);
    }

    // default constructor
    public TopicManager() {
    }

    // construct me from the given triple Query query
    public TopicManager(TripleQuery query) {
      // first query the SiDIF bases triplestore
      TripleQuery lTopicQuery = query.query(null, "isA", "Topic");
      for (Triple lTopicTriple : lTopicQuery.getTriples()) {
        add(query, lTopicTriple);
      }
      // then the SMW triplestore
      lTopicQuery = query.query(null, "Property:IsA", "Topic");
      for (Triple lTopicTriple : lTopicQuery.getTriples()) {
        add(query, lTopicTriple);
      }
      init(query);
    } // constructor for Topic Manager

    // >>>{user defined topicmanager code}{Topic}{Topic}
    /**
     * get a topic by the given name
     * 
     * @param topicName
     *          - the name of the topic to get FIXME - speedup?
     */
    public Topic byName(String topicName) {
      Topic result = null;
      for (Topic topic : mTopics) {
        if (topicName.equals(topic.name)) {
          result = topic;
        }
      }
      return result;
    } // byName

    /**
     * configure Topics: link TargetTopics set Concept Properties
     */
    public void configureTopics() {
      for (Topic topic : mTopics) {
        topic.setConceptProperty();
        topic.linkTargetTopics(this);
      }
    }
    // <<<{user defined topicmanager code}{Topic}{Topic}
  } // class Topic Manager

  /**
   * SMW_Type
   * an SMW_Type is a data type which determines the possible values for that
   * type e.g. a Boolean can hold true/fals values while a Number can hold
   * 3.1459 or 20. A Page can hold the name of a Wiki page see
   * https://semantic-mediawiki.org/wiki/Help:List_of_datatypes
   */
  public static class SMW_Type extends TopicBase {
    public String pageid;
    public String documentation;
    public String type;
    public String typepage;
    public String helppage;
    public String javaType;
    public String usedByProperties;

    public String getDocumentation() {
      return documentation;
    }

    public void setDocumentation(String pDocumentation) {
      documentation = pDocumentation;
    }

    public String getType() {
      return type;
    }

    public void setType(String pType) {
      type = pType;
    }

    public String getTypepage() {
      return typepage;
    }

    public void setTypepage(String pTypepage) {
      typepage = pTypepage;
    }

    public String getHelppage() {
      return helppage;
    }

    public void setHelppage(String pHelppage) {
      helppage = pHelppage;
    }

    public String getJavaType() {
      return javaType;
    }

    public void setJavaType(String pJavaType) {
      javaType = pJavaType;
    }

    public String getUsedByProperties() {
      return usedByProperties;
    }

    public void setUsedByProperties(String pUsedByProperties) {
      usedByProperties = pUsedByProperties;
    }

    /**
     * convert this SMW_Type to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    /**
     * get the pageid for this topic
     */
    public String getPageid() {
      return pageid;
    };

    /**
     * default constructor for SMW_Type
     */
    public SMW_Type() {
    }

    /**
     * construct a SMW_Type from the given Triple
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pSMW_TypeTriple
     *          - the triple to construct me from
     */
    public SMW_Type(TripleQuery query, Triple pSMW_TypeTriple) {
      this(query, pSMW_TypeTriple.getSubject().toString());
    } // constructor

    /**
     * construct a SMW_Type from the given pageId
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pageid
     *          - pageid
     */
    public SMW_Type(TripleQuery query, String pageid) {
      this.pageid = pageid;
      Triple documentationTriple = query.selectSingle(pageid, "documentation",
          null);
      if (documentationTriple == null)
        documentationTriple = query.selectSingle(pageid,
            "Property:SMW_Type_documentation", null);
      if (documentationTriple != null)
        documentation = documentationTriple.getObject().toString();
      Triple typeTriple = query.selectSingle(pageid, "type", null);
      if (typeTriple == null)
        typeTriple = query.selectSingle(pageid, "Property:SMW_Type_type", null);
      if (typeTriple != null)
        type = typeTriple.getObject().toString();
      Triple typepageTriple = query.selectSingle(pageid, "typepage", null);
      if (typepageTriple == null)
        typepageTriple = query.selectSingle(pageid,
            "Property:SMW_Type_typepage", null);
      if (typepageTriple != null)
        typepage = typepageTriple.getObject().toString();
      Triple helppageTriple = query.selectSingle(pageid, "helppage", null);
      if (helppageTriple == null)
        helppageTriple = query.selectSingle(pageid,
            "Property:SMW_Type_helppage", null);
      if (helppageTriple != null)
        helppage = helppageTriple.getObject().toString();
      Triple javaTypeTriple = query.selectSingle(pageid, "javaType", null);
      if (javaTypeTriple == null)
        javaTypeTriple = query.selectSingle(pageid,
            "Property:SMW_Type_javaType", null);
      if (javaTypeTriple != null)
        javaType = javaTypeTriple.getObject().toString();
      Triple usedByPropertiesTriple = query.selectSingle(pageid,
          "usedByProperties", null);
      if (usedByPropertiesTriple == null)
        usedByPropertiesTriple = query.selectSingle(pageid,
            "Property:SMW_Type_usedByProperties", null);
      if (usedByPropertiesTriple != null)
        usedByProperties = usedByPropertiesTriple.getObject().toString();
      init(query);
    } // constructor for SMW_Type

    // >>>{user defined topic code}{SMW_Type}{SMW_Type}
    // <<<{user defined topic code}{SMW_Type}{SMW_Type}
  } // class SMW_Type

  /**
   * Manager for SMW_Type
   */
  public static class SMW_TypeManager extends TopicBase {

    public String topicName = "SMW_Type";
    public List<SMW_Type> mSMW_Types = new ArrayList<SMW_Type>();
    public Map<String, SMW_Type> mSMW_TypeMap = new TreeMap<String, SMW_Type>();

    /**
     * add a new SMW_Type
     */
    public SMW_Type add(SMW_Type pSMW_Type) {
      mSMW_Types.add(pSMW_Type);
      mSMW_TypeMap.put(pSMW_Type.getPageid(), pSMW_Type);
      return pSMW_Type;
    }

    /**
     * add a new SMW_Type from the given triple
     */
    public SMW_Type add(TripleQuery query, Triple pSMW_TypeTriple) {
      SMW_Type lSMW_Type = new SMW_Type(query, pSMW_TypeTriple);
      add(lSMW_Type);
      return lSMW_Type;
    }

    // convert this manager to json format
    public String toJson() {
      return JSON.toJSONString(this);
    }

    // default constructor
    public SMW_TypeManager() {
    }

    // construct me from the given triple Query query
    public SMW_TypeManager(TripleQuery query) {
      // first query the SiDIF bases triplestore
      TripleQuery lSMW_TypeQuery = query.query(null, "isA", "SMW_Type");
      for (Triple lSMW_TypeTriple : lSMW_TypeQuery.getTriples()) {
        add(query, lSMW_TypeTriple);
      }
      // then the SMW triplestore
      lSMW_TypeQuery = query.query(null, "Property:IsA", "SMW_Type");
      for (Triple lSMW_TypeTriple : lSMW_TypeQuery.getTriples()) {
        add(query, lSMW_TypeTriple);
      }
      init(query);
    } // constructor for SMW_Type Manager

    // >>>{user defined topicmanager code}{SMW_Type}{SMW_Type}
    // <<<{user defined topicmanager code}{SMW_Type}{SMW_Type}
  } // class SMW_Type Manager

  /**
   * Property
   * a Property is a Feature/Attribute
   */
  public static class Property extends TopicBase {
    public String pageid;
    public String inputType;
    public String defaultValue;
    public String mandatory;
    public String allowedValues;
    public String uploadable;
    public String index;
    public String sortPos;
    public String showInGrid;
    public String values_from;
    public String isLink;
    public String size;
    public String topic;
    public String label;
    public String name;
    public String primaryKey;
    public String documentation;
    public String namespace;
    public String type;

    public String getInputType() {
      return inputType;
    }

    public void setInputType(String pInputType) {
      inputType = pInputType;
    }

    public String getDefaultValue() {
      return defaultValue;
    }

    public void setDefaultValue(String pDefaultValue) {
      defaultValue = pDefaultValue;
    }

    public String getMandatory() {
      return mandatory;
    }

    public void setMandatory(String pMandatory) {
      mandatory = pMandatory;
    }

    public String getAllowedValues() {
      return allowedValues;
    }

    public void setAllowedValues(String pAllowedValues) {
      allowedValues = pAllowedValues;
    }

    public String getUploadable() {
      return uploadable;
    }

    public void setUploadable(String pUploadable) {
      uploadable = pUploadable;
    }

    public String getIndex() {
      return index;
    }

    public void setIndex(String pIndex) {
      index = pIndex;
    }

    public String getSortPos() {
      return sortPos;
    }

    public void setSortPos(String pSortPos) {
      sortPos = pSortPos;
    }

    public String getShowInGrid() {
      return showInGrid;
    }

    public void setShowInGrid(String pShowInGrid) {
      showInGrid = pShowInGrid;
    }

    public String getValues_from() {
      return values_from;
    }

    public void setValues_from(String pValues_from) {
      values_from = pValues_from;
    }

    public String getIsLink() {
      return isLink;
    }

    public void setIsLink(String pIsLink) {
      isLink = pIsLink;
    }

    public String getSize() {
      return size;
    }

    public void setSize(String pSize) {
      size = pSize;
    }

    public String getTopic() {
      return topic;
    }

    public void setTopic(String pTopic) {
      topic = pTopic;
    }

    public String getLabel() {
      return label;
    }

    public void setLabel(String pLabel) {
      label = pLabel;
    }

    public String getName() {
      return name;
    }

    public void setName(String pName) {
      name = pName;
    }

    public String getPrimaryKey() {
      return primaryKey;
    }

    public void setPrimaryKey(String pPrimaryKey) {
      primaryKey = pPrimaryKey;
    }

    public String getDocumentation() {
      return documentation;
    }

    public void setDocumentation(String pDocumentation) {
      documentation = pDocumentation;
    }

    public String getNamespace() {
      return namespace;
    }

    public void setNamespace(String pNamespace) {
      namespace = pNamespace;
    }

    public String getType() {
      return type;
    }

    public void setType(String pType) {
      type = pType;
    }

    /**
     * convert this Property to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    /**
     * get the pageid for this topic
     */
    public String getPageid() {
      return pageid;
    };

    /**
     * default constructor for Property
     */
    public Property() {
    }

    /**
     * construct a Property from the given Triple
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pPropertyTriple
     *          - the triple to construct me from
     */
    public Property(TripleQuery query, Triple pPropertyTriple) {
      this(query, pPropertyTriple.getSubject().toString());
    } // constructor

    /**
     * construct a Property from the given pageId
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pageid
     *          - pageid
     */
    public Property(TripleQuery query, String pageid) {
      this.pageid = pageid;
      Triple inputTypeTriple = query.selectSingle(pageid, "inputType", null);
      if (inputTypeTriple == null)
        inputTypeTriple = query.selectSingle(pageid,
            "Property:Property_inputType", null);
      if (inputTypeTriple != null)
        inputType = inputTypeTriple.getObject().toString();
      Triple defaultValueTriple = query.selectSingle(pageid, "defaultValue",
          null);
      if (defaultValueTriple == null)
        defaultValueTriple = query.selectSingle(pageid,
            "Property:Property_defaultValue", null);
      if (defaultValueTriple != null)
        defaultValue = defaultValueTriple.getObject().toString();
      Triple mandatoryTriple = query.selectSingle(pageid, "mandatory", null);
      if (mandatoryTriple == null)
        mandatoryTriple = query.selectSingle(pageid,
            "Property:Property_mandatory", null);
      if (mandatoryTriple != null)
        mandatory = mandatoryTriple.getObject().toString();
      Triple allowedValuesTriple = query.selectSingle(pageid, "allowedValues",
          null);
      if (allowedValuesTriple == null)
        allowedValuesTriple = query.selectSingle(pageid,
            "Property:Property_allowedValues", null);
      if (allowedValuesTriple != null)
        allowedValues = allowedValuesTriple.getObject().toString();
      Triple uploadableTriple = query.selectSingle(pageid, "uploadable", null);
      if (uploadableTriple == null)
        uploadableTriple = query.selectSingle(pageid,
            "Property:Property_uploadable", null);
      if (uploadableTriple != null)
        uploadable = uploadableTriple.getObject().toString();
      Triple indexTriple = query.selectSingle(pageid, "index", null);
      if (indexTriple == null)
        indexTriple = query.selectSingle(pageid, "Property:Property_index",
            null);
      if (indexTriple != null)
        index = indexTriple.getObject().toString();
      Triple sortPosTriple = query.selectSingle(pageid, "sortPos", null);
      if (sortPosTriple == null)
        sortPosTriple = query.selectSingle(pageid, "Property:Property_sortPos",
            null);
      if (sortPosTriple != null)
        sortPos = sortPosTriple.getObject().toString();
      Triple showInGridTriple = query.selectSingle(pageid, "showInGrid", null);
      if (showInGridTriple == null)
        showInGridTriple = query.selectSingle(pageid,
            "Property:Property_showInGrid", null);
      if (showInGridTriple != null)
        showInGrid = showInGridTriple.getObject().toString();
      Triple values_fromTriple = query
          .selectSingle(pageid, "values_from", null);
      if (values_fromTriple == null)
        values_fromTriple = query.selectSingle(pageid,
            "Property:Property_values_from", null);
      if (values_fromTriple != null)
        values_from = values_fromTriple.getObject().toString();
      Triple isLinkTriple = query.selectSingle(pageid, "isLink", null);
      if (isLinkTriple == null)
        isLinkTriple = query.selectSingle(pageid, "Property:Property_isLink",
            null);
      if (isLinkTriple != null)
        isLink = isLinkTriple.getObject().toString();
      Triple sizeTriple = query.selectSingle(pageid, "size", null);
      if (sizeTriple == null)
        sizeTriple = query.selectSingle(pageid, "Property:Property_size", null);
      if (sizeTriple != null)
        size = sizeTriple.getObject().toString();
      Triple topicTriple = query.selectSingle(pageid, "topic", null);
      if (topicTriple == null)
        topicTriple = query.selectSingle(pageid, "Property:Property_topic",
            null);
      if (topicTriple != null)
        topic = topicTriple.getObject().toString();
      Triple labelTriple = query.selectSingle(pageid, "label", null);
      if (labelTriple == null)
        labelTriple = query.selectSingle(pageid, "Property:Property_label",
            null);
      if (labelTriple != null)
        label = labelTriple.getObject().toString();
      Triple nameTriple = query.selectSingle(pageid, "name", null);
      if (nameTriple == null)
        nameTriple = query.selectSingle(pageid, "Property:Property_name", null);
      if (nameTriple != null)
        name = nameTriple.getObject().toString();
      Triple primaryKeyTriple = query.selectSingle(pageid, "primaryKey", null);
      if (primaryKeyTriple == null)
        primaryKeyTriple = query.selectSingle(pageid,
            "Property:Property_primaryKey", null);
      if (primaryKeyTriple != null)
        primaryKey = primaryKeyTriple.getObject().toString();
      Triple documentationTriple = query.selectSingle(pageid, "documentation",
          null);
      if (documentationTriple == null)
        documentationTriple = query.selectSingle(pageid,
            "Property:Property_documentation", null);
      if (documentationTriple != null)
        documentation = documentationTriple.getObject().toString();
      Triple namespaceTriple = query.selectSingle(pageid, "namespace", null);
      if (namespaceTriple == null)
        namespaceTriple = query.selectSingle(pageid,
            "Property:Property_namespace", null);
      if (namespaceTriple != null)
        namespace = namespaceTriple.getObject().toString();
      Triple typeTriple = query.selectSingle(pageid, "type", null);
      if (typeTriple == null)
        typeTriple = query.selectSingle(pageid, "Property:Property_type", null);
      if (typeTriple != null)
        type = typeTriple.getObject().toString();
      init(query);
    } // constructor for Property

    // >>>{user defined topic code}{Property}{Property}
    @Override
    public void init(TripleQuery query) {
      if (isLink == null) {
        isLink = "false";
      }
      if (name == null) {
        // use page id e.g. Concept_name
        String idparts[] = pageid.split("_");
        name = pageid.replaceFirst(idparts[0] + "_", "");
      }
      if (label == null) {
        label = name;
      }
      if (type == null) {
        type = "Text";
      }
      if (type.startsWith("Special:Types/")) {
        type = type.replace("Special:Types/", "");
      }
    }
    // <<<{user defined topic code}{Property}{Property}
  } // class Property

  /**
   * Manager for Property
   */
  public static class PropertyManager extends TopicBase {

    public String topicName = "Property";
    public transient List<Property> mPropertys = new ArrayList<Property>();
    public transient Map<String, Property> mPropertyMap = new LinkedHashMap<String, Property>();

    /**
     * add a new Property
     */
    public Property add(Property pProperty) {
      if (mPropertyMap.containsKey(pProperty.getName())) {
        LOGGER.log(Level.WARNING, "duplicate property " + pProperty.getName()
            + " from pageid " + pProperty.getPageid());
      } else {
        mPropertys.add(pProperty);
        mPropertyMap.put(pProperty.getName(), pProperty);
      }
      return pProperty;
    }

    /**
     * add a new Property from the given triple
     */
    public Property add(TripleQuery query, Triple pPropertyTriple) {
      Property lProperty = new Property(query, pPropertyTriple);
      add(lProperty);
      return lProperty;
    }

    // convert this manager to json format
    public String toJson() {
      return JSON.toJSONString(this);
    }

    // default constructor
    public PropertyManager() {
    }

    // construct me from the given triple Query query
    public PropertyManager(TripleQuery query) {
      // first query the SiDIF based triplestore
      TripleQuery lPropertyQuery = query.query(null, "isA", "Property");
      for (Triple lPropertyTriple : lPropertyQuery.getTriples()) {
        add(query, lPropertyTriple);
      }
      // then the SMW triplestore
      lPropertyQuery = query.query(null, "Property:IsA", "Property");
      for (Triple lPropertyTriple : lPropertyQuery.getTriples()) {
        add(query, lPropertyTriple);
      }
      init(query);
    } // constructor for Property Manager

    // >>>{user defined topicmanager code}{Property}{Property}
    // <<<{user defined topicmanager code}{Property}{Property}
  } // class Property Manager

  /**
   * TopicLink
   * 
   */
  public static class TopicLink extends TopicBase {
    public String pageid;
    public String name;
    public String sourceRole;
    public String sourceMultiple;
    public String source;
    public String sourceDocumentation;
    public String targetRole;
    public String targetMultiple;
    public String target;
    public String masterDetail;
    public String targetDocumentation;

    public String getName() {
      return name;
    }

    public void setName(String pName) {
      name = pName;
    }

    public String getSourceRole() {
      return sourceRole;
    }

    public void setSourceRole(String pSourceRole) {
      sourceRole = pSourceRole;
    }

    public String getSourceMultiple() {
      return sourceMultiple;
    }

    public void setSourceMultiple(String pSourceMultiple) {
      sourceMultiple = pSourceMultiple;
    }

    public String getSource() {
      return source;
    }

    public void setSource(String pSource) {
      source = pSource;
    }

    public String getSourceDocumentation() {
      return sourceDocumentation;
    }

    public void setSourceDocumentation(String pSourceDocumentation) {
      sourceDocumentation = pSourceDocumentation;
    }

    public String getTargetRole() {
      return targetRole;
    }

    public void setTargetRole(String pTargetRole) {
      targetRole = pTargetRole;
    }

    public String getTargetMultiple() {
      return targetMultiple;
    }

    public void setTargetMultiple(String pTargetMultiple) {
      targetMultiple = pTargetMultiple;
    }

    public String getTarget() {
      return target;
    }

    public void setTarget(String pTarget) {
      target = pTarget;
    }

    public String getMasterDetail() {
      return masterDetail;
    }

    public void setMasterDetail(String pMasterDetail) {
      masterDetail = pMasterDetail;
    }

    public String getTargetDocumentation() {
      return targetDocumentation;
    }

    public void setTargetDocumentation(String pTargetDocumentation) {
      targetDocumentation = pTargetDocumentation;
    }

    /**
     * convert this TopicLink to a JSON string
     */
    public String toJson() {
      return JSON.toJSONString(this);
    }

    /**
     * get the pageid for this topic
     */
    public String getPageid() {
      return pageid;
    };

    /**
     * default constructor for TopicLink
     */
    public TopicLink() {
    }

    /**
     * construct a TopicLink from the given Triple
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pTopicLinkTriple
     *          - the triple to construct me from
     */
    public TopicLink(TripleQuery query, Triple pTopicLinkTriple) {
      this(query, pTopicLinkTriple.getSubject().toString());
    } // constructor

    /**
     * construct a TopicLink from the given pageId
     * 
     * @param query
     *          - the TripleQuery to get the triples from
     * @param pageid
     *          - pageid
     */
    public TopicLink(TripleQuery query, String pageid) {
      this.pageid = pageid;
      Triple nameTriple = query.selectSingle(pageid, "name", null);
      if (nameTriple == null)
        nameTriple = query
            .selectSingle(pageid, "Property:TopicLink_name", null);
      if (nameTriple != null)
        name = nameTriple.getObject().toString();
      Triple sourceRoleTriple = query.selectSingle(pageid, "sourceRole", null);
      if (sourceRoleTriple == null)
        sourceRoleTriple = query.selectSingle(pageid,
            "Property:TopicLink_sourceRole", null);
      if (sourceRoleTriple != null)
        sourceRole = sourceRoleTriple.getObject().toString();
      Triple sourceMultipleTriple = query.selectSingle(pageid,
          "sourceMultiple", null);
      if (sourceMultipleTriple == null)
        sourceMultipleTriple = query.selectSingle(pageid,
            "Property:TopicLink_sourceMultiple", null);
      if (sourceMultipleTriple != null)
        sourceMultiple = sourceMultipleTriple.getObject().toString();
      Triple sourceTriple = query.selectSingle(pageid, "source", null);
      if (sourceTriple == null)
        sourceTriple = query.selectSingle(pageid, "Property:TopicLink_source",
            null);
      if (sourceTriple != null)
        source = sourceTriple.getObject().toString();
      Triple sourceDocumentationTriple = query.selectSingle(pageid,
          "sourceDocumentation", null);
      if (sourceDocumentationTriple == null)
        sourceDocumentationTriple = query.selectSingle(pageid,
            "Property:TopicLink_sourceDocumentation", null);
      if (sourceDocumentationTriple != null)
        sourceDocumentation = sourceDocumentationTriple.getObject().toString();
      Triple targetRoleTriple = query.selectSingle(pageid, "targetRole", null);
      if (targetRoleTriple == null)
        targetRoleTriple = query.selectSingle(pageid,
            "Property:TopicLink_targetRole", null);
      if (targetRoleTriple != null)
        targetRole = targetRoleTriple.getObject().toString();
      Triple targetMultipleTriple = query.selectSingle(pageid,
          "targetMultiple", null);
      if (targetMultipleTriple == null)
        targetMultipleTriple = query.selectSingle(pageid,
            "Property:TopicLink_targetMultiple", null);
      if (targetMultipleTriple != null)
        targetMultiple = targetMultipleTriple.getObject().toString();
      Triple targetTriple = query.selectSingle(pageid, "target", null);
      if (targetTriple == null)
        targetTriple = query.selectSingle(pageid, "Property:TopicLink_target",
            null);
      if (targetTriple != null)
        target = targetTriple.getObject().toString();
      Triple masterDetailTriple = query.selectSingle(pageid, "masterDetail",
          null);
      if (masterDetailTriple == null)
        masterDetailTriple = query.selectSingle(pageid,
            "Property:TopicLink_masterDetail", null);
      if (masterDetailTriple != null)
        masterDetail = masterDetailTriple.getObject().toString();
      Triple targetDocumentationTriple = query.selectSingle(pageid,
          "targetDocumentation", null);
      if (targetDocumentationTriple == null)
        targetDocumentationTriple = query.selectSingle(pageid,
            "Property:TopicLink_targetDocumentation", null);
      if (targetDocumentationTriple != null)
        targetDocumentation = targetDocumentationTriple.getObject().toString();
      init(query);
    } // constructor for TopicLink

    // >>>{user defined topic code}{TopicLink}{TopicLink}
    public transient Topic sourceTopic = null;
    public transient Topic targetTopic = null;
    // <<<{user defined topic code}{TopicLink}{TopicLink}
  } // class TopicLink

  /**
   * Manager for TopicLink
   */
  public static class TopicLinkManager extends TopicBase {

    public String topicName = "TopicLink";
    public List<TopicLink> mTopicLinks = new ArrayList<TopicLink>();
    public Map<String, TopicLink> mTopicLinkMap = new TreeMap<String, TopicLink>();

    /**
     * add a new TopicLink
     */
    public TopicLink add(TopicLink pTopicLink) {
      mTopicLinks.add(pTopicLink);
      mTopicLinkMap.put(pTopicLink.getPageid(), pTopicLink);
      return pTopicLink;
    }

    /**
     * add a new TopicLink from the given triple
     */
    public TopicLink add(TripleQuery query, Triple pTopicLinkTriple) {
      TopicLink lTopicLink = new TopicLink(query, pTopicLinkTriple);
      add(lTopicLink);
      return lTopicLink;
    }

    // convert this manager to json format
    public String toJson() {
      return JSON.toJSONString(this);
    }

    // default constructor
    public TopicLinkManager() {
    }

    // construct me from the given triple Query query
    public TopicLinkManager(TripleQuery query) {
      // first query the SiDIF bases triplestore
      TripleQuery lTopicLinkQuery = query.query(null, "isA", "TopicLink");
      for (Triple lTopicLinkTriple : lTopicLinkQuery.getTriples()) {
        add(query, lTopicLinkTriple);
      }
      // then the SMW triplestore
      lTopicLinkQuery = query.query(null, "Property:IsA", "TopicLink");
      for (Triple lTopicLinkTriple : lTopicLinkQuery.getTriples()) {
        add(query, lTopicLinkTriple);
      }
      init(query);
    } // constructor for TopicLink Manager

    // >>>{user defined topicmanager code}{TopicLink}{TopicLink}
    // <<<{user defined topicmanager code}{TopicLink}{TopicLink}
  } // class TopicLink Manager
}
@{
  // global variables
  // will only be set if tripleStore argument is available e.g. not for dialogs
  Topic maintopic=null;
  TripleQuery query=null;
  TripleQuery topics=null;
  ContextManager mContextManager=null;
  TopicManager mTopicManager=null;
  String maintopicName=null;
  if (tripleStore!=null) {
    query=tripleStore.query();
    topics=query.query(null,"isA","Topic");
    mContextManager=new ContextManager(tripleStore);
    mTopicManager=new TopicManager(query);
    // PropertyManager mPropertyManager=new PropertyManager(query);
    // TopicLinkManager mTopicLinkManager=new TopicLinkManager(query);
    // SMW_TypeManager mSMW_TypeManager=new SMW_TypeManager(query);
    mTopicManager.configureTopics();
 
    maintopicName=wikiTask.getParams();
    if (maintopicName!=null) {
      maintopic=mTopicManager.byName(maintopicName);
    }
  }
}