2 * Copyright (C) 2010, 2011 Openismus GmbH
4 * This file is part of GWT-Glom.
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.
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
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/>.
20 package org.glom.web.server;
22 import java.beans.PropertyVetoException;
23 import java.sql.Connection;
24 import java.sql.ResultSet;
25 import java.sql.SQLException;
26 import java.sql.Statement;
27 import java.util.ArrayList;
29 import org.glom.libglom.Document;
30 import org.glom.libglom.Field;
31 import org.glom.libglom.Glom;
32 import org.glom.libglom.LayoutFieldVector;
33 import org.glom.libglom.LayoutGroupVector;
34 import org.glom.libglom.LayoutItem;
35 import org.glom.libglom.LayoutItemVector;
36 import org.glom.libglom.LayoutItem_Field;
37 import org.glom.libglom.StringVector;
38 import org.glom.web.client.GlomDocument;
39 import org.glom.web.client.GlomTable;
40 import org.glom.web.client.LibGlomService;
42 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
43 import com.mchange.v2.c3p0.ComboPooledDataSource;
44 import com.mchange.v2.c3p0.DataSources;
46 @SuppressWarnings("serial")
47 public class LibGlomServiceImpl extends RemoteServiceServlet implements LibGlomService {
48 private Document document;
49 ComboPooledDataSource cpds;
51 // Called only when the servlet is stopped (the servlet container is stopped or restarted)
52 public LibGlomServiceImpl() {
54 document = new Document();
55 // TODO hardcoded for now, need to figure out something for this
56 document.set_file_uri("file:///home/ben/music-collection.glom");
58 @SuppressWarnings("unused")
59 boolean retval = document.load(error);
60 // TODO handle error condition (also below)
62 cpds = new ComboPooledDataSource();
63 // load the jdbc driver
65 cpds.setDriverClass("org.postgresql.Driver");
66 } catch (PropertyVetoException e) {
67 // TODO log error, fatal error can't continue, user can be nofified when db access doesn't work
71 cpds.setJdbcUrl("jdbc:postgresql://" + document.get_connection_server() + "/"
72 + document.get_connection_database());
73 // TODO figure out something for db user name and password
75 cpds.setPassword("ChangeMe"); // of course it's not the password I'm using on my server
78 /* FIXME I think Swig is generating long on 64-bit machines and int on 32-bit machines - need to keep this constant
79 * http://stackoverflow.com/questions /1590831/safely-casting-long-to-int-in-java */
80 public static int safeLongToInt(long l) {
81 if (l < Integer.MIN_VALUE || l > Integer.MAX_VALUE) {
82 throw new IllegalArgumentException(l + " cannot be cast to int without changing its value.");
87 public GlomDocument getGlomDocument() {
88 GlomDocument glomDocument = new GlomDocument();
91 glomDocument.setTitle(document.get_database_title());
93 // set array of GlomTables and the default table index
94 StringVector tableNames = document.get_table_names();
95 GlomTable[] tables = new GlomTable[safeLongToInt(tableNames.size())];
96 for (int i = 0; i < tableNames.size(); i++) {
97 String tableName = tableNames.get(i);
98 GlomTable glomTable = new GlomTable();
99 glomTable.setName(tableName);
100 glomTable.setTitle(document.get_table_title(tableName));
101 tables[i] = glomTable;
102 if (tableName.equals(document.get_default_table())) {
103 glomDocument.setDefaultTableIndex(i);
106 glomDocument.setTables(tables);
111 public String[] getLayoutListHeaders(String table) {
112 LayoutGroupVector layoutList = document.get_data_layout_groups("list", table);
113 LayoutItemVector layoutItems = layoutList.get(0).get_items();
114 String[] headers = new String[safeLongToInt(layoutItems.size())];
115 for (int i = 0; i < layoutItems.size(); i++) {
116 headers[i] = layoutItems.get(i).get_title_or_name();
121 public ArrayList<String[]> getTableData(int start, int length, String table) {
122 LayoutGroupVector layoutList = document.get_data_layout_groups("list", table);
123 LayoutItemVector layoutItems = layoutList.get(0).get_items();
125 LayoutFieldVector layoutFields = new LayoutFieldVector();
126 for (int i = 0; i < layoutItems.size(); i++) {
127 LayoutItem item = layoutItems.get(i);
128 LayoutItem_Field field = LayoutItem_Field.cast_dynamic(item);
130 layoutFields.add(field);
131 Field details = field.get_full_field_details();
132 if (details != null && details.get_primary_key()) {
133 // TODO implement this for sort order, will need to sort out swig support for std::list in Java
134 // C++ code to port to Java:
135 // sort_clause.push_back(Glom::type_pair_sort_field(field, true));
140 ArrayList<String[]> rowsList = new ArrayList<String[]>();
142 Connection conn = cpds.getConnection();
143 Statement st = conn.createStatement();
145 String query = Glom.build_sql_select_simple(table, layoutFields);
146 ResultSet rs = st.executeQuery(query);
149 String[] rowArray = new String[safeLongToInt(layoutItems.size())];
150 for (int i = 0; i < layoutItems.size(); i++) {
151 rowArray[i] = rs.getString(i + 1);
153 rowsList.add(rowArray);
158 } catch (SQLException e) {
159 // TODO: log error, notify user of problem
166 // Called only when the servlet is stopped (the servlet container is stopped or restarted)
167 public void destroy() {
168 Glom.libglom_deinit();
170 DataSources.destroy(cpds);
171 } catch (SQLException e) {
172 // TODO log error, don't need to notify user because this is a clean up method