package org.zstack.configuration;
import org.apache.commons.lang.StringEscapeUtils;
import org.zstack.configuration.testlink.schema.RequirementCategory;
import org.zstack.configuration.testlink.schema.RequirementSpecification;
import org.zstack.core.rest.RESTApiJsonTemplateGenerator;
import org.zstack.header.exception.CloudRuntimeException;
import org.zstack.utils.Utils;
import org.zstack.utils.logging.CLogger;
import org.zstack.utils.path.PathUtil;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import java.io.File;
import java.io.IOException;
import java.net.URL;
public class TestLinkDocumentGenerator {
private static CLogger logger = Utils.getLogger(TestLinkDocumentGenerator.class);
private static String CONFIG_FOLDER = "testLinkTemplates";
private static String newLine(String str) {
return String.format("\n%s", str);
}
private static String multiHtmlP(String str) {
if (str == null) {
return htmlP(str);
}
/*
String[] lines = str.split("\\n");
StringBuilder sb = new StringBuilder();
for (String l : lines) {
sb.append(htmlP(l));
}
return sb.toString();
*/
return StringEscapeUtils.escapeHtml(str);
}
private static String htmlSTRONG(String str) {
return String.format("<strong>%s</strong>", str);
}
private static String htmlP(String str) {
return String.format("<p>%s</p>", str);
}
private static String makeRequirementDescription(RequirementCategory.Req req) throws ClassNotFoundException {
StringBuilder sb = new StringBuilder();
sb.append(newLine(htmlP(htmlSTRONG("Prerequisite:"))));
sb.append(newLine(htmlP(req.getPrerequisite())));
sb.append(newLine(htmlP(htmlSTRONG("Goal:"))));
sb.append(newLine(htmlP(req.getGoal())));
sb.append(newLine(htmlP(htmlSTRONG("Details:"))));
sb.append(newLine(multiHtmlP(req.getDetails())));
sb.append(newLine(htmlP(htmlSTRONG("SubResource:"))));
if (req.getSubResource().isEmpty()) {
sb.append(newLine(htmlP(null)));
} else {
for (String sr : req.getSubResource()) {
sb.append(newLine(htmlP(sr)));
}
}
sb.append(newLine(htmlP(htmlSTRONG("RelationalResource:"))));
if (req.getRelationalResource().isEmpty()) {
sb.append(newLine(htmlP(null)));
} else {
for (String sr : req.getRelationalResource()) {
sb.append(newLine(htmlP(sr)));
}
}
sb.append(newLine(htmlP(htmlSTRONG("API:"))));
if (req.getApi().isEmpty()) {
sb.append(newLine(htmlP(null)));
} else {
for (RequirementCategory.Req.Api api : req.getApi()) {
Class<?> rc = Class.forName(api.getRequestClass());
String rs = RESTApiJsonTemplateGenerator.dump(rc);
sb.append(newLine(multiHtmlP(rs)));
sb.append(newLine(htmlP("")));
rc = Class.forName(api.getResponseClass());
rs = RESTApiJsonTemplateGenerator.dump(rc);
sb.append(newLine(multiHtmlP(rs)));
sb.append(newLine(htmlP("")));
sb.append(newLine(htmlP("")));
}
}
sb.append(newLine(htmlP(htmlSTRONG("Other:"))));
sb.append(newLine(htmlP(req.getOther())));
return sb.toString();
}
private static void requirmentSpecFromXml(String outputDir, String filePath) throws JAXBException, ClassNotFoundException, IOException {
JAXBContext context = JAXBContext.newInstance("org.zstack.configuration.testlink.schema");
Unmarshaller unmarshaller = context.createUnmarshaller();
File tfile = new File(filePath);
RequirementCategory sc = (RequirementCategory) unmarshaller.unmarshal(tfile);
String docId = sc.getDocumentId();
String specTitle = sc.getTitle();
if (specTitle == null) {
specTitle = docId;
}
RequirementSpecification ret = new RequirementSpecification();
RequirementSpecification.ReqSpec rspec = new RequirementSpecification.ReqSpec();
rspec.setDocId(docId);
rspec.setTitle(specTitle);
for (RequirementCategory.Req req : sc.getReq()) {
RequirementSpecification.ReqSpec.Requirement r = new RequirementSpecification.ReqSpec.Requirement();
r.setDocid(String.format("%s-REQ-%s", docId.toUpperCase(), sc.getReq().indexOf(req)));
r.setTitle(req.getTitle());
r.setDescription(makeRequirementDescription(req));
rspec.getRequirement().add(r);
}
ret.setReqSpec(rspec);
File retFile = new File(PathUtil.join(outputDir, String.format("reqSpec-%s", tfile.getName())));
retFile.createNewFile();
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(ret, retFile);
}
public static void generateRequirementSpec(String outputDir) {
URL folderUrl = TestLinkDocumentGenerator.class.getClassLoader().getResource(CONFIG_FOLDER);
if (folderUrl == null || !folderUrl.getProtocol().equals("file")) {
throw new CloudRuntimeException(
String.format(
"The folder %s is not found in classpath or there is another resource has the same name.",
CONFIG_FOLDER));
}
try {
String[] files = new File(folderUrl.toURI()).list();
for (String f : files) {
if (!f.endsWith(".xml")) {
logger.warn(String.format("skip file which is not ended with .xml", f));
continue;
}
URL fileUrl = TestLinkDocumentGenerator.class.getClassLoader().getResource(Utils.getPathUtil().join(CONFIG_FOLDER, f));
requirmentSpecFromXml(outputDir, fileUrl.getPath());
}
} catch (Exception e) {
throw new CloudRuntimeException(e);
}
}
}