2023-01-23 16:21:01 +01:00
|
|
|
package org.gcube.informationsystem.utils.documentation.generator;
|
|
|
|
|
2023-01-24 16:54:00 +01:00
|
|
|
import java.io.File;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.StandardOpenOption;
|
2023-01-24 17:19:47 +01:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
2023-01-23 16:21:01 +01:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.TreeMap;
|
|
|
|
|
|
|
|
import org.gcube.informationsystem.base.reference.AccessType;
|
2023-01-24 17:19:47 +01:00
|
|
|
import org.gcube.informationsystem.model.reference.properties.Encrypted;
|
|
|
|
import org.gcube.informationsystem.model.reference.properties.Header;
|
|
|
|
import org.gcube.informationsystem.model.reference.properties.PropagationConstraint;
|
|
|
|
import org.gcube.informationsystem.model.reference.properties.Property;
|
2023-01-23 16:21:01 +01:00
|
|
|
import org.gcube.informationsystem.types.TypeMapper;
|
|
|
|
import org.gcube.informationsystem.types.reference.Type;
|
2023-01-24 16:54:00 +01:00
|
|
|
import org.gcube.informationsystem.utils.documentation.knowledge.Node;
|
|
|
|
import org.gcube.informationsystem.utils.documentation.knowledge.NodeElaborator;
|
2023-01-23 16:21:01 +01:00
|
|
|
import org.gcube.informationsystem.utils.documentation.knowledge.Tree;
|
2023-01-24 16:54:00 +01:00
|
|
|
import org.gcube.informationsystem.utils.documentation.model.DocumentationGenerator;
|
2023-01-24 18:17:47 +01:00
|
|
|
import org.gcube.informationsystem.utils.documentation.model.entities.ResourceDocumentationGenerator;
|
2023-01-23 16:21:01 +01:00
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Luca Frosini (ISTI - CNR)
|
|
|
|
*/
|
2023-01-24 16:54:00 +01:00
|
|
|
public class TreeGenerator extends Generator {
|
2023-01-23 16:21:01 +01:00
|
|
|
|
|
|
|
private static final Logger logger = LoggerFactory.getLogger(TreeGenerator.class);
|
|
|
|
|
2023-01-24 16:54:00 +01:00
|
|
|
public static final String IS_MODEL_FILENAME = "is-model.rst";
|
|
|
|
public static final String PROPERTIES_FILENAME = "properties.rst";
|
|
|
|
public static final String ENTITIES_FILENAME = "entities.rst";
|
|
|
|
public static final String RELATIONS_FILENAME = "relations.rst";
|
|
|
|
|
2023-01-24 17:36:06 +01:00
|
|
|
protected static final List<Class<? extends Property>> isModelProperties;
|
|
|
|
protected static final List<String> isModelPropertyNames;
|
|
|
|
|
|
|
|
static {
|
|
|
|
isModelProperties = new ArrayList<>();
|
|
|
|
isModelProperties.add(Header.class);
|
|
|
|
isModelProperties.add(Encrypted.class);
|
|
|
|
isModelProperties.add(PropagationConstraint.class);
|
|
|
|
|
|
|
|
isModelPropertyNames= new ArrayList<>();
|
|
|
|
isModelPropertyNames.add(Header.NAME);
|
|
|
|
isModelPropertyNames.add(Encrypted.NAME);
|
|
|
|
isModelPropertyNames.add(PropagationConstraint.NAME);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-01-23 16:21:01 +01:00
|
|
|
protected Map<AccessType, Tree> types;
|
|
|
|
|
|
|
|
public TreeGenerator() {
|
|
|
|
types = new TreeMap<>();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void addType(Type type) {
|
|
|
|
AccessType accessType = type.getAccessType();
|
|
|
|
if(types.get(accessType)==null) {
|
|
|
|
Type head = TypeMapper.createTypeDefinition(accessType.getTypeClass());
|
|
|
|
Tree tree = new Tree(head);
|
|
|
|
types.put(accessType, tree);
|
|
|
|
}
|
|
|
|
if(type.getName().compareTo(accessType.getName())==0) {
|
2023-01-24 16:54:00 +01:00
|
|
|
// Head has been already added
|
2023-01-23 16:21:01 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
Tree tree = types.get(accessType);
|
|
|
|
tree.addNode(type);
|
|
|
|
}
|
|
|
|
|
2023-01-24 16:54:00 +01:00
|
|
|
public void elaborateTree(final AccessType at, Tree tree, final File file) throws Exception {
|
2023-01-24 19:30:40 +01:00
|
|
|
logger.info("Going to elaborate the following type tree\n{}", tree.toString());
|
2023-01-24 16:54:00 +01:00
|
|
|
|
2023-01-24 18:17:47 +01:00
|
|
|
NodeElaborator documentationNE = new NodeElaborator() {
|
2023-01-24 16:54:00 +01:00
|
|
|
|
2023-01-24 17:36:06 +01:00
|
|
|
protected void writeSectionOnly(Type type, int level) throws Exception {
|
|
|
|
DocumentationGenerator dg = getDocumentationGenerator(type);
|
|
|
|
dg.setLevel(level);
|
|
|
|
StringBuffer sb = dg.generateSection();
|
|
|
|
Files.write(file.toPath(), sb.toString().getBytes(), StandardOpenOption.APPEND);
|
|
|
|
}
|
|
|
|
|
2023-01-24 16:54:00 +01:00
|
|
|
@Override
|
|
|
|
public void elaborate(Node node, int level) throws Exception {
|
|
|
|
Type type = node.getType();
|
|
|
|
if(level==0) {
|
|
|
|
/*
|
|
|
|
* Root node has been already documented in IS_MODEL_FILENAME
|
|
|
|
* Going to skip it
|
|
|
|
*/
|
2023-01-24 17:36:06 +01:00
|
|
|
writeSectionOnly(type, level);
|
|
|
|
}else if(isModelPropertyNames.contains(type.getName())){
|
|
|
|
// Can be Header, Encrypted or PropagationConstraint
|
|
|
|
if(node.getChildrenNodes()!=null && node.getChildrenNodes().size()>0) {
|
|
|
|
// If they have specialization I just add the section
|
|
|
|
// to maintain the level, otherwise I skip it
|
|
|
|
writeSectionOnly(type, level);
|
|
|
|
}
|
|
|
|
} else {
|
2023-01-24 16:54:00 +01:00
|
|
|
writeTypeToFile(type, file, level);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
};
|
2023-01-23 16:21:01 +01:00
|
|
|
|
2023-01-24 18:17:47 +01:00
|
|
|
tree.elaborate(documentationNE);
|
2023-01-23 16:21:01 +01:00
|
|
|
}
|
|
|
|
|
2023-01-24 16:54:00 +01:00
|
|
|
|
2023-01-24 18:17:47 +01:00
|
|
|
public void createUsageKnowledge(Tree tree) throws Exception {
|
|
|
|
|
|
|
|
NodeElaborator usageKnowledgeNE = new NodeElaborator() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void elaborate(Node node, int level) throws Exception {
|
|
|
|
Type type = node.getType();
|
|
|
|
ResourceDocumentationGenerator dg = new ResourceDocumentationGenerator(type);
|
|
|
|
dg.createUsageKnowledge();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
tree.elaborate(usageKnowledgeNE);
|
|
|
|
}
|
|
|
|
|
2023-01-23 16:21:01 +01:00
|
|
|
public void generate() throws Exception {
|
|
|
|
|
2023-01-24 16:54:00 +01:00
|
|
|
File is = getFile(IS_MODEL_FILENAME, true);
|
|
|
|
File file = null;
|
|
|
|
|
2023-01-23 16:21:01 +01:00
|
|
|
for(AccessType at : accessTypes) {
|
2023-01-24 16:54:00 +01:00
|
|
|
Type type = TypeMapper.createTypeDefinition(at.getTypeClass());
|
|
|
|
writeTypeToFile(type, is);
|
|
|
|
|
|
|
|
switch (at) {
|
|
|
|
case PROPERTY:
|
|
|
|
file = getFile(PROPERTIES_FILENAME, true);
|
2023-01-24 17:36:06 +01:00
|
|
|
for(Class<? extends Property> clz : isModelProperties) {
|
2023-01-24 17:19:47 +01:00
|
|
|
Type t = TypeMapper.createTypeDefinition(clz);
|
|
|
|
writeTypeToFile(t, is, 1);
|
|
|
|
}
|
2023-01-24 16:54:00 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case ENTITY:
|
|
|
|
file = getFile(ENTITIES_FILENAME, true);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
case RELATION:
|
|
|
|
file = getFile(RELATIONS_FILENAME, true);
|
|
|
|
continue;
|
|
|
|
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-01-23 16:21:01 +01:00
|
|
|
Tree tree = types.get(at);
|
2023-01-24 16:54:00 +01:00
|
|
|
elaborateTree(at, tree, file);
|
2023-01-23 16:21:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|