1 package org.simantics.document.linking.report.templates;
\r
3 import java.util.ArrayList;
\r
4 import java.util.Collections;
\r
5 import java.util.Comparator;
\r
6 import java.util.List;
\r
7 import java.util.Map;
\r
9 import org.simantics.db.ReadGraph;
\r
10 import org.simantics.db.Resource;
\r
11 import org.simantics.db.common.utils.NameUtils;
\r
12 import org.simantics.db.exception.DatabaseException;
\r
13 import org.simantics.document.DocumentResource;
\r
14 import org.simantics.document.linking.report.Document;
\r
15 import org.simantics.document.linking.report.DocumentTitlePage;
\r
16 import org.simantics.document.linking.report.RowContentProvider;
\r
17 import org.simantics.document.linking.report.Table;
\r
18 import org.simantics.document.linking.report.TextItem;
\r
19 import org.simantics.layer0.Layer0;
\r
20 import org.simantics.structural.stubs.StructuralResource2;
\r
25 * Writes report with Model's internal documents.
\r
42 * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
\r
45 public class ModelDocumentWriter extends DocumentWriter<List<Resource>> {
\r
50 Map<Object, Object> context;
\r
51 Comparator<Resource> comparator;
\r
55 public String getName() {
\r
56 return "Model Internal Documents";
\r
60 public void start(ReadGraph graph, Resource model, Document lineWriter, Map<Object, Object> context) throws Exception{
\r
61 super.start(graph, model, lineWriter, context);
\r
62 this.context = context;
\r
64 DocumentTitlePage titlePage = lineWriter.newElement(DocumentTitlePage.class);
\r
65 titlePage.writeTitle(graph, context);
\r
66 Table table = lineWriter.newElement(Table.class);
\r
67 table.addColumn("Folder", 0.4);
\r
68 table.addColumn("Document", 0.6);
\r
70 //lineWriter.nextPage();
\r
72 this.l0 = Layer0.getInstance(graph);
\r
74 addCellProvider(new HierarchyContentProvider());
\r
75 addCellProvider(new DocumentContentProvider());
\r
80 public List<List<Resource>> getReportItems(ReadGraph graph) throws DatabaseException {
\r
82 comparator = new ResourceNameComparator(graph, model);
\r
83 List<List<Resource>> result = new ArrayList<List<Resource>>();
\r
84 List<Resource> root = Collections.singletonList(model);
\r
85 collect(graph, root, result);
\r
89 private void collect(ReadGraph graph, List<Resource> location, List<List<Resource>> result) throws DatabaseException{
\r
90 // TODO : at the moment document structure in the model is customizable, so this method may not be able to collect the documents.
\r
91 // Current logic is:
\r
92 // 1. browse L0.ConsistsOf
\r
93 // 2a. If found resource is Document, add it into results
\r
94 // 2b. Otherwise, if resource is not structural component, go to step 1.
\r
96 // Note: Filtering structural components prevents browsing the whole model structure for locating the documents.
\r
98 Layer0 l0 = Layer0.getInstance(graph);
\r
99 DocumentResource doc = DocumentResource.getInstance(graph);
\r
100 StructuralResource2 sr = StructuralResource2.getInstance(graph);
\r
101 Resource lastInPath = location.get(location.size() -1);
\r
102 List<Resource> set = new ArrayList<Resource>();
\r
103 set.addAll(graph.getObjects(lastInPath, l0.ConsistsOf));
\r
104 Collections.sort(set, comparator);
\r
105 for (Resource r : set) {
\r
106 List<Resource> path = new ArrayList<Resource>(location.size()+1);
\r
107 path.addAll(location);
\r
109 if (graph.isInstanceOf(r, doc.Document)) {
\r
111 collect(graph, path, result);
\r
112 } else if (!graph.isInstanceOf(r, sr.Component)){
\r
113 collect(graph, path, result);
\r
121 private String getText(List<Resource> current, boolean indent) throws DatabaseException {
\r
124 for (int i = 0; i < current.size()-1; i++) {
\r
128 text += NameUtils.getSafeLabel(graph, current.get(current.size()-1));
\r
132 private class HierarchyContentProvider implements RowContentProvider<List<Resource>> {
\r
134 public void setText(Document writer, List<Resource> previous,
\r
135 List<Resource> current, List<Resource> next, TextItem[] text)
\r
137 int writeFolder = 0;
\r
138 int fic = folderIndex(current);
\r
139 if (previous == null) {
\r
140 writeFolder = fic+1;
\r
142 int fip = folderIndex(previous);
\r
145 writeFolder = fic-fip;
\r
146 } else if (fip == fic) {
\r
147 for (int i = 0; i <= fic; i++) {
\r
148 if (!previous.get(i).equals(current.get(i))) {
\r
149 writeFolder = previous.size()-i;
\r
156 if (writeFolder > 0) {
\r
157 text[0] = writer.newItem(TextItem.class);
\r
158 if (writeFolder > 1) {
\r
159 Table table = writer.getCurrentElement(Table.class);
\r
160 for (int i = current.size()-writeFolder+1; i < current.size()-1; i++) {
\r
161 text[0].setText(getText(current.subList(0, i),true));
\r
163 table.writeRowItem(text);
\r
166 text[0].setText(getText(current.subList(0, fic+1),true));
\r
174 private int folderIndex(List<Resource> path) throws DatabaseException{
\r
175 for (int i = path.size()-1; i >= 0; i--) {
\r
176 if (graph.isInstanceOf(path.get(i), doc.Document))
\r
183 private int revisionIndex(Resource document) throws DatabaseException{
\r
184 Resource r = document;
\r
186 while (r != null) {
\r
187 Resource r2 = graph.getPossibleObject(r, l0.PartOf);
\r
188 r = graph.getPossibleObject(r, doc.HasNewerVersion);
\r
190 if (r2 != null && !r2.equals(r)) // prevent indent if document revisions are not in tree form.
\r
196 private class DocumentContentProvider implements RowContentProvider<List<Resource>> {
\r
197 public void setText(Document writer, java.util.List<Resource> previous, java.util.List<Resource> current, java.util.List<Resource> next, TextItem[] row) throws Exception {
\r
200 Resource document = current.get(current.size()-1);
\r
201 int rev = revisionIndex(document);
\r
202 for (int i = 0; i < rev; i++)
\r
204 row[1] = getDocumentItem(document);
\r
205 row[1].setText(s + row[1].getText());
\r