Improving solution

This commit is contained in:
Luca Frosini 2023-01-22 19:44:32 +01:00
parent 03859306e8
commit 7a61f15c66
18 changed files with 323 additions and 174 deletions

View File

@ -68,6 +68,11 @@
<artifactId>logback-classic</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.gcube.resource-management</groupId>
<artifactId>gcube-model</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.utils.documentation;
package org.gcube.informationsystem.utils.documentation.generator;
import java.util.ArrayList;
import java.util.Arrays;

View File

@ -1,4 +1,4 @@
package org.gcube.informationsystem.utils.documentation;
package org.gcube.informationsystem.utils.documentation.generator;
import java.io.File;
import java.io.IOException;
@ -48,12 +48,15 @@ public class TypeListGenerator {
protected List<IsRelatedToType> isRelatedToTypes;
protected List<ConsistsOfType> consistsOfTypes;
protected int offsetLevel;
public TypeListGenerator() {
this.propertyTypes = new ArrayList<>();
this.resourceTypes = new ArrayList<>();
this.facetTypes = new ArrayList<>();
this.isRelatedToTypes = new ArrayList<>();
this.consistsOfTypes = new ArrayList<>();
this.offsetLevel = 2;
}
public List<ResourceType> getResourceTypes() {
@ -187,6 +190,7 @@ public class TypeListGenerator {
for(Type type : types) {
DocumentationGenerator dg = getDocumentationGeneratorInstance(clz, type);
dg.setOffsetLevel(offsetLevel);
StringBuffer sb = dg.generateSection();
Files.write(f.toPath(), sb.toString().getBytes(), StandardOpenOption.APPEND);
}
@ -203,6 +207,7 @@ public class TypeListGenerator {
File f = getFile(ENTITIES_FILENAME, true);
DocumentationGenerator edg = new EntityDocumentationGenerator(TypeMapper.createTypeDefinition(Entity.class));
edg.setOffsetLevel(offsetLevel);
StringBuffer sb = edg.generateSection();
Files.write(f.toPath(), sb.toString().getBytes(), StandardOpenOption.APPEND);
@ -211,6 +216,7 @@ public class TypeListGenerator {
f = getFile(RELATIONS_FILENAME, true);
DocumentationGenerator rdg = new RelationDocumentationGenerator(TypeMapper.createTypeDefinition(Relation.class));
rdg.setOffsetLevel(offsetLevel);
sb = rdg.generateSection();
Files.write(f.toPath(), sb.toString().getBytes(), StandardOpenOption.APPEND);

View File

@ -1,57 +0,0 @@
package org.gcube.informationsystem.utils.documentation.knowledge;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
public class FacetKnowledge {
private static FacetKnowledge singleton;
public static FacetKnowledge getInstace() {
if(FacetKnowledge.singleton==null) {
FacetKnowledge.singleton = new FacetKnowledge();
}
return FacetKnowledge.singleton;
}
protected Map<String, Set<LinkedEntity>> map;
private FacetKnowledge(){
this.map = new LinkedHashMap<>();
}
protected void add(String typeName, LinkedEntity linkedEntity) {
Set<LinkedEntity> list = map.get(typeName);
if(list==null) {
list = new TreeSet<>();
map.put(typeName, list);
}
list.add(linkedEntity);
}
public void add(LinkedEntity linkedEntity) {
String source = linkedEntity.getSource();
add(source, linkedEntity);
String relation = linkedEntity.getRelation();
add(relation, linkedEntity);
String target = linkedEntity.getTarget();
add(target, linkedEntity);
}
public void addAll(Collection<LinkedEntity> linkedEntities) {
for(LinkedEntity le : linkedEntities) {
add(le);
}
}
public Set<LinkedEntity> getUsage(String typeName){
Set<LinkedEntity> list = map.get(typeName);
return list;
}
}

View File

@ -1,57 +0,0 @@
package org.gcube.informationsystem.utils.documentation.knowledge;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
public class ResourceKnowledge {
private static ResourceKnowledge singleton;
public static ResourceKnowledge getInstace() {
if(ResourceKnowledge.singleton==null) {
ResourceKnowledge.singleton = new ResourceKnowledge();
}
return ResourceKnowledge.singleton;
}
protected Map<String, Set<LinkedEntity>> map;
private ResourceKnowledge(){
this.map = new LinkedHashMap<>();
}
protected void add(String typeName, LinkedEntity linkedEntity) {
Set<LinkedEntity> list = map.get(typeName);
if(list==null) {
list = new TreeSet<>();
map.put(typeName, list);
}
list.add(linkedEntity);
}
public void add(LinkedEntity linkedEntity) {
String source = linkedEntity.getSource();
add(source, linkedEntity);
String relation = linkedEntity.getRelation();
add(relation, linkedEntity);
String target = linkedEntity.getTarget();
add(target, linkedEntity);
}
public void addAll(List<LinkedEntity> linkedEntities) {
for(LinkedEntity le : linkedEntities) {
add(le);
}
}
public Set<LinkedEntity> getUsage(String typeName){
Set<LinkedEntity> list = map.get(typeName);
return list;
}
}

View File

@ -0,0 +1,109 @@
package org.gcube.informationsystem.utils.documentation.knowledge;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
/**
* @author ycoppel@google.com (Yohann Coppel)
*
* @param <T> Object's type in the tree.
*/
public class Tree<T> {
private T head;
private List<Tree<T>> leafs;
private Tree<T> parent = null;
private HashMap<T, Tree<T>> locate = new HashMap<T, Tree<T>>();
public Tree(T head) {
this.head = head;
this.leafs = new ArrayList<Tree<T>>();
locate.put(head, this);
}
public void addLeaf(T parent, T leaf) {
if (locate.containsKey(parent)) {
locate.get(parent).addLeaf(leaf);
} else {
addLeaf(parent).addLeaf(leaf);
}
}
public Tree<T> addLeaf(T leaf) {
Tree<T> t = new Tree<T>(leaf);
leafs.add(t);
t.parent = this;
t.locate = this.locate;
locate.put(leaf, t);
return t;
}
public Tree<T> setAsParent(T parentRoot) {
Tree<T> t = new Tree<T>(parentRoot);
t.leafs.add(this);
this.parent = t;
t.locate = this.locate;
t.locate.put(head, this);
t.locate.put(parentRoot, t);
return t;
}
public T getHead() {
return head;
}
public Tree<T> getTree(T element) {
return locate.get(element);
}
public Tree<T> getParent() {
return parent;
}
public Collection<T> getSuccessors(T root) {
Collection<T> successors = new ArrayList<T>();
Tree<T> tree = getTree(root);
if (null != tree) {
for (Tree<T> leaf : tree.leafs) {
successors.add(leaf.head);
}
}
return successors;
}
public Collection<Tree<T>> getSubTrees() {
return leafs;
}
public static <T> Collection<T> getSuccessors(T of, Collection<Tree<T>> in) {
for (Tree<T> tree : in) {
if (tree.locate.containsKey(of)) {
return tree.getSuccessors(of);
}
}
return new ArrayList<T>();
}
@Override
public String toString() {
return printTree(0);
}
private static final int indent = 2;
private String printTree(int increment) {
String s = "";
String inc = "";
for (int i = 0; i < increment; ++i) {
inc = inc + " ";
}
s = inc + head;
for (Tree<T> child : leafs) {
s += "\n" + child.printTree(increment + indent);
}
return s;
}
}

View File

@ -0,0 +1,45 @@
package org.gcube.informationsystem.utils.documentation.knowledge;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.gcube.informationsystem.types.reference.Type;
public class TypesKnowledge<T extends Type> {
protected Map<String, T> typeByName;
protected Map<Integer, Set<T>> typesByLevels;
protected Map<String, Integer> levelOfTypes;
protected Map<String, Set<String>> children;
public TypesKnowledge() {
this.typeByName = new HashMap<>();
this.typesByLevels = new HashMap<>();
this.levelOfTypes = new HashMap<>();
this.children = new HashMap<>();
}
public void addType(T type) {
typeByName.put(type.getName(), type);
Set<String> superClasses = type.getSuperClasses();
for(String superClass : superClasses) {
}
}
public Set<T> getTypesByLevel(int level) {
return typesByLevels.get(level);
}
public int getTypeLevel(Type type) {
return getTypeLevel(type.getName());
}
public int getTypeLevel(String typeName) {
return levelOfTypes.get(typeName);
}
}

View File

@ -0,0 +1,73 @@
package org.gcube.informationsystem.utils.documentation.knowledge;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
/**
* @author Luca Frosini (ISTI - CNR)
*/
public class UsageKnowledge {
private static UsageKnowledge facetKnowledge;
private static UsageKnowledge resourceKnowledge;
public static UsageKnowledge getFacetKnowledge() {
if(UsageKnowledge.facetKnowledge==null) {
UsageKnowledge.facetKnowledge = new UsageKnowledge();
}
return UsageKnowledge.facetKnowledge;
}
public static UsageKnowledge getResourceKnowledge() {
if(UsageKnowledge.resourceKnowledge==null) {
UsageKnowledge.resourceKnowledge = new UsageKnowledge();
}
return UsageKnowledge.resourceKnowledge;
}
protected Map<String, Set<LinkedEntity>> map;
private UsageKnowledge(){
this.map = new LinkedHashMap<>();
}
protected void add(String typeName, LinkedEntity linkedEntity) {
Set<LinkedEntity> list = map.get(typeName);
if(list==null) {
list = new TreeSet<>();
map.put(typeName, list);
}
list.add(linkedEntity);
}
public void add(LinkedEntity linkedEntity) {
if(linkedEntity!=null) {
String source = linkedEntity.getSource();
add(source, linkedEntity);
String relation = linkedEntity.getRelation();
add(relation, linkedEntity);
String target = linkedEntity.getTarget();
add(target, linkedEntity);
}
}
public void addAll(Collection<LinkedEntity> linkedEntities) {
if(linkedEntities!=null) {
for(LinkedEntity le : linkedEntities) {
add(le);
}
}
}
public Set<LinkedEntity> getUsage(String typeName){
Set<LinkedEntity> list = map.get(typeName);
return list;
}
}

View File

@ -29,32 +29,30 @@ public abstract class DocumentationGenerator {
protected final Type type;
protected final AccessType requiredType;
protected final String superClassToBeExcluded;
protected final int requiredNumberOfColumns;
protected String superClassToBeExcluded;
protected int requiredNumberOfColumns;
protected int offsetLevel;
protected int level;
protected DocumentationGenerator(Type type, AccessType requiredType) {
this(type, requiredType, DEFAULT_NUMBER_OF_COLUMNS, null);
}
protected DocumentationGenerator(Type type, AccessType requiredType, int requiredNumberOfColumns) {
this(type, requiredType, requiredNumberOfColumns, null);
}
protected DocumentationGenerator(Type type, AccessType requiredType, String superClassToBeExcluded) {
this(type, requiredType, DEFAULT_NUMBER_OF_COLUMNS, superClassToBeExcluded);
}
protected DocumentationGenerator(Type type, AccessType requiredType, int requiredNumberOfColumns, String superClassToBeExcluded) {
this.type = type;
this.requiredType = requiredType;
AccessType accessType = type.getAccessType();
if(accessType!=requiredType) {
throw new RuntimeException(type.getName() + " is not a " + requiredType.getName() + " type");
}
this.requiredNumberOfColumns = requiredNumberOfColumns;
this.superClassToBeExcluded = superClassToBeExcluded;
this.requiredNumberOfColumns = DEFAULT_NUMBER_OF_COLUMNS;
this.superClassToBeExcluded = null;
this.offsetLevel = 0;
}
public void setLevel(int level) {
this.level = level;
}
public void setOffsetLevel(int offsetLevel) {
this.offsetLevel = offsetLevel;
}
protected Row getPropertyFieldsBoldRow() {
Row row = new Row(RowType.NORMAL);
Cell name = new Cell();
@ -273,6 +271,11 @@ public abstract class DocumentationGenerator {
return addCellSpanToRow(row, content, cellSpan);
}
protected Row getHeadingRowCellSpan(String content, int cellSpan) {
Row row = new Row(RowType.HEADING);
return addCellSpanToRow(row, content, cellSpan);
}
protected Table addPropertyRows(Table table, Set<PropertyDefinition> properties) {
table.appendRow(getPropertyFieldsBoldRow());
if(properties!=null && properties.size()>0) {
@ -358,7 +361,8 @@ public abstract class DocumentationGenerator {
stringBuffer.append("\n");
String name = type.getName();
Section section = new Section();
stringBuffer.append(section.generateSection(SectionType.HEADING_3, name));
SectionType sectionType = SectionType.values()[level+offsetLevel];
stringBuffer.append(section.generateSection(sectionType, name));
stringBuffer.append(type.getDescription());
stringBuffer.append("\n");

View File

@ -19,25 +19,16 @@ import org.gcube.informationsystem.utils.documentation.rst.table.Table;
public class EntityDocumentationGenerator extends DocumentationGenerator {
public EntityDocumentationGenerator(Type type) {
super(type, AccessType.ENTITY, 4, TypeMapper.getType(EntityElement.class));
super(type, AccessType.ENTITY);
this.requiredNumberOfColumns = 4;
this.superClassToBeExcluded = TypeMapper.getType(EntityElement.class);
setLevel(0);
}
protected EntityDocumentationGenerator(Type type, AccessType requiredType) {
super(type, requiredType);
}
protected EntityDocumentationGenerator(Type type, AccessType requiredType, int requiredNumberOfColumns) {
super(type, requiredType, requiredNumberOfColumns);
}
protected EntityDocumentationGenerator(Type type, AccessType requiredType, String superClassToBeExcluded) {
super(type, requiredType, superClassToBeExcluded);
}
protected EntityDocumentationGenerator(Type type, AccessType requiredType, int requiredNumberOfColumns, String superClassToBeExcluded) {
super(type, requiredType, requiredNumberOfColumns, superClassToBeExcluded);
}
protected Row getEntityHeadingRow() {
Row row = new Row(RowType.HEADING);
row = addCellSpanToRow(row, "Properties", requiredNumberOfColumns);

View File

@ -6,7 +6,7 @@ import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.types.reference.Type;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
import org.gcube.informationsystem.types.reference.properties.PropertyDefinition;
import org.gcube.informationsystem.utils.documentation.knowledge.FacetKnowledge;
import org.gcube.informationsystem.utils.documentation.knowledge.UsageKnowledge;
import org.gcube.informationsystem.utils.documentation.rst.table.Table;
/**
@ -16,6 +16,11 @@ public class FacetDocumentationGenerator extends EntityDocumentationGenerator {
public FacetDocumentationGenerator(Type type) {
super(type, AccessType.FACET);
int level = 1;
if(type.getName().compareTo(requiredType.getName())!=0) {
++level;
}
setLevel(level);
}
@Override
@ -28,7 +33,7 @@ public class FacetDocumentationGenerator extends EntityDocumentationGenerator {
table.appendRow(getKnownUsageBoldRow());
table.appendRow(getSourceTargetBoldRow());
FacetKnowledge fk = FacetKnowledge.getInstace();
UsageKnowledge fk = UsageKnowledge.getFacetKnowledge();
Set<LinkedEntity> usage = fk.getUsage(type.getName());
addLinkedEntities(table, usage);

View File

@ -6,8 +6,7 @@ import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.types.reference.Type;
import org.gcube.informationsystem.types.reference.entities.ResourceType;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
import org.gcube.informationsystem.utils.documentation.knowledge.FacetKnowledge;
import org.gcube.informationsystem.utils.documentation.knowledge.ResourceKnowledge;
import org.gcube.informationsystem.utils.documentation.knowledge.UsageKnowledge;
import org.gcube.informationsystem.utils.documentation.rst.table.Table;
/**
@ -17,10 +16,15 @@ public class ResourceDocumentationGenerator extends EntityDocumentationGenerator
public ResourceDocumentationGenerator(Type type) {
super(type,AccessType.RESOURCE);
int level = 1;
if(type.getName().compareTo(requiredType.getName())!=0) {
++level;
}
setLevel(level);
ResourceType rt = (ResourceType) type;
FacetKnowledge fk = FacetKnowledge.getInstace();
UsageKnowledge fk = UsageKnowledge.getFacetKnowledge();
fk.addAll(rt.getFacets());
ResourceKnowledge rk = ResourceKnowledge.getInstace();
UsageKnowledge rk = UsageKnowledge.getResourceKnowledge();
rk.addAll(rt.getResources());
}
@ -30,11 +34,11 @@ public class ResourceDocumentationGenerator extends EntityDocumentationGenerator
table.appendRow(getSourceTargetHeadingRow());
table.appendRow(getRowCellSpan("**Facets**", requiredNumberOfColumns));
ResourceType resourceType = (ResourceType) type;
FacetKnowledge fk = FacetKnowledge.getInstace();
UsageKnowledge fk = UsageKnowledge.getFacetKnowledge();
Set<LinkedEntity> facets = fk.getUsage(resourceType.getName());
addLinkedEntities(table, facets);
table.appendRow(getRowCellSpan("**Relations**", requiredNumberOfColumns));
ResourceKnowledge rk = ResourceKnowledge.getInstace();
UsageKnowledge rk = UsageKnowledge.getResourceKnowledge();
Set<LinkedEntity> resources = rk.getUsage(resourceType.getName());
addLinkedEntities(table, resources);
return table;

View File

@ -17,7 +17,14 @@ import org.gcube.informationsystem.utils.documentation.rst.table.Table;
public class PropertyDocumentationGenerator extends DocumentationGenerator {
public PropertyDocumentationGenerator(Type type) {
super(type, AccessType.PROPERTY, 4, TypeMapper.getType(PropertyElement.class));
super(type, AccessType.PROPERTY);
this.requiredNumberOfColumns = 4;
this.superClassToBeExcluded = TypeMapper.getType(PropertyElement.class);
int level = 0;
if(type.getName().compareTo(requiredType.getName())!=0) {
++level;
}
setLevel(level);
}
@Override

View File

@ -5,7 +5,7 @@ import java.util.Set;
import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.types.reference.Type;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
import org.gcube.informationsystem.utils.documentation.knowledge.FacetKnowledge;
import org.gcube.informationsystem.utils.documentation.knowledge.UsageKnowledge;
import org.gcube.informationsystem.utils.documentation.rst.table.Table;
/**
@ -15,6 +15,11 @@ public class ConsistsOfDocumentationGenerator extends RelationDocumentationGener
public ConsistsOfDocumentationGenerator(Type type) {
super(type, AccessType.CONSISTS_OF);
int level = 1;
if(type.getName().compareTo(requiredType.getName())!=0) {
++level;
}
setLevel(level);
}
@Override
@ -22,7 +27,8 @@ public class ConsistsOfDocumentationGenerator extends RelationDocumentationGener
Table table = super.getTable();
table.appendRow(getKnownUsageBoldRow());
FacetKnowledge fk = FacetKnowledge.getInstace();
table.appendRow(getSourceTargetBoldRow());
UsageKnowledge fk = UsageKnowledge.getFacetKnowledge();
Set<LinkedEntity> facets = fk.getUsage(type.getName());
addLinkedEntities(table, facets);

View File

@ -5,7 +5,7 @@ import java.util.Set;
import org.gcube.informationsystem.base.reference.AccessType;
import org.gcube.informationsystem.types.reference.Type;
import org.gcube.informationsystem.types.reference.properties.LinkedEntity;
import org.gcube.informationsystem.utils.documentation.knowledge.ResourceKnowledge;
import org.gcube.informationsystem.utils.documentation.knowledge.UsageKnowledge;
import org.gcube.informationsystem.utils.documentation.rst.table.Table;
/**
@ -15,6 +15,11 @@ public class IsRelatedToDocumentationGenerator extends RelationDocumentationGene
public IsRelatedToDocumentationGenerator(Type type) {
super(type, AccessType.IS_RELATED_TO);
int level = 1;
if(type.getName().compareTo(requiredType.getName())!=0) {
++level;
}
setLevel(level);
}
@Override
@ -22,7 +27,8 @@ public class IsRelatedToDocumentationGenerator extends RelationDocumentationGene
Table table = super.getTable();
table.appendRow(getKnownUsageBoldRow());
ResourceKnowledge rk = ResourceKnowledge.getInstace();
table.appendRow(getSourceTargetBoldRow());
UsageKnowledge rk = UsageKnowledge.getResourceKnowledge();
Set<LinkedEntity> resources = rk.getUsage(type.getName());
addLinkedEntities(table, resources);

View File

@ -21,16 +21,14 @@ import org.gcube.informationsystem.utils.documentation.rst.table.Table;
public class RelationDocumentationGenerator extends DocumentationGenerator {
public RelationDocumentationGenerator(Type type) {
super(type, AccessType.RELATION, TypeMapper.getType(RelationElement.class));
super(type, AccessType.RELATION);
this.superClassToBeExcluded = TypeMapper.getType(RelationElement.class);
setLevel(0);
}
protected RelationDocumentationGenerator(Type type, AccessType requiredType) {
super(type, requiredType);
}
protected RelationDocumentationGenerator(Type type, AccessType requiredType, String superClassToBeExcluded) {
super(type, requiredType, superClassToBeExcluded);
}
protected Row getTypeDefinitionRow(RelationType<? extends EntityType, ? extends EntityType> relationType) {
Row row = new Row(RowType.NORMAL);
@ -64,13 +62,14 @@ public class RelationDocumentationGenerator extends DocumentationGenerator {
@Override
protected Table getTable() {
Table table = new Table();
table.appendRow(getSourceTargetHeadingRow());
table.appendRow(getHeadingRowCellSpan("**Definition**", requiredNumberOfColumns));
table.appendRow(getRowCellSpan("**Definition**", requiredNumberOfColumns));
table.appendRow(getSourceTargetBoldRow());
@SuppressWarnings("unchecked")
RelationType<? extends EntityType, ? extends EntityType> relationType = (RelationType<? extends EntityType, ? extends EntityType>) type;
table.appendRow(getTypeDefinitionRow(relationType));
table.appendRow(getRowCellSpan("**Properties**", requiredNumberOfColumns));
Set<PropertyDefinition> properties = type.getProperties();
table = addPropertyRows(table, properties);

View File

@ -6,16 +6,18 @@ package org.gcube.informationsystem.utils.documentation.rst;
public class Section {
public enum SectionType {
HEADING_1(true, "*"),
HEADING_2(false, "="),
HEADING_3(false, "-"),
HEADING_4(false, "^");
HEADING_1(true, "#"),
HEADING_2(true, "*"),
HEADING_3(false, "="),
HEADING_4(false, "-"),
HEADING_5(false, "^"),
HEADING_6(false, "\"");
boolean both;
boolean overline;
String separator;
private SectionType(boolean both, String separator) {
this.both = both;
private SectionType(boolean overline, String separator) {
this.overline = overline;
this.separator = separator;
}
}
@ -31,7 +33,7 @@ public class Section {
public StringBuffer generateSection(SectionType sectionType, String sectionTitle) {
StringBuffer stringBuffer = new StringBuffer();
int lenght = sectionTitle.length();
if(sectionType.both) {
if(sectionType.overline) {
stringBuffer.append(getSectionSeparation(sectionType.separator, lenght));
stringBuffer.append("\n");
}

View File

@ -1,5 +1,6 @@
package org.gcube.informationsystem.utils.documentation;
import org.gcube.informationsystem.utils.documentation.generator.ClassesDiscoveryGenerator;
import org.junit.Test;
/**