org.semantictools.uml.api.UmlPrinter Maven / Gradle / Ivy
/*******************************************************************************
* Copyright 2012 Pearson Education
*
* Licensed 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.
******************************************************************************/
package org.semantictools.uml.api;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import javax.imageio.ImageIO;
import org.semantictools.context.renderer.URLRewriter;
import org.semantictools.context.renderer.model.BaseDocumentMetadata;
import org.semantictools.context.renderer.model.ContextProperties;
import org.semantictools.context.renderer.model.GlobalProperties;
import org.semantictools.context.renderer.model.ReferenceManager;
import org.semantictools.context.renderer.model.ServiceDocumentation;
import org.semantictools.context.view.Caption;
import org.semantictools.context.view.CaptionType;
import org.semantictools.context.view.DefaultDocumentPrinter;
import org.semantictools.context.view.DocumentPrinter;
import org.semantictools.context.view.DocumentPrinterFactory;
import org.semantictools.context.view.Heading;
import org.semantictools.context.view.HtmlPrinter;
import org.semantictools.frame.api.LinkManager;
import org.semantictools.frame.api.TypeManager;
import org.semantictools.frame.model.Datatype;
import org.semantictools.frame.model.Field;
import org.semantictools.frame.model.Frame;
import org.semantictools.frame.model.NamedIndividual;
import org.semantictools.frame.model.OntologyInfo;
import org.semantictools.frame.model.RdfType;
import org.semantictools.index.api.LinkedDataIndex;
import org.semantictools.uml.graphics.ClassDiagram;
import org.semantictools.uml.model.UmlAssociation;
import org.semantictools.uml.model.UmlAssociationEnd;
import org.semantictools.uml.model.UmlClass;
import org.semantictools.uml.model.UmlManager;
import org.semantictools.web.upload.AppspotUploadClient;
import com.hp.hpl.jena.rdf.model.Property;
public class UmlPrinter extends HtmlPrinter {
private static final String UML_CSS = "uml.css";
private UmlManager umlManager;
private String ontologyTitle;
private String ontologyURI;
private UmlFileManager linkManager;
private LinkedDataIndex mediaTypeOracle;
private AppspotUploadClient uploadClient;
private LinkManager uploadLinkManager;
private GlobalProperties global;
private BaseDocumentMetadata metadata;
private DocumentPrinter printer;
public UmlPrinter(
GlobalProperties global,
URLRewriter rewriter,
UmlManager umlManager,
UmlFileManager linkManager,
LinkedDataIndex oracle) {
super(rewriter);
this.global = global==null ? new GlobalProperties() : global;
this.umlManager = umlManager;
this.linkManager = linkManager;
this.mediaTypeOracle = oracle;
}
public AppspotUploadClient getUploadClient() {
return uploadClient;
}
public void setUploadClient(AppspotUploadClient uploadClient) {
this.uploadClient = uploadClient;
File baseDir = linkManager.getRootDir().getParentFile();
String baseURI = baseDir.getPath().replace('\\', '/')+'/';
uploadLinkManager = new LinkManager();
uploadLinkManager.setBaseURI(baseURI);
}
public void printAll() throws IOException {
Iterator sequence = umlManager.getTypeManager().listOntologies().iterator();
while (sequence.hasNext()) {
String ontURI = sequence.next().getNamespaceUri();
if (global.isIgnoredOntology(ontURI)) continue;
if (umlManager.getTypeManager().isStandard(ontURI)) continue;
OntologyInfo info = umlManager.getTypeManager().getOntologyByNamespaceUri(ontURI);
if (info == null) continue;
init(info);
switch (info.getType()) {
case RDF:
if (info.hasClasses()) {
printOntology(ontURI);
}
break;
case XSD: printXmlSchema(info); break;
}
}
copyStyleSheet();
}
private void init(OntologyInfo info) {
this.init();
this.ontologyURI = info.getNamespaceUri();
linkManager.setOntology(ontologyURI);
}
private void printXmlSchema(OntologyInfo info) throws IOException {
String templateName = global.getTemplateName();
metadata = new BaseDocumentMetadata(global);
printer = DocumentPrinterFactory.getDefaultFactory().createPrinter(templateName);
printer.setMetadata(metadata);
setPrintContext(printer.getPrintContext());
setCss();
setXmlSchemaTitle(info);
printer.beginHTML();
printer.printTitlePage();
printer.printTableOfContentsMarker();
println("
");
printDatatypes(info);
printer.printFooter();
printer.endHTML();
printer.insertTableOfContents();
writeFile();
}
private void printDatatypes(OntologyInfo info) {
List types = listDataTypes(info.getNamespaceUri());
for (Datatype type : types) {
printDatatype(type);
}
}
private void setXmlSchemaTitle(OntologyInfo info) {
ontologyTitle = info.getLabel();
if (ontologyTitle==null) {
ontologyTitle = info.getPrefix().toUpperCase() + " XML Schema";
}
metadata.setTitle(ontologyTitle);
}
private List listDataTypes(String uri) {
List list = new ArrayList();
TypeManager typeManager = umlManager.getTypeManager();
Collection source = typeManager.listDatatypes();
for (Datatype d : source) {
String typeURI = d.getUri();
if (typeURI.startsWith(uri)) {
list.add(d);
}
}
Collections.sort(list, new DatatypeComparator());
return list;
}
private void printDatatype(Datatype type) {
Heading heading = printer.createHeading(type.getLocalName());
heading.setClassName("rdfType");
print(heading);
String baseURI = type.getBase().getUri();
printer.beginTable("propertiesTable");
printer.beginRow();
printer.printTH("Restriction Base");
printer.printTD(baseURI);
printer.endRow();
printStringFacet("pattern", type.getPattern());
printNumberFacet("length", type.getLength());
printNumberFacet("minLength", type.getMinLength());
printNumberFacet("maxLength", type.getMaxLength());
printNumberFacet("minInclusive", type.getMinInclusive());
printNumberFacet("maxInclusive", type.getMaxInclusive());
printNumberFacet("minExclusive", type.getMinExclusive());
printNumberFacet("maxExclusive", type.getMaxExclusive());
printNumberFacet("totalDigits", type.getTotalDigits());
printNumberFacet("fractionDigits", type.getFractionDigits());
printer.endTable();
//
// String captionText = "Facets of " + termName;
// Caption caption = new Caption(CaptionType.Table, captionText, termName, type.getUri());
// assignNumber(caption);
// printCaption(caption);
}
private void printNumberFacet(String name, Number value) {
if (value == null) return;
printer.beginRow();
printer.printTH(name);
printer.printTD(value.toString());
printer.endRow();
}
private void printStringFacet(String name, String value) {
if (value == null) return;
printer.beginRow();
printer.printTH(name);
printer.printTD(value);
printer.endRow();
}
static class DatatypeComparator implements Comparator {
@Override
public int compare(Datatype a, Datatype b) {
return a.getLocalName().compareTo(b.getLocalName());
}
}
private void copyStyleSheet() throws IOException {
InputStream stream = getClass().getClassLoader().getResourceAsStream(UML_CSS);
if (stream != null) {
File cssFile = new File(linkManager.getRootDir(), UML_CSS);
copyFile(stream, cssFile);
if (uploadClient != null) {
uploadClient.upload("text/css", "uml/" + UML_CSS, cssFile);
}
}
}
private void copyFile(InputStream stream, File cssFile) throws IOException {
File parent = cssFile.getParentFile();
parent.mkdirs();
FileOutputStream out = new FileOutputStream(cssFile);
try {
byte[] buffer = new byte[1024];
int len;
while ( (len = stream.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
} finally {
out.close();
}
}
public void printOntology(String ontologyURI) throws IOException {
// TODO: use a proper reference map.
String templateName = global.getTemplateName();
metadata = new BaseDocumentMetadata(global);
printer = DocumentPrinterFactory.getDefaultFactory().createPrinter(templateName);
printer.setMetadata(metadata);
setPrintContext(printer.getPrintContext());
setCss();
setTitle();
printer.beginHTML();
printer.printTitlePage();
printer.printTableOfContentsMarker();
printDataModel();
printer.printFooter();
printer.endHTML();
printer.insertTableOfContents();
writeFile();
}
private void setCss() {
// TODO: should delegate to UmlFileManager
String ontoPath = linkManager.getOntologyDir().getAbsolutePath();
String basePath = linkManager.getRootDir().getAbsolutePath();
String relativePath = ontoPath.substring(basePath.length());
relativePath = relativePath.replace('\\', '/');
int count = dirCount(relativePath);
StringBuilder builder = new StringBuilder();
for (int i=0; i");
print(ontologyTitle);
println("");
}
private void printDataModel() throws IOException {
List list = getClassList();
for (UmlClass umlClass : list) {
String uri = umlClass.getURI();
if (!uri.startsWith(ontologyURI)) continue;
printUmlClass(umlClass);
}
}
private List getClassList() {
List list = new ArrayList();
for (UmlClass umlClass : umlManager.listUmlClasses()) {
String uri = umlClass.getURI();
if (!uri.startsWith(ontologyURI)) continue;
list.add(umlClass);
}
Collections.sort(list, new UmlClassComparator());
return list;
}
static class UmlClassComparator implements Comparator {
@Override
public int compare(UmlClass a, UmlClass b) {
String aName = a.getLocalName();
String bName = b.getLocalName();
return aName.compareTo(bName);
}
}
private boolean exists(String value) {
return value != null && value.length()>0;
}
private void printUmlClass(UmlClass umlClass) throws IOException {
String localName = umlClass.getLocalName();
println("
");
Heading heading = printer.createHeading(localName, linkManager.getTypeId(umlClass.getType()));
print(heading);
pushIndent();
printClassDiagram(umlClass);
printSupertypes(umlClass);
printSubtypes(umlClass);
printClassUses(umlClass);
printMediaTypes(umlClass);
printDescription(umlClass);
printPropertyTable(umlClass);
printInheritedProperties(umlClass);
printNamedInstances(umlClass);
popIndent();
}
private void printClassUses(UmlClass umlClass) {
List list = umlClass.getParentList();
if (list == null || list.isEmpty()) return;
printer.beginDiv("list-heading");
print("Known Uses:");
printer.endDiv();
indent();
println("");
pushIndent();
for (UmlAssociation a : list) {
UmlAssociationEnd end = a.getOtherEnd(umlClass);
String classHref = linkManager.getTypeHref(end.getParticipant().getType());
String className = end.getParticipant().getLocalName();
Field field = a.getSelfEnd(umlClass).getField();
indent();
print("- ");
printer.printAnchor(classHref, className);
if (field != null) {
Property property = field.getProperty();
String fieldName = field.getLocalName();
String fieldHref = linkManager.getPropertyHref(end.getParticipant(), property);
print(".");
printer.printAnchor(fieldHref, fieldName);
}
}
popIndent();
indent();
println("
");
}
private void printMediaTypes(UmlClass umlClass) {
if (mediaTypeOracle == null) return;
List mediaTypeList = mediaTypeOracle.listMediaTypesForClass(umlClass.getURI());
List list = mediaTypeOracle.getServiceDocumentationForClass(umlClass.getURI());
if (list == null) {
list = new ArrayList();
}
int count = mediaTypeList.size() + list.size();
if (count==0) return;
printer.beginDiv("list-heading");
print("See Also:");
printer.endDiv();
println("");
pushIndent();
for (int i=0; i", " ").replace("
", " ");
String serviceHref = linkManager.relativize(doc.getServiceDocumentationFile());
indent();
print("- ");
printer.printAnchor(serviceHref, title);
}
for (ContextProperties context : mediaTypeList) {
String mediaType = context.getMediaType();
String href = linkManager.relativize(context.getMediaTypeDocFile());
indent();
print("
- ");
printer.printAnchor(href, mediaType);
}
popIndent();
println("
");
}
private void printDescription(UmlClass umlClass) {
String description = umlClass.getDescription();
if (exists(description)) {
printer.printParagraph(description);
}
}
private void printSupertypes(UmlClass umlClass) {
List superList = umlClass.getSupertypeList();
if (superList == null || superList.isEmpty()) return;
printer.beginDiv("list-heading");
print("Direct Known Supertypes:");
printer.endDiv();
printer.beginDiv("running-list");
String comma = "";
for (UmlClass supertype : superList) {
print(comma);
print(linkManager.getTypeLink(supertype.getType()));
comma = ", ";
}
printer.endDiv();
}
private void printSubtypes(UmlClass umlClass) {
List subList = umlClass.getSubtypeList();
if (subList == null || subList.isEmpty()) return;
printer.beginDiv("list-heading");
print("Direct Known Subtypes:");
printer.endDiv();
printer.beginDiv("running-list");
String comma = "";
for (UmlClass subtype : subList) {
print(comma);
print(linkManager.getTypeLink(subtype.getType()));
comma = ", ";
}
printer.endDiv();
}
private void printInheritedProperties(UmlClass umlClass) {
List list = umlClass.listAllSupertypes();
if (list.isEmpty()) return;
list = new ArrayList(list);
Collections.sort(list, new UmlClassComparator());
for (UmlClass superclass : list) {
printInheritedProperties(umlClass, superclass);
}
}
private void printInheritedProperties(UmlClass umlClass, UmlClass superclass) {
RdfType superType = superclass.getType();
if (!superType.canAsFrame()) return;
List list = superType.asFrame().getDeclaredFields();
if (list==null || list.isEmpty()) return;
String title = "Properties inherited from " + superclass.getLocalName();
printer.beginTable("propertiesTable");
printer.beginRow();
printer.printTH(title);
printer.endRow();
printer.beginRow();
indent();
print("");
String comma = "";
for (Field field : list) {
print(comma);
String id = null;
id = linkManager.getPropertyHref(superclass, field.getProperty());
if (id != null) {
print("");
}
String name = field.getLocalName();
print(name);
if (id != null) {
print("");
}
comma = ", ";
}
println();
indent();
println(" ");
printer.endRow();
printer.endTable();
}
private void printClassDiagram(UmlClass umlClass) throws IOException {
File file = linkManager.getUmlClassImageFile(umlClass);
ClassDiagram diagram = new ClassDiagram(umlClass);
BufferedImage image = diagram.getImage();
ImageIO.write(image, "png", file);
uploadFile("image/png", file);
String src = "images/" + file.getName();
// String captionText = umlClass.getLocalName() + " Class";
// String id = file.getName();
// Caption caption = new Caption(CaptionType.Figure, captionText, id, null);
//
// assignNumber(caption);
printer.printFigure(src, null);
}
private void printNamedInstances(UmlClass umlClass) {
List list = umlClass.listInstances(false);
if (list.isEmpty()) return;
Collections.sort(list, new Comparator() {
@Override
public int compare(NamedIndividual a, NamedIndividual b) {
return
(a.getLocalName() != null && b.getLocalName()!=null) ? a.getLocalName().compareTo(b.getLocalName()) :
0;
}
});
printer.beginDiv("list-heading");
print("Known Instances:");
printer.endDiv();
printer.beginTable("propertiesTable");
printer.beginRow();
println("Simple Name Description / URI ");
printer.endRow();
for (NamedIndividual n : list) {
String comment = n.getComment();
printer.beginRow();
print("");
print(n.getLocalName());
print(" ");
print("");
if (comment != null) {
print("");
print(comment);
print("
");
}
print("");
print(n.getUri());
print("
");
print(" ");
printer.endRow();
}
printer.endTable();
}
private void printPropertyTable(UmlClass umlClass) {
RdfType type = umlClass.getType();
if (!type.canAsFrame()) return;
Frame frame = type.asFrame();
List list = frame.getDeclaredFields();
if (list.isEmpty()) return;
Collections.sort(list);
String tableId = umlClass.getLocalName() + ".properties";
String captionText = format("{0} Properties", umlClass.getLocalName());
Caption caption = new Caption(CaptionType.Table, captionText, tableId, null);
printer.assignNumber(caption);
String title = format("Properties of class {0}", umlClass.getLocalName());
printer.beginTable("propertiesTable");
printer.beginRow();
println("" + title + " ");
printer.endRow();
TypeManager typeManager = umlManager.getTypeManager();
// TODO: print anchor tag for Type.
for (Field field : list) {
RdfType fieldType = field.getRdfType();
// if (fieldType.canAsListType()) {
// fieldType = fieldType.asListType().getElementType();
// }
String link = typeManager.isStandard(fieldType.getNamespace()) ? fieldType.getLocalName() :
linkManager.getTypeLink(fieldType);
String propertyId = linkManager.getPropertyId(umlClass, field.getProperty());
printer.beginRow();
indent();
print("");
printer.beginDiv("propertyName", propertyId);
indent();
print(field.getLocalName());
printer.endDiv();
printer.beginDiv("description");
indent();
print(field.getComment());
printer.endDiv();
printValueRestriction(field);
print(" ");
printer.printTD("propertyType", link);
printer.printTD("multiplicity", field.getMultiplicity());
printer.endRow();
}
// beginRow();
// printTH("Name");
// printTH("Mult");
// printTH("Description");
// printTH("Type");
// endRow();
//
// TypeManager typeManager = umlManager.getTypeManager();
//
// // TODO: print anchor tag for Type.
// for (UmlProperty p : list) {
//
// RdfType fieldType = p.getField().getRdfType();
//
// String link = typeManager.isStandard(fieldType.getNamespace()) ? fieldType.getLocalName() :
// linkManager.getTypeLink(fieldType);
//
// beginRow();
// printTD(p.getLocalName());
// printTD(p.getMultiplicity());
// printTD(p.getDescription());
// printTD(link);
// endRow();
// }
printer.endTable();
}
private void printValueRestriction(Field field) {
NamedIndividual value = field.getValueRestriction();
if (value != null) {
String message =
"This property is restricted and must have the value " +
" " + value.getUri() + "
";
;
printer.beginParagraph();
print(message);
printer.endParagraph();
}
}
private int dirCount(String relativePath) {
int count = 0;
int index = -1;
while ( (index = relativePath.indexOf('/', index+1)) >= 0) {
count++;
}
return count;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy