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.sql.Connection;
23 import java.sql.SQLException;
24 import java.util.ArrayList;
26 import javax.servlet.ServletException;
28 import org.apache.commons.lang3.StringUtils;
29 import org.glom.web.client.OnlineGlomService;
30 import org.glom.web.server.libglom.Document;
31 import org.glom.web.shared.DataItem;
32 import org.glom.web.shared.DetailsLayoutAndData;
33 import org.glom.web.shared.DocumentInfo;
34 import org.glom.web.shared.Documents;
35 import org.glom.web.shared.NavigationRecord;
36 import org.glom.web.shared.Reports;
37 import org.glom.web.shared.TypedDataItem;
38 import org.glom.web.shared.libglom.Report;
39 import org.glom.web.shared.libglom.layout.LayoutGroup;
40 import org.glom.web.shared.libglom.layout.LayoutItemPortal;
42 import com.google.gwt.user.server.rpc.RemoteServiceServlet;
45 * This is the servlet class for setting up the server side of Online Glom. The client side can call the public methods
46 * in this class via OnlineGlom
48 * For instance, it loads all the available documents and provide a list - see getDocuments(). It then provides
49 * information from each document. For instance, see getListViewLayout().
51 * TODO: Watch for changes to the .glom files, to reload new versions and to load newly-added files. TODO: Watch for
52 * changes to the properties (configuration)?
54 @SuppressWarnings("serial")
55 public class OnlineGlomServiceImpl extends RemoteServiceServlet implements OnlineGlomService {
57 ConfiguredDocumentSet configuredDocumentSet = new ConfiguredDocumentSet();
62 * @see org.glom.web.client.OnlineGlomService#checkAuthentication(java.lang.String, java.lang.String,
66 public boolean checkAuthentication(final String documentID, final String username, final String password) {
67 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
68 if (configuredDoc == null) {
69 Log.error(documentID, "The document could not be found for this ID: " + documentID);
74 return configuredDoc.setUsernameAndPassword(username, password);
75 } catch (final SQLException e) {
76 Log.error(documentID, "Unknown SQL Error checking the database authentication.", e);
82 * This is called when the servlet is stopped or restarted.
84 * @see javax.servlet.GenericServlet#destroy()
87 public void destroy() {
88 configuredDocumentSet.forgetDocuments();
94 * @see org.glom.web.client.OnlineGlomService#getConfigurationErrorMessage()
97 public String getConfigurationErrorMessage() {
98 Exception configurationException = configuredDocumentSet.getConfigurationException();
99 if (configurationException == null) {
100 return "No configuration errors to report.";
101 } else if (configurationException.getMessage() == null) {
102 return configurationException.toString();
104 return configurationException.getMessage();
111 * @see org.glom.web.client.OnlineGlomService#getDetailsData(java.lang.String, java.lang.String, java.lang.String)
114 public DataItem[] getDetailsData(final String documentID, final String tableName,
115 final TypedDataItem primaryKeyValue) {
116 // An empty tableName is OK, because that means the default table.
118 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
119 if (configuredDoc == null) {
120 return new DataItem[0];
123 // FIXME check for authentication
125 return configuredDoc.getDetailsData(tableName, primaryKeyValue);
131 * @see org.glom.web.client.OnlineGlomService#getDetailsLayoutAndData(java.lang.String, java.lang.String,
135 public DetailsLayoutAndData getDetailsLayoutAndData(final String documentID, final String tableName,
136 final TypedDataItem primaryKeyValue, final String localeID) {
137 // An empty tableName is OK, because that means the default table.
139 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
140 if (configuredDoc == null) {
144 // FIXME check for authentication
146 final DetailsLayoutAndData initalDetailsView = new DetailsLayoutAndData();
148 .setLayout(configuredDoc.getDetailsLayoutGroup(tableName, StringUtils.defaultString(localeID)));
149 initalDetailsView.setData(configuredDoc.getDetailsData(tableName, primaryKeyValue));
151 return initalDetailsView;
157 * @see org.glom.web.client.OnlineGlomService#getDocumentInfo(java.lang.String)
160 public DocumentInfo getDocumentInfo(final String documentID, final String localeID) {
162 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
164 // Avoid dereferencing a null object:
165 if (configuredDoc == null) {
166 return new DocumentInfo();
169 // FIXME check for authentication
171 return configuredDoc.getDocumentInfo(StringUtils.defaultString(localeID));
178 * @see org.glom.web.client.OnlineGlomService#getDocuments()
181 public Documents getDocuments() {
182 return configuredDocumentSet.getDocuments();
188 * @see org.glom.web.client.OnlineGlomService#getListViewData(java.lang.String, java.lang.String, int, int, int,
192 public ArrayList<DataItem[]> getListViewData(final String documentID, final String tableName,
193 final String quickFind, final int start, final int length, final int sortColumnIndex,
194 final boolean isAscending) {
195 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
196 if (configuredDoc == null) {
197 return new ArrayList<DataItem[]>();
200 if (!configuredDoc.isAuthenticated()) {
201 return new ArrayList<DataItem[]>();
203 return configuredDoc.getListViewData(tableName, quickFind, start, length, true, sortColumnIndex, isAscending);
209 * @see org.glom.web.client.OnlineGlomService#getListViewLayout(java.lang.String, java.lang.String)
212 public LayoutGroup getListViewLayout(final String documentID, final String tableName, final String localeID) {
213 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
214 if (configuredDoc == null) {
215 return new LayoutGroup();
218 // FIXME check for authentication
220 return configuredDoc.getListViewLayoutGroup(tableName, StringUtils.defaultString(localeID));
226 * @see org.glom.web.client.OnlineGlomService#getRelatedListData(java.lang.String, java.lang.String, int, int, int,
230 public ArrayList<DataItem[]> getRelatedListData(final String documentID, final String tableName,
231 final LayoutItemPortal portal, final TypedDataItem foreignKeyValue, final int start, final int length,
232 final int sortColumnIndex, final boolean ascending) {
233 // An empty tableName is OK, because that means the default table.
235 if (portal == null) {
236 Log.error("getRelatedListData(): portal is null.");
240 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
241 if (configuredDoc == null) {
242 return new ArrayList<DataItem[]>();
245 // FIXME check for authentication
247 return configuredDoc.getRelatedListData(tableName, portal, foreignKeyValue, start, length, sortColumnIndex,
252 public int getRelatedListRowCount(final String documentID, final String tableName, final LayoutItemPortal portal,
253 final TypedDataItem foreignKeyValue) {
254 // An empty tableName is OK, because that means the default table.
256 if (portal == null) {
257 Log.error("getRelatedListRowCount(): portal is null");
261 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
262 if (configuredDoc == null) {
266 // FIXME check for authentication
268 return configuredDoc.getRelatedListRowCount(tableName, portal, foreignKeyValue);
271 // TODO: Specify the foundset (via a where clause) and maybe a default sort order.
275 * @see org.glom.web.client.OnlineGlomService#getReportLayout(java.lang.String, java.lang.String, java.lang.String,
279 public String getReportHTML(final String documentID, final String tableName, final String reportName,
280 final String quickFind, final String localeID) {
281 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
282 if (configuredDoc == null) {
286 final Document glomDocument = configuredDoc.getDocument();
287 if (glomDocument == null) {
288 final String errorMessage = "getReportHTML(): getDocument() failed.";
289 Log.fatal(errorMessage);
290 // TODO: throw new Exception(errorMessage);
294 // FIXME check for authentication
296 final Report report = glomDocument.getReport(tableName, reportName);
297 if (report == null) {
298 Log.info(documentID, tableName, "The report layout is not defined for this table:" + reportName);
302 Connection connection;
304 connection = configuredDoc.getCpds().getConnection();
305 } catch (final SQLException e2) {
306 // TODO Auto-generated catch block
307 e2.printStackTrace();
308 return "Connection Failed";
311 // TODO: Use quickFind
312 final ReportGenerator generator = new ReportGenerator(StringUtils.defaultString(localeID));
313 return generator.generateReport(glomDocument, tableName, report, connection, quickFind);
319 * @see org.glom.web.client.OnlineGlomService#getReportsList(java.lang.String, java.lang.String, java.lang.String)
322 public Reports getReportsList(final String documentID, final String tableName, final String localeID) {
323 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
324 return configuredDoc.getReports(tableName, localeID);
327 // TODO: It would be more efficient to get the extra related (or related related) column value along with the other
329 // instead of doing a separate SQL query to get it now for a specific row.
333 * @see org.glom.web.client.OnlineGlomService#getSuitableRecordToViewDetails(java.lang.String, java.lang.String,
334 * java.lang.String, java.lang.String)
337 public NavigationRecord getSuitableRecordToViewDetails(final String documentID, final String tableName,
338 final LayoutItemPortal portal, final TypedDataItem primaryKeyValue) {
339 // An empty tableName is OK, because that means the default table.
341 if (portal == null) {
342 Log.error("getSuitableRecordToViewDetails(): portal is null");
346 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
347 if (configuredDoc == null) {
351 // FIXME check for authentication
353 return configuredDoc.getSuitableRecordToViewDetails(tableName, portal, primaryKeyValue);
357 * This is called when the servlet is started or restarted.
361 * @see javax.servlet.GenericServlet#init()
364 public void init() throws ServletException {
365 configuredDocumentSet.readConfiguration();
371 * @see org.glom.web.client.OnlineGlomService#isAuthenticated(java.lang.String)
374 public boolean isAuthenticated(final String documentID) {
375 final ConfiguredDocument configuredDoc = configuredDocumentSet.getDocument(documentID);
376 if (configuredDoc == null) {
380 return configuredDoc.isAuthenticated();