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.mchange.v2.c3p0.ComboPooledDataSource;
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 (). 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 OnlineGlomServlet implements OnlineGlomService {
59 * This is called when the servlet is stopped or restarted.
61 * @see javax.servlet.GenericServlet#destroy()
64 public void destroy() {
65 //TODO: This is an arbitrary place to do this,
66 //because this is shared by all servlets.
67 //It is even necessary?
68 final ConfiguredDocumentSet configuredDocumentSet = getConfiguredDocumentSet();
69 if(configuredDocumentSet != null) {
70 configuredDocumentSet.forgetDocuments();
77 * @see org.glom.web.client.OnlineGlomService#getConfigurationErrorMessage()
80 public String getConfigurationErrorMessage() {
81 final ConfiguredDocumentSet configuredDocumentSet = getConfiguredDocumentSet();
82 if(configuredDocumentSet == null) {
83 Log.error("Could not get the configuredDocumentSet.");
87 final Exception configurationException = configuredDocumentSet.getConfigurationException();
88 if (configurationException == null) {
89 return "No configuration errors to report.";
90 } else if (configurationException.getMessage() == null) {
91 return configurationException.toString();
93 return configurationException.getMessage();
100 * @see org.glom.web.client.OnlineGlomService#getDetailsData(java.lang.String, java.lang.String, java.lang.String)
103 public DataItem[] getDetailsData(final String documentID, final String tableName,
104 final TypedDataItem primaryKeyValue) {
105 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
106 if(authenticatedConnection == null) {
107 return new DataItem[0];
110 // An empty tableName is OK, because that means the default table.
112 final ConfiguredDocument configuredDoc = getDocument(documentID);
113 if (configuredDoc == null) {
114 return new DataItem[0];
117 return configuredDoc.getDetailsData(authenticatedConnection, tableName, primaryKeyValue);
123 * @see org.glom.web.client.OnlineGlomService#getDetailsLayoutAndData(java.lang.String, java.lang.String,
127 public DetailsLayoutAndData getDetailsLayoutAndData(final String documentID, final String tableName,
128 final TypedDataItem primaryKeyValue, final String localeID) {
129 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
130 if(authenticatedConnection == null) {
134 // An empty tableName is OK, because that means the default table.
136 final ConfiguredDocument configuredDoc = getDocument(documentID);
137 if (configuredDoc == null) {
141 final DetailsLayoutAndData initalDetailsView = new DetailsLayoutAndData();
143 .setLayout(configuredDoc.getDetailsLayoutGroup(tableName, StringUtils.defaultString(localeID)));
144 initalDetailsView.setData(configuredDoc.getDetailsData(authenticatedConnection, tableName, primaryKeyValue));
146 return initalDetailsView;
152 * @see org.glom.web.client.OnlineGlomService#getDocumentInfo(java.lang.String)
155 public DocumentInfo getDocumentInfo(final String documentID, final String localeID) {
157 if (!isAuthenticated(documentID)) {
158 return new DocumentInfo();
161 final ConfiguredDocument configuredDoc = getDocument(documentID);
163 // Avoid dereferencing a null object:
164 if (configuredDoc == null) {
165 return new DocumentInfo();
168 return configuredDoc.getDocumentInfo(StringUtils.defaultString(localeID));
174 * @see org.glom.web.client.OnlineGlomService#getDocuments()
177 public Documents getDocuments() {
178 final ConfiguredDocumentSet configuredDocumentSet = getConfiguredDocumentSet();
179 if(configuredDocumentSet == null) {
180 Log.error("Could not get the configuredDocumentSet.");
184 return configuredDocumentSet.getDocuments();
190 * @see org.glom.web.client.OnlineGlomService#getListViewData(java.lang.String, java.lang.String, int, int, int,
194 public ArrayList<DataItem[]> getListViewData(final String documentID, final String tableName,
195 final String quickFind, final int start, final int length, final int sortColumnIndex,
196 final boolean isAscending) {
197 if (!isAuthenticated(documentID)) {
198 return new ArrayList<DataItem[]>();
201 final ConfiguredDocument configuredDoc = getDocument(documentID);
202 if (configuredDoc == null) {
203 return new ArrayList<DataItem[]>();
206 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
207 if(authenticatedConnection == null) {
208 return new ArrayList<DataItem[]>();
211 return configuredDoc.getListViewData(authenticatedConnection, tableName, quickFind, start, length, true, sortColumnIndex, isAscending);
217 * @see org.glom.web.client.OnlineGlomService#getListViewLayout(java.lang.String, java.lang.String)
220 public LayoutGroup getListViewLayout(final String documentID, final String tableName, final String localeID) {
221 if (!isAuthenticated(documentID)) {
222 return new LayoutGroup();
225 final ConfiguredDocument configuredDoc = getDocument(documentID);
226 if (configuredDoc == null) {
227 return new LayoutGroup();
230 return configuredDoc.getListViewLayoutGroup(tableName, StringUtils.defaultString(localeID));
236 * @see org.glom.web.client.OnlineGlomService#getRelatedListData(java.lang.String, java.lang.String, int, int, int,
240 public ArrayList<DataItem[]> getRelatedListData(final String documentID, final String tableName,
241 final LayoutItemPortal portal, final TypedDataItem foreignKeyValue, final int start, final int length,
242 final int sortColumnIndex, final boolean ascending) {
243 if (!isAuthenticated(documentID)) {
244 return new ArrayList<DataItem[]>();
247 // An empty tableName is OK, because that means the default table.
249 if (portal == null) {
250 Log.error("getRelatedListData(): portal is null.");
254 final ConfiguredDocument configuredDoc = getDocument(documentID);
255 if (configuredDoc == null) {
256 return new ArrayList<DataItem[]>();
259 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
260 if(authenticatedConnection == null) {
264 return configuredDoc.getRelatedListData(authenticatedConnection, tableName, portal, foreignKeyValue, start, length, sortColumnIndex,
269 public int getRelatedListRowCount(final String documentID, final String tableName, final LayoutItemPortal portal,
270 final TypedDataItem foreignKeyValue) {
271 if (!isAuthenticated(documentID)) {
275 // An empty tableName is OK, because that means the default table.
277 if (portal == null) {
278 Log.error("getRelatedListRowCount(): portal is null");
282 final ConfiguredDocument configuredDoc = getDocument(documentID);
283 if (configuredDoc == null) {
287 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
288 if(authenticatedConnection == null) {
292 return configuredDoc.getRelatedListRowCount(authenticatedConnection, tableName, portal, foreignKeyValue);
295 // TODO: Specify the foundset (via a where clause) and maybe a default sort order.
299 * @see org.glom.web.client.OnlineGlomService#getReportLayout(java.lang.String, java.lang.String, java.lang.String,
303 public String getReportHTML(final String documentID, final String tableName, final String reportName,
304 final String quickFind, final String localeID) {
305 if (!isAuthenticated(documentID)) {
309 final ConfiguredDocument configuredDoc = getDocument(documentID);
310 if (configuredDoc == null) {
314 final Document glomDocument = configuredDoc.getDocument();
315 if (glomDocument == null) {
316 final String errorMessage = "getReportHTML(): getDocument() failed.";
317 Log.fatal(errorMessage);
318 // TODO: throw new Exception(errorMessage);
322 final Report report = glomDocument.getReport(tableName, reportName);
323 if (report == null) {
324 Log.info(documentID, tableName, "The report layout is not defined for this table:" + reportName);
328 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
329 if(authenticatedConnection == null) {
333 Connection connection;
335 connection = authenticatedConnection.getConnection();
336 } catch (final SQLException e2) {
337 // TODO Auto-generated catch block
338 e2.printStackTrace();
339 return "Connection Failed";
342 // TODO: Use quickFind
343 final ReportGenerator generator = new ReportGenerator(StringUtils.defaultString(localeID));
344 return generator.generateReport(glomDocument, tableName, report, connection, quickFind);
350 * @see org.glom.web.client.OnlineGlomService#getReportsList(java.lang.String, java.lang.String, java.lang.String)
353 public Reports getReportsList(final String documentID, final String tableName, final String localeID) {
354 final ConfiguredDocument configuredDoc = getDocument(documentID);
355 if(configuredDoc != null) {
356 return configuredDoc.getReports(tableName, localeID);
362 // TODO: It would be more efficient to get the extra related (or related related) column value along with the other
364 // instead of doing a separate SQL query to get it now for a specific row.
368 * @see org.glom.web.client.OnlineGlomService#getSuitableRecordToViewDetails(java.lang.String, java.lang.String,
369 * java.lang.String, java.lang.String)
372 public NavigationRecord getSuitableRecordToViewDetails(final String documentID, final String tableName,
373 final LayoutItemPortal portal, final TypedDataItem primaryKeyValue) {
374 final ComboPooledDataSource authenticatedConnection = getConnection(documentID);
375 if(authenticatedConnection == null) {
379 // An empty tableName is OK, because that means the default table.
381 if (portal == null) {
382 Log.error("getSuitableRecordToViewDetails(): portal is null");
386 final ConfiguredDocument configuredDoc = getDocument(documentID);
387 if (configuredDoc == null) {
391 return configuredDoc.getSuitableRecordToViewDetails(authenticatedConnection, tableName, portal, primaryKeyValue);
395 * This is called when the servlet is started or restarted.
399 * @see javax.servlet.GenericServlet#init()
402 public void init() throws ServletException {