]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.document.linking.ui/src/org/simantics/document/linking/report/templates/ModelDocumentWriter.java
b0f94261a9e283b0a38b05243b56119b87fa24c5
[simantics/platform.git] / bundles / org.simantics.document.linking.ui / src / org / simantics / document / linking / report / templates / ModelDocumentWriter.java
1 package org.simantics.document.linking.report.templates;
2
3 import java.util.ArrayList;
4 import java.util.Collections;
5 import java.util.Comparator;
6 import java.util.List;
7 import java.util.Map;
8
9 import org.simantics.db.ReadGraph;
10 import org.simantics.db.Resource;
11 import org.simantics.db.common.utils.NameUtils;
12 import org.simantics.db.exception.DatabaseException;
13 import org.simantics.document.DocumentResource;
14 import org.simantics.document.linking.report.Document;
15 import org.simantics.document.linking.report.DocumentTitlePage;
16 import org.simantics.document.linking.report.RowContentProvider;
17 import org.simantics.document.linking.report.Table;
18 import org.simantics.document.linking.report.TextItem;
19 import org.simantics.layer0.Layer0;
20 import org.simantics.structural.stubs.StructuralResource2;
21
22
23
24 /**
25  * Writes report with Model's internal documents.
26  * 
27  * Model information
28     □ Document folder 1
29         • Document 1-1
30         • Document 1-2 rev1
31         • Document 1-2 rev2
32         • Document 1-2 rev3
33         • Document 1-3
34     □ Document folder 2
35         • Document folder 3
36             o Document 3-1
37             o Document 3-2
38         • Document folder 4
39             o Document 4-1
40             o Document 4-2
41  * 
42  * @author Marko Luukkainen <marko.luukkainen@vtt.fi>
43  *
44  */
45 public class ModelDocumentWriter extends  DocumentWriter<List<Resource>> {
46         
47         ReadGraph graph;
48         Layer0 l0;
49         Resource model;
50         Map<Object, Object> context;
51         Comparator<Resource> comparator;
52
53         
54         @Override
55         public String getName() {
56                 return "Model Internal Documents";
57         }
58         
59         @Override
60         public void start(ReadGraph graph, Resource model, Document lineWriter, Map<Object, Object> context) throws Exception{
61                 super.start(graph, model, lineWriter, context);
62                 this.context = context;
63                 this.model = model;
64                 DocumentTitlePage titlePage = lineWriter.newElement(DocumentTitlePage.class);
65                 titlePage.writeTitle(graph, context);
66                 Table table = lineWriter.newElement(Table.class);
67                 table.addColumn("Folder", 0.4);
68                 table.addColumn("Document", 0.6);
69                 
70                 //lineWriter.nextPage();
71                 this.graph = graph;
72                 this.l0 = Layer0.getInstance(graph);
73                 clearProviders();
74                 addCellProvider(new HierarchyContentProvider());
75                 addCellProvider(new DocumentContentProvider());
76                 
77         }
78         
79         @Override
80         public List<List<Resource>> getReportItems(ReadGraph graph)     throws DatabaseException {
81                 
82                 comparator = new ResourceNameComparator(graph, model);
83                 List<List<Resource>> result = new ArrayList<List<Resource>>();
84                 List<Resource> root = Collections.singletonList(model);
85                 collect(graph, root, result);
86                 return result;
87         }
88         
89         private void collect(ReadGraph graph, List<Resource> location, List<List<Resource>> result) throws DatabaseException{
90                 // TODO : at the moment document structure in the model is customizable, so this method may not be able to collect the documents.
91                 // Current logic is:
92                 // 1. browse L0.ConsistsOf
93                 // 2a. If found resource is Document, add it into results
94                 // 2b. Otherwise, if resource is not structural component, go to step 1. 
95                 // 
96                 // Note: Filtering structural components prevents browsing the whole model structure for locating the documents.
97                 
98                 Layer0 l0 = Layer0.getInstance(graph);
99                 DocumentResource doc = DocumentResource.getInstance(graph);
100                 StructuralResource2 sr = StructuralResource2.getInstance(graph);
101                 Resource lastInPath = location.get(location.size() -1);
102                 List<Resource> set = new ArrayList<Resource>();
103                 set.addAll(graph.getObjects(lastInPath, l0.ConsistsOf));
104                 Collections.sort(set, comparator);
105                 for (Resource r : set) {
106                         List<Resource> path = new ArrayList<Resource>(location.size()+1);
107                         path.addAll(location);
108                         path.add(r);
109                         if (graph.isInstanceOf(r, doc.Document)) {
110                                 result.add(path);
111                                 collect(graph, path, result);
112                         } else if (!graph.isInstanceOf(r, sr.Component)){
113                                 collect(graph, path, result);
114                         }
115                 }
116         }
117         
118         
119         
120         
121         private String getText(List<Resource> current, boolean indent) throws DatabaseException {
122                 String text = "";
123                 if (indent)
124                         for (int i = 0; i < current.size()-1; i++) {
125                                 text += "  ";
126                         }
127                 
128                 text += NameUtils.getSafeLabel(graph, current.get(current.size()-1));
129                 return text;
130         }
131         
132         private class HierarchyContentProvider implements RowContentProvider<List<Resource>> {
133                 @Override
134                 public void setText(Document writer, List<Resource> previous,
135                                 List<Resource> current, List<Resource> next, TextItem[] text)
136                                 throws Exception {
137                         int writeFolder = 0;
138                         int fic = folderIndex(current);
139                         if (previous == null) {
140                                 writeFolder =  fic+1;
141                         } else {
142                                 int fip = folderIndex(previous);
143                                 
144                                 if (fip < fic) {
145                                         writeFolder = fic-fip;
146                                 } else if (fip == fic) {
147                                         for (int i = 0; i <= fic; i++) {
148                                                 if (!previous.get(i).equals(current.get(i))) {
149                                                         writeFolder = previous.size()-i;
150                                                         break;
151                                                 }
152                                         }
153                                 }
154                         }
155                         
156                         if (writeFolder > 0) {
157                                 text[0] = writer.newItem(TextItem.class);
158                                 if (writeFolder > 1) {
159                                         Table table = writer.getCurrentElement(Table.class);
160                                         for (int i = current.size()-writeFolder+1; i < current.size()-1; i++) {
161                                                 text[0].setText(getText(current.subList(0, i),true));
162                                                 text[1] = null;
163                                                 table.writeRowItem(text);
164                                         }
165                                 }
166                                 text[0].setText(getText(current.subList(0, fic+1),true));
167                         } else {
168                                 text[0] = null;
169                         }
170                         
171                 }
172         }
173         
174         private int folderIndex(List<Resource> path) throws DatabaseException{
175                 for (int i = path.size()-1; i >= 0; i--) {
176                         if (graph.isInstanceOf(path.get(i), doc.Document))
177                                 continue;
178                         return i;
179                 }
180                 return -1;
181         }
182         
183         private int revisionIndex(Resource document) throws DatabaseException{
184                 Resource r = document;
185                 int i = -1;
186                 while (r != null) {
187                         Resource r2 = graph.getPossibleObject(r, l0.PartOf);
188                         r = graph.getPossibleObject(r, doc.HasNewerVersion);
189                         i++;
190                         if (r2 != null && !r2.equals(r)) // prevent indent if document revisions are not in tree form.
191                                 break;
192                 }
193                 return i;
194         }
195         
196         private class DocumentContentProvider implements RowContentProvider<List<Resource>> {
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 {
198                         String s = "";
199                         
200                         Resource document = current.get(current.size()-1);
201                         int rev = revisionIndex(document);
202                         for (int i = 0; i < rev; i++)
203                                 s += "  ";
204                         row[1] = getDocumentItem(document);
205                         row[1].setText(s + row[1].getText());
206                 };
207         }
208
209 }