Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swd 121 black and white lists for generators #28

Merged
merged 4 commits into from
Oct 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,38 @@ gradle myRun -PmyArgs="-o,/tmp/test_beans,-m,src/test/resources/test_schemas/mul
-gp,destFileNameExt=java,-gp,packageName=de.sw.atlas.test"
```
### Usage of the release

```bash
./jsonCodeGen.sh
Usage: de.lisaplus.atlas.DoCodeGen [options]
Options:
-at, --add-tag
add a text as tag to a specific type, f.e. -at User=unused
Default: []
-b, --black-list
black listed type, multiple usage possible
Default: []
-g, --generator
generator that are used with the model. This parameter can be used
multiple times
Default: []
-gp, --generator-parameter
special parameter that are passed to template via maps
Default: []
-h, --help

* -m, --model
Path to JSON schema to parse
* -o, --outputBase
Base directory for the output
-rt, --remove-tag
remove a tag from a specific type, f.e. -at User=unused
Default: []
-w, --white-list
white listed type, multiple usage possible
Default: []
```

After you built a release with gradle or you download a release bundle you can start
the program with the contained start script. If you start it with the help option you
get a full description of the possible parameters
Expand Down
11 changes: 11 additions & 0 deletions Releases.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
## 0.8.0
- command line switches for type black- and white-lists
- command line switch to add tags to types
- command line switch to remove a tag from types
- command line switch to remove a tag from all types
- enforce camel-case type names in models
- add guidTypeColor generator parameter for plantuml
- remove printTags generator parameter for plantuml
- add printTypeTags generator parameter for plantuml
- add printPropTags generator parameter for plantuml

## 0.7.5
- deep copy functions for types
- introduce pure array type to handle definitions where arrays contain only arrays, f.e. geoJson Polygons
Expand Down
107 changes: 106 additions & 1 deletion src/main/groovy/de/lisaplus/atlas/DoCodeGen.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,71 @@ import org.slf4j.LoggerFactory
* Created by eiko on 30.05.17.
*/
class DoCodeGen {
/**
* model file
*/
@Parameter(names = [ '-m', '--model' ], description = "Path to JSON schema to parse", required = true)
String model

/**
* Base directory for the output
*/
@Parameter(names = [ '-o', '--outputBase' ], description = "Base directory for the output", required = true)
String outputBaseDir

/**
* Generator to use
*/
@Parameter(names = ['-g', '--generator'], description = "generator that are used with the model. This parameter can be used multiple times")
List<String> generators = []

/**
* Generator parameter
*/
@Parameter(names = ['-gp', '--generator-parameter'], description = "special parameter that are passed to template via maps")
List<String> generator_parameters = []

/**
* Type white list
*/
@Parameter(names = ['-w', '--white-list'], description = "white listed type, multiple usage possible")
List<String> whiteListed = []

/**
* Type black list
*/
@Parameter(names = ['-b', '--black-list'], description = "black listed type, multiple usage possible")
List<String> blackListed = []

/**
* Print help
*/
@Parameter(names = ['-h','--help'], help = true)
boolean help = false

/**
* List of type-name tag-text tuple, The tags will be merged after initialization with the object tree
*/
@Parameter(names = ['-at', '--add-tag'], description = "add a text as tag to a specific type, f.e. -at User=unused")
List<String> typeAddTagList = []

/**
* List of type-name tag-text tuple, after initialization the tags will be removed for the given types in the object tree
*/
@Parameter(names = ['-rt', '--remove-tag'], description = "remove a tag from a specific type, f.e. -rt User=unused")
List<String> typeRemoveTagList = []

/**
* List of tags-text tuple, after initialization the tags will be removed for the given types in the object tree
*/
@Parameter(names = ['-rta', '--remove-tag-all'], description = "remove a tag from all model types, f.e. -rta rest")
List<String> typeRemoveTagAllList = []

/**
* The datamodel parsed by the builder. It is public accessible for tests
*/
Model dataModel

static void main(String ... args) {
DoCodeGen doCodeGen = new DoCodeGen()
try {
Expand Down Expand Up @@ -87,9 +137,12 @@ class DoCodeGen {
log.error("unknown file type, currently only jscon schema and xsd are supported: ${model}")
System.exit(1)
}
Model dataModel = builder.buildModel(modelFile)
dataModel = builder.buildModel(modelFile)
adjustTagsForModel(dataModel)
// convert extra generator parameter to a map
Map<String,String> extraParameters = getMapFromGeneratorParams(generator_parameters)
extraParameters['blackListed']=blackListed
extraParameters['whiteListed']=whiteListed
if (generators==null || generators.isEmpty()) {
log.warn('no generators configured - skip')
}
Expand Down Expand Up @@ -290,6 +343,58 @@ class DoCodeGen {
print (usageFile.getText())
}

private void adjustTagsForModel(Model dataModel) {
Map<String, List<String>> typeAddTagMap = mapFromConfig(typeAddTagList)
Map<String, List<String>> typeRemoveTagMap = mapFromConfig(typeRemoveTagList)
dataModel.types.each { type ->
// remove all tags
typeRemoveTagAllList.each { tag ->
if (type.tags.contains(tag)) {
type.tags.remove(tag)
}
}
// remove undesired tags
List<String> tagsToRemove = typeRemoveTagMap[type.name]
if (tagsToRemove) {
// remove tags
tagsToRemove.each { tag ->
type.tags.remove(tag)
}
}
// add new tags
List<String> tagsToAdd = typeAddTagMap[type.name]
if (tagsToAdd) {
// add tags
tagsToAdd.each { tag ->
if (!type.tags.contains(tag)) {
type.tags.add(tag)
}
}
}
}
}

private Map<String, List<String>> mapFromConfig(List<String> config) {
Map<String, List<String>> ret = [:]
if (!config) return ret
config.each { typeTagStr ->
def typeTagArray = typeTagStr.split('=')
if (typeTagArray.length>2) {
println "[mapFromConfig] - wrong type/tag-tuple: $typeTagStr"
return
}
def typeName = typeTagArray[0].trim()
def tag = typeTagArray[1].trim()
List<String> alreadyExistingValues = ret[typeName]
if (alreadyExistingValues && (!alreadyExistingValues.contains(tag))) {
alreadyExistingValues.add(tag)
}
else {
ret[typeName] = [tag]
}
}
return ret
}

private static final Logger log=LoggerFactory.getLogger(DoCodeGen.class)
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ class BuildHelper {
static String string2Name(String s,boolean firstUpper=true) {
def ret = s.replaceAll('[^a-zA-Z0-9]','_')
if (firstUpper) {
return ret.substring(0,1).toUpperCase()+ret.substring(1)
return ret.substring(0,1).toUpperCase()+makeCamelCase(ret.substring(1))
}
else {
return ret.substring(0,1).toLowerCase()+makeCamelCase(ret.substring(1))
}
else
return ret.substring(0,1).toLowerCase()+ret.substring(1)
}

static String makeCamelCase(String s) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ abstract class MultiFileGenarator extends GeneratorBase implements ICodeGen {
data.extraParam = [:]
}

def blackListed=data.extraParam['blackListed']
def whiteListed=data.extraParam['whiteListed']

def shouldRemoveEmptyLines = extraParams['removeEmptyLines']

def neededAttrib = extraParams['containsAttrib']
Expand All @@ -46,6 +49,16 @@ abstract class MultiFileGenarator extends GeneratorBase implements ICodeGen {
return prop.name==missingAttrib
} == null : true

boolean handleType=true;
if (whiteListed && (!whiteListed.contains(type.name))) {
handleType = false
println "ingnored by white-list: ${type.name}"
}
else if (blackListed && blackListed.contains(type.name)) {
handleType = false
println "ingnored by black-list: ${type.name}"
}

boolean handleTag = neededTag ? type.tags.find { tag ->
return tag==neededTag
} != null : true
Expand All @@ -56,7 +69,7 @@ abstract class MultiFileGenarator extends GeneratorBase implements ICodeGen {
} == null
}

if (handleNeeded && handleMissing && handleTag) {
if (handleType && handleNeeded && handleMissing && handleTag) {
data.put('currentType', type)
def ergebnis = template.make(data)
def destFileName = getDestFileName(model, extraParams, type)
Expand Down
1 change: 1 addition & 0 deletions src/main/resources/docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ build/release/jsonCodeGen.sh -o /tmp/test_beans -m src/test/resources/test_schem

### PlantUML
- printTags - if set to true then plantuml prints also tags to the diagrams
- guidTypeColor - if given that color is used as background for the guid-types, f.e. -gp guidTypeColor=adadad

### Base generators
* multifiles - creates multiple files from model and extra given template
Expand Down
81 changes: 71 additions & 10 deletions src/main/resources/templates/meta/plantuml.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
<%
def printTypeTagsValue = extraParam.printTypeTags=='false' ? false : true
def printPropTagsValue = extraParam.printPropTags=='true' ? true : false
def ignoreUnRefTypes = extraParam.ignoreUnRefTypes=='true' ? true : false

def guidTypeColor = extraParam.guidTypeColor ? extraParam.guidTypeColor : 'e4ffd4'
def printJoins = extraParam.printJoins
def printStereoType = { type ->
if ( type instanceof de.lisaplus.atlas.model.InnerType ) {
Expand All @@ -15,19 +20,75 @@ def printStereoType = { type ->
}

def printPropTags = { prop ->
if (extraParam.printTags==true && prop.tags) {
if (printPropTagsValue && prop.tags) {
return "<color:#888888 ><&tag> <size:10><i>${prop.tags}</i>"
}
else
return ''
}

def printTypeTags = { type ->
if (printTypeTagsValue && type.tags) {
def s = null
type.tags.each { tag ->
if (s!=null) {
s+=',\\n'
s+=tag
}
else
s=tag
}
return " <${s}>"
}
else
return ''
}


def typesToIgnore = []

extraParam.blackListed.each { typeName ->
typesToIgnore.add(typeName)
}

if (ignoreUnRefTypes) {
// remove unreferenced type from the diagram
def linkedTypes=[]

model.types.findAll { type ->
! typesToIgnore.contains(type.name)
}.each { type ->
type.properties.each { prop ->
def propType
if (prop.isRefTypeOrComplexType()) {
propType = prop.type.type.name
}
else if (prop.implicitRef) {
propType = prop.implicitRef.type.name
}
if (!linkedTypes.contains(propType)) {
linkedTypes.add(propType)
}
}
if (type.refOwner && !linkedTypes.contains(type.name)) {
linkedTypes.add(type.name)
}
}
model.types.each { type ->
if (!linkedTypes.contains(type.name) && !typesToIgnore.contains(type.name)) {
typesToIgnore.add(type.name)
}
}
}

%>
<% if (extraParam.markdown) { %>
```plantuml
<% } else { %>
@startuml
<% } %>
skinparam roundcorner 10

skinparam class {
BackgroundColor #FFFFFF
ArrowColor #000000
Expand All @@ -36,7 +97,7 @@ skinparam class {
BorderColor<<InnerType>> #777777
BackgroundColor<<InnerType>> #EEEEEE

BackgroundColor<<GidType>> #e4ffd4
BackgroundColor<<GidType>> #${guidTypeColor}

FontName Courier
FontSize 12
Expand All @@ -54,8 +115,10 @@ skinparam classAttribute {
FontSize 12
}

<% model.types.each { type -> %>
class ${firstUpperCase.call(type.name)} ${ printStereoType(type) } << ( ,${type.color}) >> {
<% model.types.findAll { type ->
! typesToIgnore.contains(type.name)
}.each { type -> %>
class ${firstUpperCase.call(type.name)} ${printTypeTags(type) }${ printStereoType(type) } << ( ,${type.color}) >> {
<% def i=0; type.properties.each { prop ->
def arrayStr = prop.type.isArray ? '[]' : ''
i++
Expand All @@ -70,19 +133,17 @@ class ${firstUpperCase.call(type.name)} ${ printStereoType(type) } << ( ,${typ
<% } %>
<% } %>
}
<% if (type.description || (extraParam.printTags==true && type.tags)) { %>
<% if (type.description) { %>
note top of ${firstUpperCase.call(type.name)}
${breakTxt.call(type.description,10)}
<% if (extraParam.printTags==true && type.tags) { %>
..
<&tag> //${type.tags}//
<% } %>
end note
<% } %>
<% } %>
hide methods

<% model.types.each { type -> %>
<% model.types.findAll { type ->
! typesToIgnore.contains(type.name)
}.each { type -> %>
<% def linkedTypes=[] %>
<% type.properties.each { prop -> %>
<% if (prop.isRefTypeOrComplexType()) { %>
Expand Down
Loading