1
|
/**
|
2
|
* '$RCSfile$'
|
3
|
* Purpose: A Class that implements a metadata catalog as a java Servlet
|
4
|
* Copyright: 2006 Regents of the University of California and the
|
5
|
* National Center for Ecological Analysis and Synthesis
|
6
|
* Authors: Matt Jones, Dan Higgins, Jivka Bojilova, Chad Berkley, Matthew Perry
|
7
|
*
|
8
|
* '$Author: cjones $'
|
9
|
* '$Date: 2016-05-18 09:01:29 -0700 (Wed, 18 May 2016) $'
|
10
|
* '$Revision: 9780 $'
|
11
|
*
|
12
|
* This program is free software; you can redistribute it and/or modify
|
13
|
* it under the terms of the GNU General Public License as published by
|
14
|
* the Free Software Foundation; either version 2 of the License, or
|
15
|
* (at your option) any later version.
|
16
|
*
|
17
|
* This program is distributed in the hope that it will be useful,
|
18
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
19
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
20
|
* GNU General Public License for more details.
|
21
|
*
|
22
|
* You should have received a copy of the GNU General Public License
|
23
|
* along with this program; if not, write to the Free Software
|
24
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
25
|
*/
|
26
|
|
27
|
package edu.ucsb.nceas.metacat;
|
28
|
|
29
|
import java.io.IOException;
|
30
|
import java.io.OutputStreamWriter;
|
31
|
import java.io.PrintWriter;
|
32
|
import java.io.Writer;
|
33
|
import java.sql.PreparedStatement;
|
34
|
import java.sql.ResultSet;
|
35
|
import java.sql.SQLException;
|
36
|
import java.sql.Timestamp;
|
37
|
import java.util.Enumeration;
|
38
|
import java.util.Hashtable;
|
39
|
import java.util.Timer;
|
40
|
import java.util.Vector;
|
41
|
|
42
|
import javax.servlet.ServletConfig;
|
43
|
import javax.servlet.ServletContext;
|
44
|
import javax.servlet.ServletException;
|
45
|
import javax.servlet.ServletOutputStream;
|
46
|
import javax.servlet.http.HttpServlet;
|
47
|
import javax.servlet.http.HttpServletRequest;
|
48
|
import javax.servlet.http.HttpServletResponse;
|
49
|
import javax.servlet.http.HttpSession;
|
50
|
|
51
|
import org.apache.commons.lang.StringEscapeUtils;
|
52
|
import org.apache.log4j.Logger;
|
53
|
import org.apache.log4j.PropertyConfigurator;
|
54
|
|
55
|
|
56
|
import edu.ucsb.nceas.metacat.common.query.EnabledQueryEngines;
|
57
|
import edu.ucsb.nceas.metacat.database.DBConnection;
|
58
|
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
|
59
|
import edu.ucsb.nceas.metacat.database.DatabaseService;
|
60
|
import edu.ucsb.nceas.metacat.dataone.hazelcast.HazelcastService;
|
61
|
import edu.ucsb.nceas.metacat.plugin.MetacatHandlerPlugin;
|
62
|
import edu.ucsb.nceas.metacat.plugin.MetacatHandlerPluginManager;
|
63
|
import edu.ucsb.nceas.metacat.properties.PropertyService;
|
64
|
import edu.ucsb.nceas.metacat.properties.SkinPropertyService;
|
65
|
import edu.ucsb.nceas.metacat.replication.ReplicationService;
|
66
|
import edu.ucsb.nceas.metacat.service.ServiceService;
|
67
|
import edu.ucsb.nceas.metacat.service.SessionService;
|
68
|
import edu.ucsb.nceas.metacat.service.XMLSchemaService;
|
69
|
import edu.ucsb.nceas.metacat.shared.BaseException;
|
70
|
import edu.ucsb.nceas.metacat.shared.HandlerException;
|
71
|
import edu.ucsb.nceas.metacat.shared.MetacatUtilException;
|
72
|
import edu.ucsb.nceas.metacat.shared.ServiceException;
|
73
|
import edu.ucsb.nceas.metacat.spatial.SpatialHarvester;
|
74
|
import edu.ucsb.nceas.metacat.util.AuthUtil;
|
75
|
import edu.ucsb.nceas.metacat.util.ConfigurationUtil;
|
76
|
import edu.ucsb.nceas.metacat.util.DocumentUtil;
|
77
|
import edu.ucsb.nceas.metacat.util.ErrorSendingErrorException;
|
78
|
import edu.ucsb.nceas.metacat.util.RequestUtil;
|
79
|
import edu.ucsb.nceas.metacat.util.ResponseUtil;
|
80
|
import edu.ucsb.nceas.metacat.util.SessionData;
|
81
|
import edu.ucsb.nceas.metacat.util.SystemUtil;
|
82
|
import edu.ucsb.nceas.metacat.workflow.WorkflowSchedulerClient;
|
83
|
import edu.ucsb.nceas.utilities.FileUtil;
|
84
|
import edu.ucsb.nceas.utilities.GeneralPropertyException;
|
85
|
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
|
86
|
import edu.ucsb.nceas.utilities.UtilException;
|
87
|
|
88
|
/**
|
89
|
* A metadata catalog server implemented as a Java Servlet
|
90
|
*
|
91
|
* Valid actions are:
|
92
|
*
|
93
|
* action=login
|
94
|
* username
|
95
|
* password
|
96
|
* qformat
|
97
|
* action=logout
|
98
|
* qformat
|
99
|
* action=query -- query the values of all elements and attributes and return a result set of nodes
|
100
|
* meta_file_id --
|
101
|
* returndoctype --
|
102
|
* filterdoctype --
|
103
|
* returnfield --
|
104
|
* owner --
|
105
|
* site --
|
106
|
* operator --
|
107
|
* casesensitive --
|
108
|
* searchmode --
|
109
|
* anyfield --
|
110
|
* action=spatial_query -- run a spatial query. these queries may include any of the
|
111
|
* queries supported by the WFS / WMS standards
|
112
|
* xmax --
|
113
|
* ymax --
|
114
|
* xmin --
|
115
|
* ymin --
|
116
|
* skin --
|
117
|
* pagesize --
|
118
|
* pagestart --
|
119
|
* action=squery -- structured query (see pathquery.dtd)
|
120
|
* query --
|
121
|
* pagesize --
|
122
|
* pagestart --
|
123
|
* action=export -- export a zip format for data packadge
|
124
|
* docid --
|
125
|
* action=read -- read any metadata/data file from Metacat and from Internet
|
126
|
* archiveEntryName --
|
127
|
* docid --
|
128
|
* qformat --
|
129
|
* metadatadocid --
|
130
|
* action=readinlinedata -- read inline data only
|
131
|
* inlinedataid
|
132
|
* action=insert -- insert an XML document into the database store
|
133
|
* qformat --
|
134
|
* docid --
|
135
|
* doctext --
|
136
|
* dtdtext --
|
137
|
* action=insertmultipart -- insert an xml document into the database using multipart encoding
|
138
|
* qformat --
|
139
|
* docid --
|
140
|
* action=update -- update an XML document that is in the database store
|
141
|
* qformat --
|
142
|
* docid --
|
143
|
* doctext --
|
144
|
* dtdtext --
|
145
|
* action=delete -- delete an XML document from the database store
|
146
|
* docid --
|
147
|
* action=validate -- validate the xml contained in valtext
|
148
|
* valtext --
|
149
|
* docid --
|
150
|
* action=setaccess -- change access permissions for a user on a document.
|
151
|
* docid --
|
152
|
* principal --
|
153
|
* permission --
|
154
|
* permType --
|
155
|
* permOrder --
|
156
|
* action=getaccesscontrol -- retrieve acl info for Metacat document
|
157
|
* docid --
|
158
|
* action=getprincipals -- retrieve a list of principals in XML
|
159
|
* action=getalldocids -- retrieves a list of all docids registered with the system
|
160
|
* scope --
|
161
|
* action=getlastdocid --
|
162
|
* scope --
|
163
|
* username --
|
164
|
* action=isregistered -- checks to see if the provided docid is registered
|
165
|
* docid --
|
166
|
* action=getrevisionanddoctype -- get a document's revision and doctype from database
|
167
|
* docid --
|
168
|
* action=getversion --
|
169
|
* action=getdoctypes -- retrieve all doctypes (publicID)
|
170
|
* action=getdtdschema -- retrieve a DTD or Schema file
|
171
|
* doctype --
|
172
|
* action=getlog -- get a report of events that have occurred in the system
|
173
|
* ipAddress -- filter on one or more IP addresses>
|
174
|
* principal -- filter on one or more principals (LDAP DN syntax)
|
175
|
* docid -- filter on one or more document identifiers (with revision)
|
176
|
* event -- filter on event type (e.g., read, insert, update, delete)
|
177
|
* start -- filter out events before the start date-time
|
178
|
* end -- filter out events before the end date-time
|
179
|
* action=getloggedinuserinfo -- get user info for the currently logged in user
|
180
|
* ipAddress -- filter on one or more IP addresses>
|
181
|
* principal -- filter on one or more principals (LDAP DN syntax)
|
182
|
* docid -- filter on one or more document identifiers (with revision)
|
183
|
* event -- filter on event type (e.g., read, insert, update, delete)
|
184
|
* start -- filter out events before the start date-time
|
185
|
* end -- filter out events before the end date-time
|
186
|
* action=shrink -- Shrink the database connection pool size if it has grown and
|
187
|
* extra connections are no longer being used.
|
188
|
* action=buildindex --
|
189
|
* docid --
|
190
|
* action=refreshServices --
|
191
|
* action=scheduleWorkflow -- Schedule a workflow to be run. Scheduling a workflow
|
192
|
* registers it with the scheduling engine and creates a row
|
193
|
* in the scheduled_job table. Note that this may be
|
194
|
* extracted into a separate servlet.
|
195
|
* delay -- The amount of time from now before the workflow should be run. The
|
196
|
* delay can be expressed in number of seconds, minutes, hours and days,
|
197
|
* for instance 30s, 2h, etc.
|
198
|
* starttime -- The time that the workflow should first run. If both are provided
|
199
|
* this takes precedence over delay. The time should be expressed as:
|
200
|
* MM/dd/yyyy HH:mm:ss with the timezone assumed to be that of the OS.
|
201
|
* endtime -- The time when the workflow should end. The time should be expressed as:
|
202
|
* MM/dd/yyyy HH:mm:ss with the timezone assumed to be that of the OS.
|
203
|
* intervalvalue -- The numeric value of the interval between runs
|
204
|
* intervalunit -- The unit of the interval between runs. Can be s, m, h, d for
|
205
|
* seconds, minutes, hours and days respectively
|
206
|
* workflowid -- The lsid of the workflow that we want to schedule. This workflow
|
207
|
* must already exist in the database.
|
208
|
* karid -- The karid for the workflow that we want to schedule.
|
209
|
* workflowname -- The name of the workflow.
|
210
|
* forwardto -- If provided, forward to this page when processing is done.
|
211
|
* qformat -- If provided, render results using the stylesheets associated with
|
212
|
* this skin. Default is xml.
|
213
|
* action=unscheduleWorkflow -- Unschedule a workflow. Unscheduling a workflow
|
214
|
* removes it from the scheduling engine and changes the
|
215
|
* status in the scheduled_job table to " unscheduled. Note
|
216
|
* that this may be extracted into a separate servlet.
|
217
|
* workflowjobname -- The job ID for the workflow run that we want to unschedule. This
|
218
|
* is held in the database as scheduled_job.name
|
219
|
* forwardto -- If provided, forward to this page when processing is done.
|
220
|
* qformat -- If provided, render results using the stylesheets associated with
|
221
|
* this skin. Default is xml.
|
222
|
* action=rescheduleWorkflow -- Unschedule a workflow. Rescheduling a workflow
|
223
|
* registers it with the scheduling engine and changes the
|
224
|
* status in the scheduled_job table to " scheduled. Note
|
225
|
* that this may be extracted into a separate servlet.
|
226
|
* workflowjobname -- The job ID for the workflow run that we want to reschedule. This
|
227
|
* is held in the database as scheduled_job.name
|
228
|
* forwardto -- If provided, forward to this page when processing is done.
|
229
|
* qformat -- If provided, render results using the stylesheets associated with
|
230
|
* this skin. Default is xml.
|
231
|
* action=deleteScheduledWorkflow -- Delete a workflow. Deleting a workflow
|
232
|
* removes it from the scheduling engine and changes the
|
233
|
* status in the scheduled_job table to " deleted. Note
|
234
|
* that this may be extracted into a separate servlet.
|
235
|
* workflowjobname -- The job ID for the workflow run that we want to delete. This
|
236
|
* is held in the database as scheduled_job.name
|
237
|
* forwardto -- If provided, forward to this page when processing is done.
|
238
|
* qformat -- If provided, render results using the stylesheets associated with
|
239
|
* this skin. Default is xml.
|
240
|
* action=reindex -- rebuild the solr index for the specified pids.
|
241
|
* pid -- the id of the document which will be rebuilt slor index.
|
242
|
* action=reindexall -- rebuild the solr index for all objects in the systemmetadata table.
|
243
|
*
|
244
|
* Here are some of the common parameters for actions
|
245
|
* doctype -- document type list returned by the query (publicID)
|
246
|
* qformat=xml -- display resultset from query in XML
|
247
|
* qformat=html -- display resultset from query in HTML
|
248
|
* qformat=zip -- zip resultset from query
|
249
|
* docid=34 -- display the document with the document ID number 34
|
250
|
* doctext -- XML text of the document to load into the database
|
251
|
* acltext -- XML access text for a document to load into the database
|
252
|
* dtdtext -- XML DTD text for a new DTD to load into Metacat XML Catalog
|
253
|
* query -- actual query text (to go with 'action=query' or 'action=squery')
|
254
|
* valtext -- XML text to be validated
|
255
|
* scope --can limit the query by the scope of the id
|
256
|
* docid --the docid to check
|
257
|
* datadoc -- data document name (id)
|
258
|
*/
|
259
|
public class MetaCatServlet extends HttpServlet {
|
260
|
|
261
|
private static final long serialVersionUID = 1L;
|
262
|
private Timer timer = null;
|
263
|
private static boolean _firstHalfInitialized = false;
|
264
|
private static boolean _fullyInitialized = false;
|
265
|
private MetacatHandler handler = null;
|
266
|
|
267
|
// Constants -- these should be final in a servlet
|
268
|
public static final String SCHEMALOCATIONKEYWORD = ":schemaLocation";
|
269
|
public static final String NONAMESPACELOCATION = ":noNamespaceSchemaLocation";
|
270
|
public static final String EML2KEYWORD = ":eml";
|
271
|
private static final String FALSE = "false";
|
272
|
private static final String TRUE = "true";
|
273
|
private static String LOG_CONFIG_NAME = null;
|
274
|
public static final String APPLICATION_NAME = "metacat";
|
275
|
public static final String DEFAULT_ENCODING = "UTF-8";
|
276
|
|
277
|
/**
|
278
|
* Initialize the servlet by creating appropriate database connections
|
279
|
*/
|
280
|
public void init(ServletConfig config) throws ServletException {
|
281
|
Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
|
282
|
try {
|
283
|
if(_firstHalfInitialized) {
|
284
|
return;
|
285
|
}
|
286
|
|
287
|
super.init(config);
|
288
|
|
289
|
ServletContext context = config.getServletContext();
|
290
|
context.setAttribute("APPLICATION_NAME", APPLICATION_NAME);
|
291
|
|
292
|
ServiceService serviceService = ServiceService.getInstance(context);
|
293
|
logMetacat.debug("MetaCatServlet.init - ServiceService singleton created " + serviceService);
|
294
|
|
295
|
// Initialize the properties file
|
296
|
String dirPath = ServiceService.getRealConfigDir();
|
297
|
|
298
|
LOG_CONFIG_NAME = dirPath + "/log4j.properties";
|
299
|
PropertyConfigurator.configureAndWatch(LOG_CONFIG_NAME);
|
300
|
|
301
|
// Register preliminary services
|
302
|
ServiceService.registerService("PropertyService", PropertyService.getInstance(context));
|
303
|
ServiceService.registerService("SkinPropertyService", SkinPropertyService.getInstance());
|
304
|
ServiceService.registerService("SessionService", SessionService.getInstance());
|
305
|
|
306
|
// Check to see if the user has requested to bypass configuration
|
307
|
// (dev option) and check see if metacat has been configured.
|
308
|
// If both are false then stop the initialization
|
309
|
if (!ConfigurationUtil.bypassConfiguration() && !ConfigurationUtil.isMetacatConfigured()) {
|
310
|
return;
|
311
|
}
|
312
|
|
313
|
_firstHalfInitialized = true;
|
314
|
|
315
|
initSecondHalf(context);
|
316
|
|
317
|
} catch (ServiceException se) {
|
318
|
String errorMessage =
|
319
|
"Service problem while intializing MetaCat Servlet: " + se.getMessage();
|
320
|
logMetacat.error("MetaCatServlet.init - " + errorMessage);
|
321
|
throw new ServletException(errorMessage);
|
322
|
} catch (MetacatUtilException mue) {
|
323
|
String errorMessage = "Metacat utility problem while intializing MetaCat Servlet: "
|
324
|
+ mue.getMessage();
|
325
|
logMetacat.error("MetaCatServlet.init - " + errorMessage);
|
326
|
throw new ServletException(errorMessage);
|
327
|
}
|
328
|
}
|
329
|
|
330
|
|
331
|
/**
|
332
|
* Initialize the remainder of the servlet. This is the part that can only
|
333
|
* be initialized after metacat properties have been configured
|
334
|
*
|
335
|
* @param context
|
336
|
* the servlet context of MetaCatServlet
|
337
|
*/
|
338
|
public void initSecondHalf(ServletContext context) throws ServletException {
|
339
|
|
340
|
Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
|
341
|
|
342
|
try {
|
343
|
ServiceService.registerService("DatabaseService", DatabaseService.getInstance());
|
344
|
|
345
|
// initialize DBConnection pool
|
346
|
DBConnectionPool connPool = DBConnectionPool.getInstance();
|
347
|
logMetacat.debug("MetaCatServlet.initSecondHalf - DBConnection pool initialized: " + connPool.toString());
|
348
|
|
349
|
// register the XML schema service
|
350
|
ServiceService.registerService("XMLSchemaService", XMLSchemaService.getInstance());
|
351
|
|
352
|
// check if eml201 document were corrected or not. if not, correct eml201 documents.
|
353
|
// Before Metacat 1.8.1, metacat uses tag RELEASE_EML_2_0_1_UPDATE_6 as eml
|
354
|
// schema, which accidentily points to wrong version of eml-resource.xsd.
|
355
|
String correctedEML201Doc = PropertyService.getProperty("document.eml201DocumentCorrected");
|
356
|
if (correctedEML201Doc != null && correctedEML201Doc.equals(FALSE)) {
|
357
|
logMetacat.info("MetaCatServlet.initSecondHalf - Start to correct eml201 documents");
|
358
|
EML201DocumentCorrector correct = new EML201DocumentCorrector();
|
359
|
boolean success = correct.run();
|
360
|
if (success) {
|
361
|
PropertyService.setProperty("document.eml201DocumentCorrected", TRUE);
|
362
|
}
|
363
|
logMetacat.info("MetaCatServlet.initSecondHalf - Finish to correct eml201 documents");
|
364
|
}
|
365
|
|
366
|
// Index the paths specified in the metacat.properties
|
367
|
checkIndexPaths();
|
368
|
|
369
|
// initiate the indexing Queue
|
370
|
IndexingQueue.getInstance();
|
371
|
|
372
|
// start the IndexingThread if indexingTimerTaskTime more than 0.
|
373
|
// It will index all the documents not yet indexed in the database
|
374
|
int indexingTimerTaskTime = Integer.parseInt(PropertyService
|
375
|
.getProperty("database.indexingTimerTaskTime"));
|
376
|
int delayTime = Integer.parseInt(PropertyService
|
377
|
.getProperty("database.indexingInitialDelay"));
|
378
|
|
379
|
if (indexingTimerTaskTime > 0) {
|
380
|
timer = new Timer();
|
381
|
timer.schedule(new IndexingTimerTask(), delayTime, indexingTimerTaskTime);
|
382
|
}
|
383
|
|
384
|
/*
|
385
|
* If spatial option is turned on and set to regenerate the spatial
|
386
|
* cache on restart, trigger the harvester regeneratation method
|
387
|
*/
|
388
|
if (PropertyService.getProperty("spatial.runSpatialOption").equals("true") &&
|
389
|
PropertyService.getProperty("spatial.regenerateCacheOnRestart").equals("true")) {
|
390
|
|
391
|
// Begin timer
|
392
|
long before = System.currentTimeMillis();
|
393
|
|
394
|
// if either the point or polygon shape files do not exist, then regenerate the entire spatial cache
|
395
|
// this may be expensive with many documents
|
396
|
SpatialHarvester sh = new SpatialHarvester();
|
397
|
sh.regenerate();
|
398
|
sh.destroy();
|
399
|
|
400
|
// After running the first time, we want to to set
|
401
|
// regenerateCacheOnRestart to false
|
402
|
// so that it does not regenerate the cache every time tomcat is
|
403
|
// restarted
|
404
|
PropertyService.setProperty("spatial.regenerateCacheOnRestart", "false");
|
405
|
|
406
|
// End timer
|
407
|
long after = System.currentTimeMillis();
|
408
|
logMetacat.info("MetaCatServlet.initSecondHalf - Spatial Harvester Time "
|
409
|
+ (after - before) + "ms");
|
410
|
|
411
|
} else {
|
412
|
logMetacat.info("MetaCatServlet.initSecondHalf - Spatial cache is not set to regenerate on restart");
|
413
|
}
|
414
|
|
415
|
// Set up the replication log file by setting the "replication.logfile.name"
|
416
|
// system property and reconfiguring the log4j property configurator.
|
417
|
String replicationLogPath = PropertyService.getProperty("replication.logdir")
|
418
|
+ FileUtil.getFS() + ReplicationService.REPLICATION_LOG_FILE_NAME;
|
419
|
|
420
|
if (FileUtil.getFileStatus(replicationLogPath) == FileUtil.DOES_NOT_EXIST) {
|
421
|
FileUtil.createFile(replicationLogPath);
|
422
|
}
|
423
|
|
424
|
if (FileUtil.getFileStatus(replicationLogPath) < FileUtil.EXISTS_READ_WRITABLE) {
|
425
|
logMetacat.error("MetaCatServlet.initSecondHalf - Replication log file: " + replicationLogPath
|
426
|
+ " does not exist read/writable.");
|
427
|
}
|
428
|
|
429
|
System.setProperty("replication.logfile.name", replicationLogPath);
|
430
|
PropertyConfigurator.configureAndWatch(LOG_CONFIG_NAME);
|
431
|
|
432
|
SessionService.getInstance().unRegisterAllSessions();
|
433
|
|
434
|
//Initialize Metacat Handler
|
435
|
handler = new MetacatHandler(timer);
|
436
|
|
437
|
handler.set_sitemapScheduled(false);
|
438
|
|
439
|
// initialize the plugins
|
440
|
MetacatHandlerPluginManager.getInstance();
|
441
|
|
442
|
// initialize the HazelcastService
|
443
|
ServiceService.registerService("HazelcastService", HazelcastService.getInstance());
|
444
|
|
445
|
_fullyInitialized = true;
|
446
|
|
447
|
logMetacat.warn("MetaCatServlet.initSecondHalf - Metacat (" + MetacatVersion.getVersionID()
|
448
|
+ ") initialized.");
|
449
|
|
450
|
} catch (SQLException e) {
|
451
|
String errorMessage = "SQL problem while intializing MetaCat Servlet: "
|
452
|
+ e.getMessage();
|
453
|
logMetacat.error("MetaCatServlet.initSecondHalf - " + errorMessage);
|
454
|
throw new ServletException(errorMessage);
|
455
|
} catch (IOException ie) {
|
456
|
String errorMessage = "IO problem while intializing MetaCat Servlet: "
|
457
|
+ ie.getMessage();
|
458
|
logMetacat.error("MetaCatServlet.initSecondHalf - " + errorMessage);
|
459
|
throw new ServletException(errorMessage);
|
460
|
} catch (GeneralPropertyException gpe) {
|
461
|
String errorMessage = "Could not retrieve property while intializing MetaCat Servlet: "
|
462
|
+ gpe.getMessage();
|
463
|
logMetacat.error("MetaCatServlet.initSecondHalf - " + errorMessage);
|
464
|
throw new ServletException(errorMessage);
|
465
|
} catch (ServiceException se) {
|
466
|
String errorMessage = "Service problem while intializing MetaCat Servlet: "
|
467
|
+ se.getMessage();
|
468
|
logMetacat.error("MetaCatServlet.initSecondHalf - " + errorMessage);
|
469
|
throw new ServletException(errorMessage);
|
470
|
} catch (UtilException ue) {
|
471
|
String errorMessage = "Utility problem while intializing MetaCat Servlet: "
|
472
|
+ ue.getMessage();
|
473
|
logMetacat.error("MetaCatServlet.initSecondHalf - " + errorMessage);
|
474
|
throw new ServletException(errorMessage);
|
475
|
}
|
476
|
}
|
477
|
|
478
|
/**
|
479
|
* Close all db connections from the pool
|
480
|
*/
|
481
|
public void destroy() {
|
482
|
Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
|
483
|
|
484
|
ServiceService.stopAllServices();
|
485
|
|
486
|
// Close all db connection
|
487
|
logMetacat.warn("MetaCatServlet.destroy - Destroying MetacatServlet");
|
488
|
timer.cancel();
|
489
|
IndexingQueue.getInstance().setMetacatRunning(false);
|
490
|
DBConnectionPool.release();
|
491
|
}
|
492
|
|
493
|
/** Handle "GET" method requests from HTTP clients */
|
494
|
public void doGet(HttpServletRequest request, HttpServletResponse response)
|
495
|
throws ServletException, IOException {
|
496
|
|
497
|
// Process the data and send back the response
|
498
|
handleGetOrPost(request, response);
|
499
|
}
|
500
|
|
501
|
/** Handle "POST" method requests from HTTP clients */
|
502
|
public void doPost(HttpServletRequest request, HttpServletResponse response)
|
503
|
throws ServletException, IOException {
|
504
|
|
505
|
// Process the data and send back the response
|
506
|
handleGetOrPost(request, response);
|
507
|
}
|
508
|
|
509
|
/**
|
510
|
* Index the paths specified in the metacat.properties
|
511
|
*/
|
512
|
private void checkIndexPaths() {
|
513
|
Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
|
514
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - starting....");
|
515
|
if(!EnabledQueryEngines.getInstance().isEnabled(EnabledQueryEngines.PATHQUERYENGINE)) {
|
516
|
logMetacat.info("MetaCatServlet.checkIndexPaths - the pathquery is disabled and it does nothing for checking path_index");
|
517
|
return;
|
518
|
}
|
519
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - after checking is the pathquery enabled or not...");
|
520
|
|
521
|
|
522
|
Vector<String> pathsForIndexing = null;
|
523
|
try {
|
524
|
pathsForIndexing = SystemUtil.getPathsForIndexing();
|
525
|
}
|
526
|
catch (MetacatUtilException ue) {
|
527
|
pathsForIndexing = null;
|
528
|
logMetacat.error("MetaCatServlet.checkIndexPaths - not find index paths. Setting "
|
529
|
+ "pathsForIndexing to null: " + ue.getMessage());
|
530
|
}
|
531
|
|
532
|
if (pathsForIndexing != null && !pathsForIndexing.isEmpty()) {
|
533
|
|
534
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - Indexing paths specified in metacat.properties....");
|
535
|
|
536
|
DBConnection conn = null;
|
537
|
int serialNumber = -1;
|
538
|
PreparedStatement pstmt = null;
|
539
|
PreparedStatement pstmt1 = null;
|
540
|
ResultSet rs = null;
|
541
|
|
542
|
for (String pathIndex : pathsForIndexing) {
|
543
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - Checking if '" + pathIndex + "' is indexed.... ");
|
544
|
|
545
|
try {
|
546
|
//check out DBConnection
|
547
|
conn = DBConnectionPool.
|
548
|
getDBConnection("MetaCatServlet.checkIndexPaths");
|
549
|
serialNumber = conn.getCheckOutSerialNumber();
|
550
|
|
551
|
pstmt = conn.prepareStatement(
|
552
|
"SELECT * FROM xml_path_index " + "WHERE path = ?");
|
553
|
pstmt.setString(1, pathIndex);
|
554
|
|
555
|
pstmt.execute();
|
556
|
rs = pstmt.getResultSet();
|
557
|
|
558
|
if (!rs.next()) {
|
559
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - not indexed yet.");
|
560
|
rs.close();
|
561
|
pstmt.close();
|
562
|
conn.increaseUsageCount(1);
|
563
|
|
564
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - Inserting following path in xml_path_index: "
|
565
|
+ pathIndex);
|
566
|
if(pathIndex.indexOf("@")<0){
|
567
|
pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
|
568
|
+ "n.nodedata, n.nodedatanumerical, n.nodedatadate, n.parentnodeid"
|
569
|
+ " FROM xml_nodes n, xml_index i WHERE"
|
570
|
+ " i.path = ? and n.parentnodeid=i.nodeid and"
|
571
|
+ " n.nodetype LIKE 'TEXT' order by n.parentnodeid");
|
572
|
} else {
|
573
|
pstmt = conn.prepareStatement("SELECT DISTINCT n.docid, "
|
574
|
+ "n.nodedata, n.nodedatanumerical, n.nodedatadate, n.parentnodeid"
|
575
|
+ " FROM xml_nodes n, xml_index i WHERE"
|
576
|
+ " i.path = ? and n.nodeid=i.nodeid and"
|
577
|
+ " n.nodetype LIKE 'ATTRIBUTE' order by n.parentnodeid");
|
578
|
}
|
579
|
pstmt.setString(1, pathIndex);
|
580
|
pstmt.execute();
|
581
|
rs = pstmt.getResultSet();
|
582
|
|
583
|
int count = 0;
|
584
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - Executed the select statement for: "
|
585
|
+ pathIndex);
|
586
|
|
587
|
try {
|
588
|
while (rs.next()) {
|
589
|
|
590
|
String docid = rs.getString(1);
|
591
|
String nodedata = rs.getString(2);
|
592
|
float nodedatanumerical = rs.getFloat(3);
|
593
|
Timestamp nodedatadate = rs.getTimestamp(4);
|
594
|
int parentnodeid = rs.getInt(5);
|
595
|
|
596
|
if (!nodedata.trim().equals("")) {
|
597
|
pstmt1 = conn.prepareStatement(
|
598
|
"INSERT INTO xml_path_index"
|
599
|
+ " (docid, path, nodedata, "
|
600
|
+ "nodedatanumerical, nodedatadate, parentnodeid)"
|
601
|
+ " VALUES (?, ?, ?, ?, ?, ?)");
|
602
|
|
603
|
pstmt1.setString(1, docid);
|
604
|
pstmt1.setString(2, pathIndex);
|
605
|
pstmt1.setString(3, nodedata);
|
606
|
pstmt1.setFloat(4, nodedatanumerical);
|
607
|
pstmt1.setTimestamp(5, nodedatadate);
|
608
|
pstmt1.setInt(6, parentnodeid);
|
609
|
|
610
|
pstmt1.execute();
|
611
|
pstmt1.close();
|
612
|
|
613
|
count++;
|
614
|
|
615
|
}
|
616
|
}
|
617
|
} catch (Exception e) {
|
618
|
logMetacat.error("MetaCatServlet.checkIndexPaths - Exception:" + e.getMessage());
|
619
|
e.printStackTrace();
|
620
|
}
|
621
|
|
622
|
rs.close();
|
623
|
pstmt.close();
|
624
|
conn.increaseUsageCount(1);
|
625
|
|
626
|
logMetacat.info("MetaCatServlet.checkIndexPaths - Indexed " + count + " records from xml_nodes for '"
|
627
|
+ pathIndex + "'");
|
628
|
|
629
|
} else {
|
630
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - already indexed.");
|
631
|
}
|
632
|
|
633
|
rs.close();
|
634
|
pstmt.close();
|
635
|
conn.increaseUsageCount(1);
|
636
|
|
637
|
} catch (Exception e) {
|
638
|
logMetacat.error("MetaCatServlet.checkIndexPaths - Error in MetaCatServlet.checkIndexPaths: "
|
639
|
+ e.getMessage());
|
640
|
}finally {
|
641
|
//check in DBonnection
|
642
|
DBConnectionPool.returnDBConnection(conn, serialNumber);
|
643
|
}
|
644
|
|
645
|
|
646
|
}
|
647
|
|
648
|
logMetacat.debug("MetaCatServlet.checkIndexPaths - Path Indexing Completed");
|
649
|
}
|
650
|
}
|
651
|
|
652
|
/**
|
653
|
* Control servlet response depending on the action parameter specified
|
654
|
*/
|
655
|
@SuppressWarnings("unchecked")
|
656
|
private void handleGetOrPost(HttpServletRequest request,
|
657
|
HttpServletResponse response) throws ServletException, IOException {
|
658
|
Logger logMetacat = Logger.getLogger(MetaCatServlet.class);
|
659
|
|
660
|
String requestEncoding = request.getCharacterEncoding();
|
661
|
if (requestEncoding == null) {
|
662
|
logMetacat.debug("null requestEncoding, setting to application default: " + DEFAULT_ENCODING);
|
663
|
request.setCharacterEncoding(DEFAULT_ENCODING);
|
664
|
}
|
665
|
logMetacat.debug("requestEncoding: " + requestEncoding);
|
666
|
|
667
|
// Update the last update time for this user if they are not new
|
668
|
HttpSession httpSession = request.getSession(false);
|
669
|
if (httpSession != null) {
|
670
|
SessionService.getInstance().touchSession(httpSession.getId());
|
671
|
}
|
672
|
|
673
|
// Each time metacat is called, check to see if metacat has been
|
674
|
// configured. If not then forward to the administration servlet
|
675
|
if (!ConfigurationUtil.isMetacatConfigured()) {
|
676
|
try {
|
677
|
RequestUtil.forwardRequest(request, response, "/admin?action=configure", null);
|
678
|
return;
|
679
|
} catch (MetacatUtilException mue) {
|
680
|
logMetacat.error("MetacatServlet.handleGetOrPost - utility error when forwarding to " +
|
681
|
"configuration screen: " + mue.getMessage());
|
682
|
throw new ServletException("MetacatServlet.handleGetOrPost - utility error when forwarding to " +
|
683
|
"configuration screen: " + mue.getMessage());
|
684
|
}
|
685
|
}
|
686
|
|
687
|
// if we get here, metacat is configured. If we have not completed the
|
688
|
// second half of the initialization, do so now. This allows us to initially
|
689
|
// configure metacat without a restart.
|
690
|
logMetacat.info("MetacatServlet.handleGetOrPost - the _fullyInitailzied value is "+_fullyInitialized);
|
691
|
if (!_fullyInitialized) {
|
692
|
initSecondHalf(request.getSession().getServletContext());
|
693
|
}
|
694
|
|
695
|
/*
|
696
|
* logMetacat.debug("Connection pool size: "
|
697
|
* +connPool.getSizeOfDBConnectionPool(),10); logMetacat.debug("Free
|
698
|
* DBConnection number: "
|
699
|
*/
|
700
|
// If all DBConnection in the pool are free and DBConnection pool
|
701
|
// size is greater than initial value, shrink the connection pool
|
702
|
// size to initial value
|
703
|
DBConnectionPool.shrinkDBConnectionPoolSize();
|
704
|
|
705
|
// Debug message to print out the method which have a busy DBConnection
|
706
|
try {
|
707
|
@SuppressWarnings("unused")
|
708
|
DBConnectionPool pool = DBConnectionPool.getInstance();
|
709
|
// pool.printMethodNameHavingBusyDBConnection();
|
710
|
} catch (SQLException e) {
|
711
|
logMetacat.error("MetaCatServlet.handleGetOrPost - Error in MetacatServlet.handleGetOrPost: " + e.getMessage());
|
712
|
e.printStackTrace();
|
713
|
}
|
714
|
|
715
|
try {
|
716
|
String ctype = request.getContentType();
|
717
|
|
718
|
if (ctype != null && ctype.startsWith("multipart/form-data")) {
|
719
|
if(isReadOnly(response)) {
|
720
|
return;
|
721
|
}
|
722
|
handler.handleMultipartForm(request, response);
|
723
|
return;
|
724
|
}
|
725
|
|
726
|
String name = null;
|
727
|
String[] value = null;
|
728
|
String[] docid = new String[3];
|
729
|
Hashtable<String, String[]> params = new Hashtable<String, String[]>();
|
730
|
|
731
|
// Check if this is a simple read request that doesn't use the
|
732
|
// "action" syntax
|
733
|
// These URLs are of the form:
|
734
|
// http://localhost:8180/metacat/metacat/docid/skinname
|
735
|
// e.g., http://localhost:8180/metacat/metacat/test.1.1/knb
|
736
|
String pathInfo = request.getPathInfo();
|
737
|
if (pathInfo != null) {
|
738
|
String[] path = pathInfo.split("/");
|
739
|
if (path.length > 1) {
|
740
|
String docidToRead = path[1];
|
741
|
String docs[] = new String[1];
|
742
|
docs[0] = docidToRead;
|
743
|
logMetacat.debug("MetaCatServlet.handleGetOrPost - READING DOCID FROM PATHINFO: " + docs[0]);
|
744
|
params.put("docid", docs);
|
745
|
String skin = null;
|
746
|
if (path.length > 2) {
|
747
|
skin = path[2];
|
748
|
String skins[] = new String[1];
|
749
|
skins[0] = skin;
|
750
|
params.put("qformat", skins);
|
751
|
}
|
752
|
|
753
|
// attempt to redirect to metacatui (#view/{pid}) if not getting the raw XML
|
754
|
// see: https://projects.ecoinformatics.org/ecoinfo/issues/6546
|
755
|
if (!skin.equals("xml")) {
|
756
|
String uiContext = PropertyService.getProperty("ui.context");
|
757
|
String docidNoRev = DocumentUtil.getDocIdFromAccessionNumber(docidToRead);
|
758
|
int rev = DocumentUtil.getRevisionFromAccessionNumber(docidToRead);
|
759
|
String pid = null;
|
760
|
try {
|
761
|
pid = IdentifierManager.getInstance().getGUID(docidNoRev, rev);
|
762
|
response.sendRedirect(SystemUtil.getServerURL() + "/" + uiContext + "/#view/" + pid );
|
763
|
return;
|
764
|
} catch (McdbDocNotFoundException nfe) {
|
765
|
logMetacat.warn("Could not locate PID for docid: " + docidToRead, nfe);
|
766
|
}
|
767
|
}
|
768
|
|
769
|
// otherwise carry on as usual
|
770
|
handler.handleReadAction(params, request, response, "public", null, null);
|
771
|
return;
|
772
|
}
|
773
|
}
|
774
|
|
775
|
Enumeration<String> paramlist =
|
776
|
(Enumeration<String>) request.getParameterNames();
|
777
|
while (paramlist.hasMoreElements()) {
|
778
|
|
779
|
name = paramlist.nextElement();
|
780
|
value = request.getParameterValues(name);
|
781
|
|
782
|
// Decode the docid and mouse click information
|
783
|
// THIS IS OBSOLETE -- I THINK -- REMOVE THIS BLOCK
|
784
|
// 4/12/2007d
|
785
|
// MBJ
|
786
|
if (name.endsWith(".y")) {
|
787
|
docid[0] = name.substring(0, name.length() - 2);
|
788
|
params.put("docid", docid);
|
789
|
name = "ypos";
|
790
|
}
|
791
|
if (name.endsWith(".x")) {
|
792
|
name = "xpos";
|
793
|
}
|
794
|
|
795
|
params.put(name, value);
|
796
|
}
|
797
|
|
798
|
// handle param is emptpy
|
799
|
if (params.isEmpty() || params == null) {
|
800
|
return;
|
801
|
}
|
802
|
|
803
|
// if the user clicked on the input images, decode which image
|
804
|
// was clicked then set the action.
|
805
|
if (params.get("action") == null) {
|
806
|
PrintWriter out = response.getWriter();
|
807
|
response.setContentType("text/xml");
|
808
|
out.println("<?xml version=\"1.0\"?>");
|
809
|
out.println("<error>");
|
810
|
out.println("Action not specified");
|
811
|
out.println("</error>");
|
812
|
out.close();
|
813
|
return;
|
814
|
}
|
815
|
|
816
|
String action = (params.get("action"))[0];
|
817
|
logMetacat.info("MetaCatServlet.handleGetOrPost - Action is: " + action);
|
818
|
|
819
|
// This block handles session management for the servlet
|
820
|
// by looking up the current session information for all actions
|
821
|
// other than "login" and "logout"
|
822
|
String userName = null;
|
823
|
String password = null;
|
824
|
String[] groupNames = null;
|
825
|
String sessionId = null;
|
826
|
name = null;
|
827
|
|
828
|
// handle login action
|
829
|
if (action.equals("login")) {
|
830
|
//PrintWriter out = response.getWriter();
|
831
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
832
|
handler.handleLoginAction(out, params, request, response);
|
833
|
out.close();
|
834
|
|
835
|
// handle logout action
|
836
|
} else if (action.equals("logout")) {
|
837
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
838
|
handler.handleLogoutAction(out, params, request, response);
|
839
|
out.close();
|
840
|
|
841
|
// handle session validate request
|
842
|
} else if (action.equals("validatesession")) {
|
843
|
String token = request.getHeader("Authorization");
|
844
|
|
845
|
// First check for a valid authentication token
|
846
|
if ( token != null && ! token.equals("") ) {
|
847
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
848
|
SessionData sessionData = RequestUtil.getSessionData(request);
|
849
|
|
850
|
response.setContentType("text/xml");
|
851
|
out.write("<?xml version=\"1.0\"?>");
|
852
|
out.write("<validateSession><status>");
|
853
|
|
854
|
if ( sessionData != null ) {
|
855
|
out.write("valid");
|
856
|
|
857
|
} else {
|
858
|
out.write("invalid");
|
859
|
|
860
|
}
|
861
|
out.write("</status>");
|
862
|
|
863
|
if (sessionData != null) {
|
864
|
out.write("<userInformation>");
|
865
|
out.write("<name>");
|
866
|
out.write(sessionData.getUserName());
|
867
|
out.write("</name>");
|
868
|
out.write("<fullName>");
|
869
|
out.write(sessionData.getName());
|
870
|
out.write("</fullName>");
|
871
|
String[] groups = sessionData.getGroupNames();
|
872
|
if ( groups != null ) {
|
873
|
for(String groupName : groups) {
|
874
|
out.write("<group>");
|
875
|
out.write(groupName);
|
876
|
out.write("</group>");
|
877
|
}
|
878
|
}
|
879
|
out.write("</userInformation>");
|
880
|
}
|
881
|
|
882
|
out.write("<sessionId>" + sessionId + "</sessionId></validateSession>");
|
883
|
out.close();
|
884
|
|
885
|
} else {
|
886
|
// With no token, validate the sessionid
|
887
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
888
|
String idToValidate = null;
|
889
|
String idsToValidate[] = params.get("sessionid");
|
890
|
if (idsToValidate != null) {
|
891
|
idToValidate = idsToValidate[0];
|
892
|
|
893
|
} else {
|
894
|
// use the sessionid from the cookie
|
895
|
SessionData sessionData = RequestUtil.getSessionData(request);
|
896
|
if (sessionData != null) {
|
897
|
idToValidate = sessionData.getId();
|
898
|
|
899
|
}
|
900
|
}
|
901
|
SessionService.getInstance().validateSession(out, response, idToValidate);
|
902
|
out.close();
|
903
|
}
|
904
|
|
905
|
// aware of session expiration on every request
|
906
|
} else {
|
907
|
SessionData sessionData = RequestUtil.getSessionData(request);
|
908
|
|
909
|
if (sessionData != null) {
|
910
|
userName = sessionData.getUserName();
|
911
|
password = sessionData.getPassword();
|
912
|
groupNames = sessionData.getGroupNames();
|
913
|
sessionId = sessionData.getId();
|
914
|
}
|
915
|
|
916
|
logMetacat.info("MetaCatServlet.handleGetOrPost - The user is : " + userName);
|
917
|
}
|
918
|
|
919
|
// Now that we know the session is valid, we can delegate the
|
920
|
// request to a particular action handler
|
921
|
if (action.equals("query")) {
|
922
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
923
|
handler.handleQuery(out, params, response, userName, groupNames, sessionId);
|
924
|
out.close();
|
925
|
} else if (action.equals("squery")) {
|
926
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
927
|
if (params.containsKey("query")) {
|
928
|
handler.handleSQuery(out, params, response, userName, groupNames, sessionId);
|
929
|
out.close();
|
930
|
} else {
|
931
|
out.write("Illegal action squery without \"query\" parameter");
|
932
|
out.close();
|
933
|
}
|
934
|
} else if (action.trim().equals("spatial_query")) {
|
935
|
|
936
|
logMetacat
|
937
|
.debug("MetaCatServlet.handleGetOrPost - ******************* SPATIAL QUERY ********************");
|
938
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
939
|
handler.handleSpatialQuery(out, params, response, userName, groupNames, sessionId);
|
940
|
out.close();
|
941
|
|
942
|
} else if (action.trim().equals("dataquery")) {
|
943
|
|
944
|
logMetacat.debug("MetaCatServlet.handleGetOrPost - ******************* DATA QUERY ********************");
|
945
|
handler.handleDataquery(params, response, sessionId);
|
946
|
} else if (action.trim().equals("editcart")) {
|
947
|
logMetacat.debug("MetaCatServlet.handleGetOrPost - ******************* EDIT CART ********************");
|
948
|
handler.handleEditCart(params, response, sessionId);
|
949
|
} else if (action.equals("export")) {
|
950
|
|
951
|
handler.handleExportAction(params, response, userName, groupNames, password);
|
952
|
} else if (action.equals("read")) {
|
953
|
if (params.get("archiveEntryName") != null) {
|
954
|
ArchiveHandler.getInstance().readArchiveEntry(params, request,
|
955
|
response, userName, password, groupNames);
|
956
|
} else {
|
957
|
handler.handleReadAction(params, request, response, userName, password,
|
958
|
groupNames);
|
959
|
}
|
960
|
} else if (action.equals("readinlinedata")) {
|
961
|
handler.handleReadInlineDataAction(params, request, response, userName, password,
|
962
|
groupNames);
|
963
|
} else if (action.equals("insert") || action.equals("update")) {
|
964
|
if(isReadOnly(response)) {
|
965
|
return;
|
966
|
}
|
967
|
PrintWriter out = response.getWriter();
|
968
|
if ((userName != null) && !userName.equals("public")) {
|
969
|
//formatid will be set null here since this is metacat api
|
970
|
String formatId = null;
|
971
|
handler.handleInsertOrUpdateAction(request.getRemoteAddr(), request.getHeader("User-Agent"), response, out, params, userName,
|
972
|
groupNames, true, true, null, formatId);
|
973
|
} else {
|
974
|
response.setContentType("text/xml");
|
975
|
out.println("<?xml version=\"1.0\"?>");
|
976
|
out.println("<error>");
|
977
|
String cleanMessage = StringEscapeUtils.escapeXml("Permission denied for user " + userName + " " + action);
|
978
|
out.println(cleanMessage);
|
979
|
out.println("</error>");
|
980
|
}
|
981
|
out.close();
|
982
|
} else if (action.equals("delete")) {
|
983
|
if(isReadOnly(response)) {
|
984
|
return;
|
985
|
}
|
986
|
PrintWriter out = response.getWriter();
|
987
|
if ((userName != null) && !userName.equals("public")) {
|
988
|
handler.handleDeleteAction(out, params, request, response, userName,
|
989
|
groupNames);
|
990
|
} else {
|
991
|
response.setContentType("text/xml");
|
992
|
out.println("<?xml version=\"1.0\"?>");
|
993
|
out.println("<error>");
|
994
|
String cleanMessage = StringEscapeUtils.escapeXml("Permission denied for " + action);
|
995
|
out.println(cleanMessage);
|
996
|
out.println("</error>");
|
997
|
}
|
998
|
out.close();
|
999
|
} else if (action.equals("validate")) {
|
1000
|
PrintWriter out = response.getWriter();
|
1001
|
handler.handleValidateAction(out, params);
|
1002
|
out.close();
|
1003
|
} else if (action.equals("setaccess")) {
|
1004
|
if(isReadOnly(response)) {
|
1005
|
return;
|
1006
|
}
|
1007
|
PrintWriter out = response.getWriter();
|
1008
|
handler.handleSetAccessAction(out, params, userName, request, response);
|
1009
|
out.close();
|
1010
|
} else if (action.equals("getaccesscontrol")) {
|
1011
|
PrintWriter out = response.getWriter();
|
1012
|
handler.handleGetAccessControlAction(out, params, response, userName, groupNames);
|
1013
|
out.close();
|
1014
|
} else if (action.equals("isauthorized")) {
|
1015
|
PrintWriter out = response.getWriter();
|
1016
|
DocumentUtil.isAuthorized(out, params, request, response);
|
1017
|
out.close();
|
1018
|
} else if (action.equals("getprincipals")) {
|
1019
|
Writer out = new OutputStreamWriter(response.getOutputStream(), DEFAULT_ENCODING);
|
1020
|
handler.handleGetPrincipalsAction(out, userName, password);
|
1021
|
out.close();
|
1022
|
} else if (action.equals("getdoctypes")) {
|
1023
|
PrintWriter out = response.getWriter();
|
1024
|
handler.handleGetDoctypesAction(out, params, response);
|
1025
|
out.close();
|
1026
|
} else if (action.equals("getdtdschema")) {
|
1027
|
PrintWriter out = response.getWriter();
|
1028
|
handler.handleGetDTDSchemaAction(out, params, response);
|
1029
|
out.close();
|
1030
|
} else if (action.equals("getdocid")) {
|
1031
|
handler.handleGetDocid(params, response);
|
1032
|
} else if (action.equals("getlastdocid")) {
|
1033
|
PrintWriter out = response.getWriter();
|
1034
|
handler.handleGetMaxDocidAction(out, params, response);
|
1035
|
out.close();
|
1036
|
} else if (action.equals("getalldocids")) {
|
1037
|
PrintWriter out = response.getWriter();
|
1038
|
handler.handleGetAllDocidsAction(out, params, response);
|
1039
|
out.close();
|
1040
|
} else if (action.equals("isregistered")) {
|
1041
|
PrintWriter out = response.getWriter();
|
1042
|
handler.handleIdIsRegisteredAction(out, params, response);
|
1043
|
out.close();
|
1044
|
} else if (action.equals("getrevisionanddoctype")) {
|
1045
|
PrintWriter out = response.getWriter();
|
1046
|
handler.handleGetRevisionAndDocTypeAction(out, params);
|
1047
|
out.close();
|
1048
|
} else if (action.equals("getversion")) {
|
1049
|
response.setContentType("text/xml");
|
1050
|
PrintWriter out = response.getWriter();
|
1051
|
out.println(MetacatVersion.getVersionAsXml());
|
1052
|
out.close();
|
1053
|
} else if (action.equals("getlog")) {
|
1054
|
handler.handleGetLogAction(params, request, response, userName, groupNames, sessionId);
|
1055
|
} else if (action.equals("getloggedinuserinfo")) {
|
1056
|
PrintWriter out = response.getWriter();
|
1057
|
response.setContentType("text/xml");
|
1058
|
out.println("<?xml version=\"1.0\"?>");
|
1059
|
out.println("\n<user>\n");
|
1060
|
out.println("\n<username>\n");
|
1061
|
out.println(userName);
|
1062
|
out.println("\n</username>\n");
|
1063
|
if (name != null) {
|
1064
|
out.println("\n<name>\n");
|
1065
|
out.println(name);
|
1066
|
out.println("\n</name>\n");
|
1067
|
}
|
1068
|
if (AuthUtil.isAdministrator(userName, groupNames)) {
|
1069
|
out.println("<isAdministrator></isAdministrator>\n");
|
1070
|
}
|
1071
|
if (AuthUtil.isModerator(userName, groupNames)) {
|
1072
|
out.println("<isModerator></isModerator>\n");
|
1073
|
}
|
1074
|
out.println("\n</user>\n");
|
1075
|
out.close();
|
1076
|
} else if (action.equals("buildindex")) {
|
1077
|
if(isReadOnly(response)) {
|
1078
|
return;
|
1079
|
}
|
1080
|
handler.handleBuildIndexAction(params, request, response, userName, groupNames);
|
1081
|
} else if (action.equals("reindex")) {
|
1082
|
if(isReadOnly(response)) {
|
1083
|
return;
|
1084
|
}
|
1085
|
handler.handleReindexAction(params, request, response, userName, groupNames);
|
1086
|
} else if (action.equals("reindexall")) {
|
1087
|
if(isReadOnly(response)) {
|
1088
|
return;
|
1089
|
}
|
1090
|
handler.handleReindexAllAction(params, request, response, userName, groupNames);
|
1091
|
} else if (action.equals("login") || action.equals("logout")) {
|
1092
|
/*
|
1093
|
* } else if (action.equals("protocoltest")) { String testURL =
|
1094
|
* "metacat://dev.nceas.ucsb.edu/NCEAS.897766.9"; try { testURL =
|
1095
|
* ((String[]) params.get("url"))[0]; } catch (Throwable t) { }
|
1096
|
* String phandler = System
|
1097
|
* .getProperty("java.protocol.handler.pkgs");
|
1098
|
* response.setContentType("text/html"); PrintWriter out =
|
1099
|
* response.getWriter(); out.println("<body
|
1100
|
* bgcolor=\"white\">"); out.println("<p>Handler property:
|
1101
|
* <code>" + phandler + "</code></p>"); out.println("<p>Starting
|
1102
|
* test for:<br>"); out.println(" " + testURL + "</p>"); try {
|
1103
|
* URL u = new URL(testURL); out.println("<pre>");
|
1104
|
* out.println("Protocol: " + u.getProtocol()); out.println("
|
1105
|
* Host: " + u.getHost()); out.println(" Port: " + u.getPort());
|
1106
|
* out.println(" Path: " + u.getPath()); out.println(" Ref: " +
|
1107
|
* u.getRef()); String pquery = u.getQuery(); out.println("
|
1108
|
* Query: " + pquery); out.println(" Params: "); if (pquery !=
|
1109
|
* null) { Hashtable qparams =
|
1110
|
* MetacatUtil.parseQuery(u.getQuery()); for (Enumeration en =
|
1111
|
* qparams.keys(); en .hasMoreElements();) { String pname =
|
1112
|
* (String) en.nextElement(); String pvalue = (String)
|
1113
|
* qparams.get(pname); out.println(" " + pname + ": " + pvalue); } }
|
1114
|
* out.println("</pre>"); out.println("</body>");
|
1115
|
* out.close(); } catch (MalformedURLException mue) {
|
1116
|
* System.out.println( "bad url from
|
1117
|
* MetacatServlet.handleGetOrPost");
|
1118
|
* out.println(mue.getMessage()); mue.printStackTrace(out);
|
1119
|
* out.close(); }
|
1120
|
*/
|
1121
|
} else if (action.equals("refreshServices")) {
|
1122
|
// TODO MCD this interface is for testing. It should go through
|
1123
|
// a ServiceService class and only work for an admin user. Move
|
1124
|
// to the MetacatAdminServlet
|
1125
|
ServiceService.refreshService("XMLSchemaService");
|
1126
|
return;
|
1127
|
} else if (action.equals("scheduleWorkflow")) {
|
1128
|
if(isReadOnly(response)) {
|
1129
|
return;
|
1130
|
}
|
1131
|
try {
|
1132
|
WorkflowSchedulerClient.getInstance().scheduleJob(request, response,
|
1133
|
params, userName, groupNames);
|
1134
|
return;
|
1135
|
} catch (BaseException be) {
|
1136
|
ResponseUtil.sendErrorXML(response,
|
1137
|
ResponseUtil.SCHEDULE_WORKFLOW_ERROR, be);
|
1138
|
return;
|
1139
|
}
|
1140
|
} else if (action.equals("unscheduleWorkflow")) {
|
1141
|
if(isReadOnly(response)) {
|
1142
|
return;
|
1143
|
}
|
1144
|
try {
|
1145
|
WorkflowSchedulerClient.getInstance().unScheduleJob(request,
|
1146
|
response, params, userName, groupNames);
|
1147
|
return;
|
1148
|
} catch (BaseException be) {
|
1149
|
ResponseUtil.sendErrorXML(response,
|
1150
|
ResponseUtil.UNSCHEDULE_WORKFLOW_ERROR, be);
|
1151
|
return;
|
1152
|
}
|
1153
|
} else if (action.equals("rescheduleWorkflow")) {
|
1154
|
if(isReadOnly(response)) {
|
1155
|
return;
|
1156
|
}
|
1157
|
try {
|
1158
|
WorkflowSchedulerClient.getInstance().reScheduleJob(request,
|
1159
|
response, params, userName, groupNames);
|
1160
|
return;
|
1161
|
} catch (BaseException be) {
|
1162
|
ResponseUtil.sendErrorXML(response,
|
1163
|
ResponseUtil.RESCHEDULE_WORKFLOW_ERROR, be);
|
1164
|
return;
|
1165
|
}
|
1166
|
} else if (action.equals("getScheduledWorkflow")) {
|
1167
|
try {
|
1168
|
WorkflowSchedulerClient.getInstance().getJobs(request, response,
|
1169
|
params, userName, groupNames);
|
1170
|
return;
|
1171
|
} catch (BaseException be) {
|
1172
|
ResponseUtil.sendErrorXML(response,
|
1173
|
ResponseUtil.GET_SCHEDULED_WORKFLOW_ERROR, be);
|
1174
|
return;
|
1175
|
}
|
1176
|
} else if (action.equals("deleteScheduledWorkflow")) {
|
1177
|
if(isReadOnly(response)) {
|
1178
|
return;
|
1179
|
}
|
1180
|
try {
|
1181
|
WorkflowSchedulerClient.getInstance().deleteJob(request, response,
|
1182
|
params, userName, groupNames);
|
1183
|
return;
|
1184
|
} catch (BaseException be) {
|
1185
|
ResponseUtil.sendErrorXML(response,
|
1186
|
ResponseUtil.DELETE_SCHEDULED_WORKFLOW_ERROR, be);
|
1187
|
return;
|
1188
|
}
|
1189
|
} else if (action.equals("shrink")) {
|
1190
|
// handle shrink DBConnection request
|
1191
|
PrintWriter out = response.getWriter();
|
1192
|
if(!AuthUtil.isAdministrator(userName, groupNames)){
|
1193
|
out.println("The user "+userName+ " is not the administrator of the Metacat and doesn't have the permission to call the method.");
|
1194
|
out.close();
|
1195
|
return;
|
1196
|
}
|
1197
|
boolean success = false;
|
1198
|
// If all DBConnection in the pool are free and DBConnection
|
1199
|
// pool
|
1200
|
// size is greater than initial value, shrink the connection
|
1201
|
// pool
|
1202
|
// size to initial value
|
1203
|
success = DBConnectionPool.shrinkConnectionPoolSize();
|
1204
|
if (success) {
|
1205
|
// if successfully shrink the pool size to initial value
|
1206
|
out.println("DBConnection Pool shrunk successfully.");
|
1207
|
}// if
|
1208
|
else {
|
1209
|
out.println("DBConnection pool did not shrink successfully.");
|
1210
|
}
|
1211
|
// close out put
|
1212
|
out.close();
|
1213
|
} else {
|
1214
|
//try the plugin handler if it has an entry for handling this action
|
1215
|
MetacatHandlerPlugin handlerPlugin = MetacatHandlerPluginManager.getInstance().getHandler(action);
|
1216
|
if (handlerPlugin != null) {
|
1217
|
if(isReadOnly(response)) {
|
1218
|
return;
|
1219
|
}
|
1220
|
handlerPlugin.handleAction(action, params, request, response, userName, groupNames, sessionId);
|
1221
|
}
|
1222
|
else {
|
1223
|
PrintWriter out = response.getWriter();
|
1224
|
out.println("<?xml version=\"1.0\"?>");
|
1225
|
out.println("<error>");
|
1226
|
String cleanMessage = StringEscapeUtils.escapeXml("Error: action: " + action + " not registered. Please report this error.");
|
1227
|
out.println(cleanMessage);
|
1228
|
out.println("</error>");
|
1229
|
out.close();
|
1230
|
}
|
1231
|
}
|
1232
|
|
1233
|
// Schedule the sitemap generator to run periodically
|
1234
|
handler.scheduleSitemapGeneration(request);
|
1235
|
|
1236
|
|
1237
|
} catch (PropertyNotFoundException pnfe) {
|
1238
|
String errorString = "Critical property not found: " + pnfe.getMessage();
|
1239
|
logMetacat.error("MetaCatServlet.handleGetOrPost - " + errorString);
|
1240
|
throw new ServletException(errorString);
|
1241
|
} catch (MetacatUtilException ue) {
|
1242
|
String errorString = "Utility error: " + ue.getMessage();
|
1243
|
logMetacat.error("MetaCatServlet.handleGetOrPost - " + errorString);
|
1244
|
throw new ServletException(errorString);
|
1245
|
} catch (ServiceException ue) {
|
1246
|
String errorString = "Service error: " + ue.getMessage();
|
1247
|
logMetacat.error("MetaCatServlet.handleGetOrPost - " + errorString);
|
1248
|
throw new ServletException(errorString);
|
1249
|
} catch (HandlerException he) {
|
1250
|
String errorString = "Handler error: " + he.getMessage();
|
1251
|
logMetacat.error("MetaCatServlet.handleGetOrPost - " + errorString);
|
1252
|
throw new ServletException(errorString);
|
1253
|
} catch (ErrorSendingErrorException esee) {
|
1254
|
String errorString = "Error sending error message: " + esee.getMessage();
|
1255
|
logMetacat.error("MetaCatServlet.handleGetOrPost - " + errorString);
|
1256
|
throw new ServletException(errorString);
|
1257
|
} catch (ErrorHandledException ehe) {
|
1258
|
// Nothing to do here. We assume if we get here, the error has been
|
1259
|
// written to ouput. Continue on and let it display.
|
1260
|
}
|
1261
|
}
|
1262
|
|
1263
|
/**
|
1264
|
* Reports whether the MetaCatServlet has been fully initialized
|
1265
|
*
|
1266
|
* @return true if fully intialized, false otherwise
|
1267
|
*/
|
1268
|
public static boolean isFullyInitialized() {
|
1269
|
return _fullyInitialized;
|
1270
|
}
|
1271
|
|
1272
|
public static boolean isReadOnly(HttpServletResponse response) throws IOException {
|
1273
|
boolean readOnly = false;
|
1274
|
ReadOnlyChecker checker = new ReadOnlyChecker();
|
1275
|
readOnly = checker.isReadOnly();
|
1276
|
if(readOnly) {
|
1277
|
PrintWriter out = response.getWriter();
|
1278
|
response.setContentType("text/xml");
|
1279
|
out.println("<?xml version=\"1.0\"?>");
|
1280
|
out.println("<error>");
|
1281
|
out.println("The Metacat is on the read-only mode and your request can't be fulfiled. Please try again later.");
|
1282
|
out.println("</error>");
|
1283
|
out.close();
|
1284
|
}
|
1285
|
return readOnly;
|
1286
|
}
|
1287
|
}
|