blob: 7d5bb2b3c0c6e42c69cf87aaf63c05fd8a263228 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
////////////////////////////////////////////////////////////////////////
//
// Groovy script to generate a types.xml file from a text file in
// a simplified syntax
// This script expects two files names TypeDefinitions.txt and
// PropertyDefinitions.txt in the same directory and generates
// file types.xml that can be imported into the InMemoryServer
//
////////////////////////////////////////////////////////////////////////
def genCommons1(name, id, descr) {
def id1 = id
def localName = name
def ns = ""
// allow syntax name;localName;namespace in property name line
if (id.contains(";")) {
names = id.tokenize(";")
if (names.size() > 0)
id1 = names[0];
if (names.size() > 1)
localName = names[1];
if (names.size() > 2)
ns = names[2];
}
outFile.println(" <id>" + id1 + "</id>")
outFile.println(" <localName>" + localName + "</localName>")
outFile.println(" <displayName>" + name + "</displayName>")
outFile.println(" <queryName>" + name.replaceAll(" ", "_").toUpperCase() + "</queryName>")
outFile.println(" <description>" + descr + "</description>")
outFile.println(" <localNamespace>" + ns + "</localNamespace>")
}
//////////////////////////////////////////////////////////////////
def genCommons2(choices, cardinality, updatability, required, queryable, orderable) {
def cardinalityStr
def updatabilityStr
def requiredStr
def queryableStr
def orderableStr
if (updatability.toLowerCase().startsWith("readonly"))
updatabilityStr = "readonly"
else if (updatability.toLowerCase().startsWith("oncreate"))
updatabilityStr = "oncreate"
else if (updatability.toLowerCase().startsWith("whencheckedout"))
updatabilityStr = "whencheckedout"
else
updatabilityStr = "readwrite"
if (required.toLowerCase().startsWith("true"))
requiredStr = "true"
else
requiredStr = "false"
if (cardinality.toLowerCase().startsWith("multi"))
cardinalityStr = "multi"
else
cardinalityStr = "single"
if (queryable.toLowerCase().startsWith("true"))
queryableStr = "true"
else
queryableStr = "false"
if (orderable.toLowerCase().startsWith("true"))
orderableStr = "true"
else
orderableStr = "false"
outFile.println(" <cardinality>" + cardinalityStr + "</cardinality>")
outFile.println(" <updatability>" + updatabilityStr + "</updatability>")
outFile.println(" <inherited>false</inherited>")
outFile.println(" <required>" + requiredStr + "</required>")
outFile.println(" <queryable>" + queryableStr + "</queryable>")
outFile.println(" <orderable>" + orderableStr + "</orderable>")
outFile.println(" <openChoice>false</openChoice>")
if (null != choices)
genChoices(choices)
}
//////////////////////////////////////////////////////////////////
def genBoolean (name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
outFile.println(" <propertyBooleanDefinition>")
genCommons1(name, uuid, descr)
outFile.println(" <propertyType>boolean</propertyType>")
genCommons2(choices, cardinality, updatability, required, queryable, orderable)
outFile.println(" </propertyBooleanDefinition>")
}
//////////////////////////////////////////////////////////////////
def genDate (name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
outFile.println(" <propertyDateTimeDefinition>")
genCommons1(name, uuid, descr)
outFile.println(" <propertyType>datetime</propertyType>")
genCommons2(choices, cardinality, updatability, required, queryable, orderable)
outFile.println(" </propertyDateTimeDefinition>")
}
//////////////////////////////////////////////////////////////////
def genId (name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
outFile.println(" <propertyIdDefinition>")
genCommons1(name, uuid, descr)
outFile.println(" <propertyType>id</propertyType>")
genCommons2(choices, cardinality, updatability, required, queryable, orderable)
outFile.println(" </propertyIdDefinition>")
}
45//////////////////////////////////////////////////////////////////
def genInteger (name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
outFile.println(" <propertyIntegerDefinition>")
genCommons1(name, uuid, descr)
outFile.println(" <propertyType>integer</propertyType>")
genCommons2(choices, cardinality, updatability, required, queryable, orderable)
outFile.println(" </propertyIntegerDefinition>")
}
//////////////////////////////////////////////////////////////////
def genString (name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
outFile.println(" <propertyStringDefinition>")
genCommons1(name, uuid, descr)
outFile.println(" <propertyType>string</propertyType>")
genCommons2(choices, cardinality, updatability, required, queryable, orderable)
outFile.println(" </propertyStringDefinition>")
}
//////////////////////////////////////////////////////////////////
def genDecimal (name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
outFile.println(" <propertyDecimalDefinition>")
genCommons1(name, uuid, descr)
outFile.println(" <propertyType>decimal</propertyType>")
genCommons2(choices, cardinality, updatability, required, queryable, orderable)
outFile.println(" </propertyDecimalDefinition>")
}
//////////////////////////////////////////////////////////////////
def genChoices (choices) {
choices.each {
keyValue = it.tokenize("=")
String key = keyValue.get(0).trim()
String value = keyValue.get(1).trim()
// println("Found enum with key: " + key + " value: " + value)
outFile.println(" <choice displayName=\"" + value + "\">")
outFile.println(" <value>" + key + "</value>")
outFile.println(" </choice>")
}
}
//////////////////////////////////////////////////////////////////
def genTypeDef (name, id, descr, typeKind, parentType, props) {
String xsiType
String baseId
switch (typeKind) {
case "document":
xsiType = "cmisTypeDocumentDefinitionType"
baseId = "cmis:document"
break;
case "folder":
xsiType = "cmisTypeFolderDefinitionType"
baseId = "cmis:folder"
break;
default:
println("Error illegal type: " + typeKind)
}
if (parentType == null)
parentType = baseId
def id1 = id
def localName = name
def ns = ""
// allow syntax name;localName;namespace in property name line
if (id.contains(";")) {
names = id.tokenize(";")
if (names.size() > 0)
id1 = names[0];
if (names.size() > 1)
localName = names[1];
ns = names[2];
}
outFile.println("<cmisra:type xsi:type=\"" + xsiType + "\">")
outFile.println(" <id>" + id1 + "</id>")
outFile.println(" <localName>" + localName + "</localName>")
outFile.println(" <localNamespace>" + ns + "</localNamespace>")
outFile.println(" <parentId>" + parentType + "</parentId>")
outFile.println(" <displayName>" + name + "</displayName>")
outFile.println(" <queryName>" + name.replaceAll(" ", "_").toUpperCase() + "</queryName>")
outFile.println(" <description>" + descr + "</description>")
outFile.println(" <baseId>" + baseId + "</baseId>")
outFile.println(" <creatable>true</creatable>")
outFile.println(" <fileable>true</fileable>")
outFile.println(" <queryable>true</queryable>")
outFile.println(" <fulltextIndexed>true</fulltextIndexed>")
outFile.println(" <includedInSupertypeQuery>true</includedInSupertypeQuery>")
outFile.println(" <controllablePolicy>false</controllablePolicy>")
outFile.println(" <controllableACL>true</controllableACL>")
if (typeKind == "document") {
outFile.println(" <versionable>false</versionable>")
outFile.println(" <contentStreamAllowed>allowed</contentStreamAllowed>")
}
if (props != null)
props.each {
def propDef = propDefsMap.get(it)
if (propDef != null)
genPropertyDef (propDef.type, propDef.name, propDef.id, propDef.descr, propDef.choices,
propDef.cardinality, propDef.updatability, propDef.required, propDef.queryable, propDef.orderable)
else
println ("Error: unknown property definition " + it + " in type definition " + name)
}
outFile.println("</cmisra:type>")
outFile.println()
outFile.flush()
}
//////////////////////////////////////////////////////////////////
def genPropertyDef(type, name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable) {
switch (type) {
case "boolean":
genBoolean(name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable)
break
case "datetime":
genDate(name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable)
break
case "id":
genId(name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable)
break
case "integer":
genInteger(name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable)
break
case "string":
genString(name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable)
break
case "decimal":
genDecimal(name, uuid, descr, choices, cardinality, updatability, required, queryable, orderable)
break
default:
println("!!!Error: unknown property type " + type);
}
}
//////////////////////////////////////////////////////////////////
def readPropertiesFile(inputFile) {
def propDefMap = [:]
def inFile = new File(inputFile).newReader()
while (inFile.readLine() != null) {
def typeLine = inFile.readLine()
def name = inFile.readLine().trim()
println(" processing property: " + name + " type: " + typeLine)
def id = inFile.readLine().trim()
def descr = inFile.readLine().trim()
def attrs = inFile.readLine().trim()
def choices = null;
def cardinality, updatability, required, queryable, orderable
type = typeLine.tokenize().get(0)
def arr = attrs.split(",")
cardinality = arr.length > 0 ? arr[0].trim() : null
updatability = arr.length > 1 ? arr[1].trim() : null
required = arr.length > 2 ? arr[2].trim() : null
queryable = arr.length > 2 ? arr[3].trim() : "false"
orderable = arr.length > 2 ? arr[4].trim() : "false"
if (typeLine.contains("enum:")) {
choices = typeLine[typeLine.indexOf("enum:")+ 5..typeLine.length()-1].tokenize(";")
}
propDefMap.put(name, [name:name, id:id, descr:descr, type:type, choices:choices, cardinality:cardinality,
updatability:updatability, required:required, queryable:queryable, orderable:orderable])
}
return propDefMap;
}
//////////////////////////////////////////////////////////////////
def readTypeDefinitions(inputFile) {
def typeDefMap = [:]
def inReader = new File(inputFile).newReader()
// def inReader = new StringReader(typeDefInput)
def line = inReader.readLine()
while (line != null) {
def kind = inReader.readLine().trim()
def idLine = inReader.readLine().trim()
def name = inReader.readLine().trim()
def descr = inReader.readLine().trim()
def arr = idLine.split(":")
def id = arr.length>0 ? arr[0].trim() : null
def superType = arr.length>1 ? arr[1].trim() : null
def propDefs = []
def readProperties = true;
while (readProperties) {
line = inReader.readLine()
if (line != null && line.size() > 0)
propDefs.push(line.trim())
else
readProperties = false;
}
println("Reading type def " + name)
typeDefMap.put(name, [name: name, id: id, kind: kind, super: superType, descr: descr, props: propDefs])
}
return typeDefMap
}
//////////////////////////////////////////////////////////////////
def writeTypes(typeDefsMap) {
outFile.println("<chem:typeDefinitions xmlns=\"http://docs.oasis-open.org/ns/cmis/core/200908/\"")
outFile.println(" xmlns:cmisra=\"http://docs.oasis-open.org/ns/cmis/restatom/200908/\"")
outFile.println(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"")
outFile.println(" xmlns:chem=\"http://chemistry.apache.org/schemas/TypeDefnitions\">")
for ( e in typeDefsMap ) {
println("generating type" + e.value.name)
genTypeDef (e.value.name, e.value.id, e.value.descr, e.value.kind, e.value.super, e.value.props)
}
outFile.println("</chem:typeDefinitions>")
}
//////////////////////////////////////////////////////////////////
def writePropDefs(propDefsMap) {
for ( e in propDefsMap ) {
println("generating property" + e.value.name)
genPropertyDef (e.value.type, e.value.name, e.value.id, e.value.descr, e.value.choices,
e.value.cardinality, e.value.updatability, e.value.required)
}
}
//////////////////////////////////////////////////////////////////
// Main program
println("Starting...")
def propsFile = "PropertyDefinitions.txt";
def typesFile = "TypeDefinitions.txt";
def outFileName = "types.xml";
outFile = new File(outFileName).newPrintWriter()
println("Reading type definitions from file " + typesFile);
typeDefsMap = readTypeDefinitions(typesFile)
println("Reading property definitions from file " + propsFile);
propDefsMap = readPropertiesFile(propsFile)
println("Writing out to " + outFileName);
outFile.println("<!-- Generated Output file with type definitions. Do not edit! -->")
writeTypes(typeDefsMap)
outFile.close()
println("...Done.")