Initial Document loading implementation, instead of libglom.
[online-glom:gwt-glom.git] / src / main / java / org / glom / web / shared / libglom / Document.java
1 /*
2  * Copyright (C) 2012 Openismus GmbH
3  *
4  * This file is part of GWT-Glom.
5  *
6  * GWT-Glom is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as published by the
8  * Free Software Foundation, either version 3 of the License, or (at your
9  * option) any later version.
10  *
11  * GWT-Glom is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
14  * for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with GWT-Glom.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package org.glom.web.shared.libglom;
21
22 import java.io.IOException;
23 import java.util.Hashtable;
24
25 import javax.xml.parsers.DocumentBuilder;
26 import javax.xml.parsers.DocumentBuilderFactory;
27 import javax.xml.parsers.ParserConfigurationException;
28
29 import org.apache.commons.lang3.StringUtils;
30 import org.glom.libglom.Field;
31 import org.glom.libglom.FieldVector;
32 import org.glom.libglom.LayoutGroupVector;
33 import org.glom.libglom.StringVector;
34 import org.jfree.util.Log;
35 import org.w3c.dom.Element;
36 import org.w3c.dom.Node;
37 import org.w3c.dom.NodeList;
38 import org.xml.sax.SAXException;
39
40
41 /**
42  * @author Murray Cumming <murrayc@openismus.com>
43  *
44  */
45 public class Document {
46
47         
48         private class TableInfo extends Translatable {
49                 public String name = "";
50                 public boolean isDefault;
51                 public boolean isHidden;
52                 
53                 private final Hashtable<String, Report> reportsMap = new Hashtable<String, Report>();
54         };
55
56         private String fileURI = "";
57         private org.w3c.dom.Document xmlDocument = null;
58         
59         private Translatable databaseTitle = new Translatable();
60         private String connectionServer = "";
61         private String connectionDatabase = "";
62         private int connectionPort = 0;
63         private final Hashtable<String, TableInfo> tablesMap = new Hashtable<String, TableInfo>();
64         
65         private static String NODE_CONNECTION = "connection";
66         private static String ATTRIBUTE_CONNECTION_SERVER = "server";
67         private static String ATTRIBUTE_CONNECTION_DATABASE = "database";
68         private static String ATTRIBUTE_CONNECTION_PORT = "port";
69         private static String NODE_TABLE = "table";
70         private static String ATTRIBUTE_NAME = "name";
71         private static String ATTRIBUTE_TITLE = "title";
72         private static String ATTRIBUTE_DEFAULT = "default";
73         private static String ATTRIBUTE_HIDDEN = "hidden";
74         private static String NODE_TRANSLATIONS_SET = "trans_set";
75         private static String NODE_TRANSLATIONS = "trans";
76         private static String ATTRIBUTE_TRANSLATION_LOCALE = "loc";
77         private static String ATTRIBUTE_TRANSLATION_TITLE = "val";
78         private static String NODE_REPORTS = "reports";
79         private static String NODE_REPORT = "report";
80         private static String NODE_FIELDS = "fields";
81         private static String NODE_FIELD = "field";
82         
83         public void set_file_uri(final String fileURI) {
84                 this.fileURI = fileURI;
85         }
86         
87         public String get_file_uri() {
88                 return fileURI;
89         }
90
91         //TODO: Make sure these have the correct values.
92         public enum LoadFailureCodes {
93                 LOAD_FAILURE_CODE_NONE,
94             LOAD_FAILURE_CODE_NOT_FOUND,
95                 LOAD_FAILURE_CODE_FILE_VERSION_TOO_NEW
96         };
97
98             
99         public boolean load(int failure_code) {
100                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
101                 DocumentBuilder documentBuilder;
102                 try {
103                         documentBuilder = dbf.newDocumentBuilder();
104                 } catch (ParserConfigurationException e) {
105                         // TODO Auto-generated catch block
106                         e.printStackTrace();
107                         return false;
108                 }
109                 
110                 try {
111                         xmlDocument = documentBuilder.parse(fileURI);
112                 } catch (SAXException e) {
113                         // TODO Auto-generated catch block
114                         e.printStackTrace();
115                         return false;
116                 } catch (IOException e) {
117                         // TODO Auto-generated catch block
118                         e.printStackTrace();
119                         return false;
120                 }
121                 
122                 final Element rootNode = xmlDocument.getDocumentElement();
123                 if(rootNode.getNodeName() != "glom_document") {
124                         Log.error("Unexpected XML root node name found: " + rootNode.getNodeName());
125                         return false;
126                 }
127                 
128                 databaseTitle.original = rootNode.getAttribute(ATTRIBUTE_TITLE);
129                 
130                 final NodeList listTableNodes = rootNode.getElementsByTagName(NODE_TABLE);
131                 final int num = listTableNodes.getLength();
132                 for(int i = 0; i < num; i++) {
133                         final Node node = listTableNodes.item(i);
134                         final Element element = (Element)node; //TODO: Check the cast.
135                         loadTableNode(element);
136                 }
137                 
138                 Element nodeConnection = getElementByName(rootNode, NODE_CONNECTION);
139                 if(nodeConnection != null) {
140                         connectionServer = nodeConnection.getAttribute(ATTRIBUTE_CONNECTION_SERVER);
141                         connectionDatabase = nodeConnection.getAttribute(ATTRIBUTE_CONNECTION_DATABASE);
142                         
143                         final String strPort = nodeConnection.getAttribute(ATTRIBUTE_CONNECTION_PORT);
144                         int port = 0;
145                         if(!StringUtils.isEmpty(strPort)) {
146                                 port = Integer.valueOf(strPort);
147                         }
148                         connectionPort = port;
149                 }
150                 
151
152                 return true;
153         };
154         
155         private Element getElementByName(final Element parentElement, final String tagName) {
156                 final NodeList listNodes = parentElement.getElementsByTagName(NODE_TABLE);
157                 if(listNodes == null)
158                         return null;
159
160                 if(listNodes.getLength() == 0)
161                         return null;
162
163                 return (Element)listNodes.item(0);
164         }
165         
166         private boolean getAttributeAsBoolean(final Element node, final String attributeName) {
167                 final String str = node.getAttribute(attributeName);
168                 if(str == null)
169                         return false;
170                 
171                 return (str.equals("true"));
172         }
173         
174         /** Load a title and its translations.
175          * 
176          * @param node The XML Element that may contain a title attribute and a trans_set of translations of the title.
177          * @param title
178          */
179         private void loadTitle(final Element node, final Translatable title) {
180                 title.original = node.getAttribute(ATTRIBUTE_TITLE);
181                 
182                 final Element nodeSet = getElementByName(node, NODE_TRANSLATIONS_SET);
183                 if(nodeSet == null) {
184                         return;
185                 }
186                 
187                 final NodeList listNodes = nodeSet.getElementsByTagName(NODE_TRANSLATIONS);
188                 if(listNodes == null)
189                         return;
190
191                 final int num = listNodes.getLength();
192                 for(int i = 0; i < num; i++) {
193                         final Node transNode = listNodes.item(i);
194                         final Element element = (Element)transNode; //TODO: Check the cast.
195                         
196                         final String locale = element.getAttribute(ATTRIBUTE_TRANSLATION_LOCALE);
197                         final String translatedTitle = element.getAttribute(ATTRIBUTE_TRANSLATION_TITLE);
198                         if(!StringUtils.isEmpty(locale) && !StringUtils.isEmpty(translatedTitle)) {
199                                 title.translationsMap.put(locale, translatedTitle);
200                         }
201                 }
202         }
203         /**
204          * @param node
205          */
206         private void loadTableNode(final Element node) {
207                 TableInfo info = new TableInfo();
208                 info.name = node.getAttribute(ATTRIBUTE_NAME);
209                 loadTitle(node, info);
210                 info.isDefault = getAttributeAsBoolean(node, ATTRIBUTE_DEFAULT);
211                 info.isHidden = getAttributeAsBoolean(node, ATTRIBUTE_HIDDEN);
212                 
213                 final Element reportsNode = getElementByName(node, NODE_REPORTS);
214                 if(reportsNode != null) {
215                         final NodeList listReportNodes = reportsNode.getElementsByTagName(NODE_REPORT);
216                         final int numReports = listReportNodes.getLength();
217                         for(int i = 0; i < numReports; i++) {
218                                 final Node reportNode = listReportNodes.item(i);
219                                 final Element element = (Element)reportNode; //TODO: Check the cast.
220                                 Report report = new Report();
221                                 loadReport(element, report);
222
223                                 info.reportsMap.put(report.name, report);
224                         }
225                 }
226                 
227                 final Element fieldsNode = getElementByName(node, NODE_FIELDS);
228                 if(fieldsNode != null) {
229                         final NodeList listFieldNodes = reportsNode.getElementsByTagName(NODE_FIELD);
230                         final int numFields = listFieldNodes.getLength();
231                         for(int i = 0; i < numFields; i++) {
232                                 final Node fieldNode = listFieldNodes.item(i);
233                                 final Element element = (Element)fieldNode; //TODO: Check the cast.
234                                 //TODO: Report report = new Report();
235                                 //loadField(element, report);
236
237                                 //TODO: info.fieldsMap.put(field.name, Field);
238                         }
239                 }
240                 
241                 tablesMap.put(info.name, info);
242         }
243
244         /**
245          * @param element
246          * @param reportNode
247          */
248         private void loadReport(Element element, Report report) {
249                 report.name = element.getAttribute(ATTRIBUTE_NAME);
250                 loadTitle(element, report);
251         }
252         
253         private TableInfo getTableInfo(final String tableName) {
254                 return tablesMap.get(tableName);
255         }
256
257         public enum HostingMode {
258             HOSTING_MODE_POSTGRES_CENTRAL,
259             HOSTING_MODE_POSTGRES_SELF,
260             HOSTING_MODE_SQLITE
261         };
262         
263         public String get_database_title(final String locale) {
264                 return databaseTitle.get_title(locale);
265         }
266         
267         public String get_database_title_original() {
268                 return databaseTitle.get_title_original();
269         }
270         
271         public StringVector get_translation_available_locales() {
272                 return new StringVector();
273         }
274         
275         public Document.HostingMode get_hosting_mode() {
276                 return HostingMode.HOSTING_MODE_POSTGRES_CENTRAL;
277         }
278         
279         public String get_connection_server() {
280                 return connectionServer;
281         }
282         
283         public long get_connection_port() {
284                 return connectionPort;
285         }
286         
287         public String get_connection_database() {
288                 return connectionDatabase;
289         }
290         
291         public StringVector get_table_names() {
292                 StringVector result = new StringVector(); //TODO: Use a normal type.
293                 
294                 //return tablesMap.keySet();
295                 
296                 for (final TableInfo info : tablesMap.values()) {
297                         result.add(info.name);
298                 }
299                 
300                 return result;
301         }
302         
303         public boolean get_table_is_hidden(final String table_name) {
304                 for (final TableInfo info : tablesMap.values()) {
305                         return info.isHidden;
306                 }
307                 
308                 return false;
309         }
310                         
311         public String get_table_title(final String tableName, final String locale) {
312                 final TableInfo info = getTableInfo(tableName);
313                 if(info == null) {
314                         return "";
315                 }
316                 
317                 return info.get_title(locale);
318         }
319         
320         public String get_default_table() {
321                 for (final TableInfo info : tablesMap.values()) {
322                         if(info.isDefault) {
323                                 return info.name;
324                         }
325                 }
326                 
327                 return "";
328         }
329         
330         public boolean get_table_is_known(String tableName) {
331                 final TableInfo info = getTableInfo(tableName);
332                 if(info == null) {
333                         return false;
334                 }
335                 
336                 return true;
337         }
338         
339         public FieldVector get_table_fields(final String tableName) {
340                 //TODO:
341                 return new FieldVector();
342         }
343         
344         public Field get_field(String table_name, String strFieldName) {
345                 //TODO:
346                 return new Field();
347         }
348         
349         public LayoutGroupVector get_data_layout_groups(String layout_name, String parent_table_name) {
350                 //TODO:
351                 return new LayoutGroupVector();
352         }
353         
354         public StringVector get_report_names(String tableName) {
355                 StringVector result = new StringVector();
356
357                 final TableInfo info = getTableInfo(tableName);
358                 if(info == null)
359                         return result;
360
361                 for (final Report report : info.reportsMap.values()) {
362                         result.add(report.name);
363                 }
364
365                 return new StringVector();
366         }
367         
368         public Report get_report(String tableName, String reportName) {
369                 final TableInfo info = getTableInfo(tableName);
370                 if(info == null)
371                         return null;
372
373                 return info.reportsMap.get(reportName);
374         }
375 }