package org.simantics.document.linking.report.templates; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import org.simantics.db.ReadGraph; import org.simantics.db.Resource; import org.simantics.db.common.utils.NameUtils; import org.simantics.db.exception.DatabaseException; import org.simantics.document.DocumentResource; import org.simantics.document.linking.report.Document; import org.simantics.document.linking.report.DocumentTitlePage; import org.simantics.document.linking.report.RowContentProvider; import org.simantics.document.linking.report.Table; import org.simantics.document.linking.report.TextItem; import org.simantics.layer0.Layer0; import org.simantics.structural.stubs.StructuralResource2; /** * Writes report with Model's internal documents. * * Model information □ Document folder 1 • Document 1-1 • Document 1-2 rev1 • Document 1-2 rev2 • Document 1-2 rev3 • Document 1-3 □ Document folder 2 • Document folder 3 o Document 3-1 o Document 3-2 • Document folder 4 o Document 4-1 o Document 4-2 * * @author Marko Luukkainen * */ public class ModelDocumentWriter extends DocumentWriter> { ReadGraph graph; Layer0 l0; Resource model; Map context; Comparator comparator; @Override public String getName() { return "Model Internal Documents"; //$NON-NLS-1$ } @Override public void start(ReadGraph graph, Resource model, Document lineWriter, Map context) throws Exception{ super.start(graph, model, lineWriter, context); this.context = context; this.model = model; DocumentTitlePage titlePage = lineWriter.newElement(DocumentTitlePage.class); titlePage.writeTitle(graph, context); Table table = lineWriter.newElement(Table.class); table.addColumn("Folder", 0.4); //$NON-NLS-1$ table.addColumn("Document", 0.6); //$NON-NLS-1$ //lineWriter.nextPage(); this.graph = graph; this.l0 = Layer0.getInstance(graph); clearProviders(); addCellProvider(new HierarchyContentProvider()); addCellProvider(new DocumentContentProvider()); } @Override public List> getReportItems(ReadGraph graph) throws DatabaseException { comparator = new ResourceNameComparator(graph, model); List> result = new ArrayList>(); List root = Collections.singletonList(model); collect(graph, root, result); return result; } private void collect(ReadGraph graph, List location, List> result) throws DatabaseException{ // TODO : at the moment document structure in the model is customizable, so this method may not be able to collect the documents. // Current logic is: // 1. browse L0.ConsistsOf // 2a. If found resource is Document, add it into results // 2b. Otherwise, if resource is not structural component, go to step 1. // // Note: Filtering structural components prevents browsing the whole model structure for locating the documents. Layer0 l0 = Layer0.getInstance(graph); DocumentResource doc = DocumentResource.getInstance(graph); StructuralResource2 sr = StructuralResource2.getInstance(graph); Resource lastInPath = location.get(location.size() -1); List set = new ArrayList(); set.addAll(graph.getObjects(lastInPath, l0.ConsistsOf)); Collections.sort(set, comparator); for (Resource r : set) { List path = new ArrayList(location.size()+1); path.addAll(location); path.add(r); if (graph.isInstanceOf(r, doc.Document)) { result.add(path); collect(graph, path, result); } else if (!graph.isInstanceOf(r, sr.Component)){ collect(graph, path, result); } } } private String getText(List current, boolean indent) throws DatabaseException { String text = ""; //$NON-NLS-1$ if (indent) for (int i = 0; i < current.size()-1; i++) { text += " "; //$NON-NLS-1$ } text += NameUtils.getSafeLabel(graph, current.get(current.size()-1)); return text; } private class HierarchyContentProvider implements RowContentProvider> { @Override public void setText(Document writer, List previous, List current, List next, TextItem[] text) throws Exception { int writeFolder = 0; int fic = folderIndex(current); if (previous == null) { writeFolder = fic+1; } else { int fip = folderIndex(previous); if (fip < fic) { writeFolder = fic-fip; } else if (fip == fic) { for (int i = 0; i <= fic; i++) { if (!previous.get(i).equals(current.get(i))) { writeFolder = previous.size()-i; break; } } } } if (writeFolder > 0) { text[0] = writer.newItem(TextItem.class); if (writeFolder > 1) { Table table = writer.getCurrentElement(Table.class); for (int i = current.size()-writeFolder+1; i < current.size()-1; i++) { text[0].setText(getText(current.subList(0, i),true)); text[1] = null; table.writeRowItem(text); } } text[0].setText(getText(current.subList(0, fic+1),true)); } else { text[0] = null; } } } private int folderIndex(List path) throws DatabaseException{ for (int i = path.size()-1; i >= 0; i--) { if (graph.isInstanceOf(path.get(i), doc.Document)) continue; return i; } return -1; } private int revisionIndex(Resource document) throws DatabaseException{ Resource r = document; int i = -1; while (r != null) { Resource r2 = graph.getPossibleObject(r, l0.PartOf); r = graph.getPossibleObject(r, doc.HasNewerVersion); i++; if (r2 != null && !r2.equals(r)) // prevent indent if document revisions are not in tree form. break; } return i; } private class DocumentContentProvider implements RowContentProvider> { public void setText(Document writer, java.util.List previous, java.util.List current, java.util.List next, TextItem[] row) throws Exception { String s = ""; //$NON-NLS-1$ Resource document = current.get(current.size()-1); int rev = revisionIndex(document); for (int i = 0; i < rev; i++) s += " "; //$NON-NLS-1$ row[1] = getDocumentItem(document); row[1].setText(s + row[1].getText()); }; } }