Project

General

Profile

1 2096 jones
/**
2
 *  '$RCSfile$'
3
 *  Copyright: 2004 Regents of the University of California and the
4
 *             National Center for Ecological Analysis and Synthesis
5
 *
6
 *   '$Author$'
7
 *     '$Date$'
8
 * '$Revision$'
9
 *
10
 * This program is free software; you can redistribute it and/or modify
11
 * it under the terms of the GNU General Public License as published by
12
 * the Free Software Foundation; either version 2 of the License, or
13
 * (at your option) any later version.
14
 *
15
 * This program is distributed in the hope that it will be useful,
16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 * GNU General Public License for more details.
19
 *
20
 * You should have received a copy of the GNU General Public License
21
 * along with this program; if not, write to the Free Software
22
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
 */
24
package edu.ucsb.nceas.metacat;
25
26 2104 jones
import java.sql.PreparedStatement;
27 2111 jones
import java.sql.ResultSet;
28 2096 jones
import java.sql.SQLException;
29 2104 jones
import java.sql.Timestamp;
30 6595 leinfelder
import java.util.ArrayList;
31 2096 jones
import java.util.Date;
32 8464 leinfelder
import java.util.HashMap;
33 6595 leinfelder
import java.util.List;
34 8464 leinfelder
import java.util.Map;
35 7285 leinfelder
import java.util.Vector;
36 2096 jones
37 2663 sgarg
import org.apache.log4j.Logger;
38 8810 leinfelder
import org.dataone.service.types.v1.Identifier;
39
import org.dataone.service.types.v2.Log;
40
import org.dataone.service.types.v2.LogEntry;
41 7285 leinfelder
import org.dataone.service.types.v1.Event;
42
import org.dataone.service.types.v1.NodeReference;
43
import org.dataone.service.types.v1.Subject;
44 6944 leinfelder
import org.dataone.service.util.DateTimeMarshaller;
45 2663 sgarg
46 5015 daigle
import edu.ucsb.nceas.metacat.database.DBConnection;
47
import edu.ucsb.nceas.metacat.database.DBConnectionPool;
48 7437 leinfelder
import edu.ucsb.nceas.metacat.database.DatabaseService;
49 8464 leinfelder
import edu.ucsb.nceas.metacat.index.MetacatSolrIndex;
50 7285 leinfelder
import edu.ucsb.nceas.metacat.properties.PropertyService;
51 7409 leinfelder
import edu.ucsb.nceas.metacat.util.DocumentUtil;
52 7285 leinfelder
import edu.ucsb.nceas.utilities.PropertyNotFoundException;
53 5015 daigle
54 2096 jones
/**
55
 * EventLog is used to intialize and store a log of events that occur in an
56
 * application. The events are registered with the logger as they occur, but
57
 * EventLog writes them to permenant storage when it is most convenient or
58
 * efficient. EventLog is a Singleton as there should always be only one object
59
 * for these logging events.
60
 *
61
 * TODO: Logging to the database needn't be synchronous with the event.
62
 * Instead, a separate thread can be launched that periodically sleeps and only
63
 * wakes periodically to see if metacat is idle.  The log event can be cached
64
 * and inserted later when the thread wakes and finds metacat idle.
65
 *
66
 * TODO: Write a function that archives a part of the log table to an
67
 * external text file so that the log table doesn't get to big.  This
68
 * function should be able to be called manually or on a schedule.
69
 *
70
 * TODO: Write an access function that returns an XML report for a
71
 * specific subset of events.  Users should be able to query on
72
 * principal, docid/rev, date, event, and possibly other fields.
73
 *
74
 * @author jones
75
 */
76
public class EventLog
77
{
78 8896 tao
    public static final String DELETE = "delete";
79 2096 jones
    /**
80
     * The single instance of the event log that is always returned.
81
     */
82
    private static EventLog self = null;
83 2663 sgarg
    private Logger logMetacat = Logger.getLogger(EventLog.class);
84 9107 tao
    private static final int USERAGENTLENGTH = 512;
85 2096 jones
86
    /**
87
     * A private constructor that initializes the class when getInstance() is
88
     * called.
89
     */
90
    private EventLog()
91
    {
92
    }
93
94
    /**
95
     * Return the single instance of the event log after initializing it if it
96
     * wasn't previously initialized.
97
     *
98
     * @return the single EventLog instance
99
     */
100
    public static EventLog getInstance()
101
    {
102
        if (self == null) {
103
            self = new EventLog();
104
        }
105
        return self;
106
    }
107
108
    /**
109
     * Log an event of interest to the application. The information logged can
110
     * include basic identification information about the principal or computer
111
     * that initiated the event.
112
     *
113 2099 jones
     * @param ipAddress the internet protocol address for the event
114 6542 leinfelder
     * @param userAgent the agent making the request
115 2099 jones
	 * @param principal the principal for the event (a username, etc)
116
	 * @param docid the identifier of the document to which the event applies
117
	 * @param event the string code for the event
118 2096 jones
     */
119 6542 leinfelder
    public void log(String ipAddress, String userAgent, String principal, String docid, String event) {
120 9098 tao
        EventLogData logData = new EventLogData(ipAddress, userAgent, principal, docid, event);
121 2096 jones
        insertLogEntry(logData);
122 8464 leinfelder
123
        // update the event information in the index
124
        try {
125
	        String localId = DocumentUtil.getSmartDocId(docid);
126
			int rev = DocumentUtil.getRevisionFromAccessionNumber(docid);
127
128
	        String guid = IdentifierManager.getInstance().getGUID(localId, rev);
129
	        Identifier pid = new Identifier();
130
	        pid.setValue(guid);
131
132
	        // submit for indexing
133 8647 leinfelder
	        MetacatSolrIndex.getInstance().submit(pid, null, this.getIndexFields(pid, event), false);
134 8464 leinfelder
135
        } catch (Exception e) {
136
        	logMetacat.error("Could not update event index information", e);
137
        }
138 2096 jones
    }
139 2099 jones
140 8464 leinfelder
    public Map<String, List<Object>> getIndexFields(Identifier pid, String event) {
141
    	// update the search index for the event
142
        try {
143
144 8810 leinfelder
        	if (event != null) {
145 8596 leinfelder
146 8810 leinfelder
	        	String fieldName = event + "_count_i";
147 8596 leinfelder
	        	int eventCount = 0;
148
149
	        	String docid = IdentifierManager.getInstance().getLocalId(pid.getValue());
150 8810 leinfelder
	        	Log eventLog = this.getD1Report(null, null, new String[] {docid}, event, null, null, false, 0, 0);
151 8596 leinfelder
	        	eventCount = eventLog.getTotal();
152
153
		        List<Object> values = new ArrayList<Object>();
154
				values.add(eventCount);
155
		        Map<String, List<Object>> fields = new HashMap<String, List<Object>>();
156
		        fields.put(fieldName, values);
157
158
		        return fields;
159
        	}
160 8464 leinfelder
161
        } catch (Exception e) {
162 8596 leinfelder
        	logMetacat.error("Could not update event index information on pid: " + pid.getValue() + " for event: " + event, e);
163 8464 leinfelder
        }
164 8596 leinfelder
        // default if we can't find the event information
165
    	return null;
166
167 8464 leinfelder
    }
168
169 2096 jones
    /**
170
     * Insert a single log event record to the database.
171
     *
172
     * @param logData the data to be logged when an event occurs
173
     */
174
    private void insertLogEntry(EventLogData logData)
175
    {
176
        String insertString = "insert into access_log"
177 6542 leinfelder
                + "(ip_address, user_agent, principal, docid, "
178 2096 jones
                + "event, date_logged) "
179 6595 leinfelder
                + "values ( ?, ?, ?, ?, ?, ? )";
180
181 2096 jones
        DBConnection dbConn = null;
182
        int serialNumber = -1;
183
        try {
184
            // Get a database connection from the pool
185 2111 jones
            dbConn = DBConnectionPool.getDBConnection("EventLog.insertLogEntry");
186 2096 jones
            serialNumber = dbConn.getCheckOutSerialNumber();
187 9107 tao
            String userAgent = logData.getUserAgent();
188
            if(userAgent != null && userAgent.length() > USERAGENTLENGTH) {
189
                userAgent = userAgent.substring(0, USERAGENTLENGTH);
190
            }
191 2096 jones
192
            // Execute the insert statement
193 2104 jones
            PreparedStatement stmt = dbConn.prepareStatement(insertString);
194 6595 leinfelder
195
            stmt.setString(1, logData.getIpAddress());
196 9107 tao
            stmt.setString(2, userAgent);
197 6595 leinfelder
            stmt.setString(3, logData.getPrincipal());
198
            stmt.setString(4, logData.getDocid());
199
            stmt.setString(5, logData.getEvent());
200
            stmt.setTimestamp(6, new Timestamp(new Date().getTime()));
201 2104 jones
            stmt.executeUpdate();
202 2096 jones
            stmt.close();
203
        } catch (SQLException e) {
204 2663 sgarg
        	logMetacat.error("Error while logging event to database: "
205
                    + e.getMessage());
206 2096 jones
        } finally {
207
            // Return database connection to the pool
208
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
209
        }
210
    }
211 2110 jones
212
    /**
213
     * Get a report of the log events that match a set of filters.  The
214 2111 jones
     * filter parameters can be null; log records are subset based on
215 2110 jones
     * non-null filter parameters.
216
     *
217
     * @param ipAddress the internet protocol address for the event
218
	 * @param principal the principal for the event (a username, etc)
219
	 * @param docid the identifier of the document to which the event applies
220
	 * @param event the string code for the event
221 2111 jones
	 * @param startDate beginning of date range for query
222
	 * @param endDate end of date range for query
223
	 * @return an XML-formatted report of the access log entries
224 2110 jones
     */
225 2111 jones
    public String getReport(String[] ipAddress, String[] principal, String[] docid,
226 5693 leinfelder
            String[] event, Timestamp startDate, Timestamp endDate, boolean anonymous)
227 2110 jones
    {
228 2111 jones
        StringBuffer resultDoc = new StringBuffer();
229
        StringBuffer query = new StringBuffer();
230 6542 leinfelder
        query.append("select entryid, ip_address, user_agent, principal, docid, "
231 2111 jones
            + "event, date_logged from access_log");
232
//                        + ""
233
//                        + "event, date_logged) " + "values (" + "'"
234
//                        + logData.getIpAddress() + "', " + "'"
235
//                        + logData.getPrincipal() + "', " + "'"
236
//                        + logData.getDocid() + "', " + "'" + logData.getEvent()
237
//                        + "', " + " ? " + ")";
238
        if (ipAddress != null || principal != null || docid != null
239
                        || event != null || startDate != null || endDate != null) {
240
            query.append(" where ");
241
        }
242
        boolean clauseAdded = false;
243
        int startIndex = 0;
244
        int endIndex = 0;
245
246 6595 leinfelder
        List<String> paramValues = new ArrayList<String>();
247 2111 jones
        if (ipAddress != null) {
248 6595 leinfelder
        	query.append("ip_address in (");
249
        	for (int i = 0; i < ipAddress.length; i++) {
250
        		if (i > 0) {
251
            		query.append(", ");
252
        		}
253
        		query.append("?");
254
        		paramValues.add(ipAddress[i]);
255
        	}
256
        	query.append(") ");
257 2111 jones
            clauseAdded = true;
258
        }
259
        if (principal != null) {
260 7309 leinfelder
        	if (clauseAdded) {
261
                query.append(" and ");
262
            }
263 6595 leinfelder
        	query.append("principal in (");
264
        	for (int i = 0; i < principal.length; i++) {
265
        		if (i > 0) {
266
            		query.append(", ");
267
        		}
268
        		query.append("?");
269
        		paramValues.add(principal[i]);
270
        	}
271
        	query.append(") ");
272 2111 jones
            clauseAdded = true;
273
        }
274
        if (docid != null) {
275 7309 leinfelder
        	if (clauseAdded) {
276
                query.append(" and ");
277
            }
278 6595 leinfelder
        	query.append("docid in (");
279
        	for (int i = 0; i < docid.length; i++) {
280
        		if (i > 0) {
281
            		query.append(", ");
282
        		}
283
        		query.append("?");
284 7409 leinfelder
        		String fullDocid = docid[i];
285
        		// allow docid without revision - look up latest version
286
        		try {
287
        			fullDocid = DocumentUtil.appendRev(fullDocid);
288
        		} catch (Exception e) {
289
					// just warn about this
290
        			logMetacat.warn("Could not check docid for revision: " + fullDocid, e);
291
				}
292
        		paramValues.add(fullDocid);
293 6595 leinfelder
        	}
294
        	query.append(") ");
295 2111 jones
            clauseAdded = true;
296
        }
297
        if (event != null) {
298 7309 leinfelder
        	if (clauseAdded) {
299
                query.append(" and ");
300
            }
301 6595 leinfelder
        	query.append("event in (");
302
        	for (int i = 0; i < event.length; i++) {
303
        		if (i > 0) {
304
            		query.append(", ");
305
        		}
306
        		query.append("?");
307
        		paramValues.add(event[i]);
308
        	}
309
        	query.append(") ");
310 2111 jones
            clauseAdded = true;
311
        }
312
        if (startDate != null) {
313
            if (clauseAdded) {
314
                query.append(" and ");
315
            }
316 7057 leinfelder
            query.append("date_logged >= ?");
317 2111 jones
            clauseAdded = true;
318
            startIndex++;
319
        }
320
        if (endDate != null) {
321
            if (clauseAdded) {
322
                query.append(" and ");
323
            }
324
            query.append("date_logged < ?");
325
            clauseAdded = true;
326
            endIndex = startIndex + 1;
327
        }
328
        DBConnection dbConn = null;
329
        int serialNumber = -1;
330
        try {
331
            // Get a database connection from the pool
332
            dbConn = DBConnectionPool.getDBConnection("EventLog.getReport");
333
            serialNumber = dbConn.getCheckOutSerialNumber();
334
335 2113 jones
            // Execute the query statement
336 2111 jones
            PreparedStatement stmt = dbConn.prepareStatement(query.toString());
337 6595 leinfelder
            //set the param values
338
            int parameterIndex = 1;
339
            for (String val: paramValues) {
340 7309 leinfelder
            	stmt.setString(parameterIndex++, val);
341 6595 leinfelder
            }
342 6598 leinfelder
            if (startDate != null) {
343
                stmt.setTimestamp(parameterIndex++, startDate);
344 2111 jones
            }
345 6598 leinfelder
            if (endDate != null) {
346
            	stmt.setTimestamp(parameterIndex++, endDate);
347 2111 jones
            }
348
            stmt.execute();
349
            ResultSet rs = stmt.getResultSet();
350 2113 jones
            //process the result and return it as an XML document
351 2111 jones
            resultDoc.append("<?xml version=\"1.0\"?>\n");
352
            resultDoc.append("<log>\n");
353
            while (rs.next()) {
354 5693 leinfelder
                resultDoc.append(
355
                		generateXmlRecord(
356
                				rs.getString(1), //id
357
                				anonymous ? "" : rs.getString(2), //ip
358 6542 leinfelder
                				rs.getString(3), //userAgent
359
                				anonymous ? "" : rs.getString(4), //principal
360 5693 leinfelder
                                rs.getString(5),
361 6542 leinfelder
                                rs.getString(6),
362
                                rs.getTimestamp(7)));
363 2111 jones
            }
364
            resultDoc.append("</log>");
365
            stmt.close();
366
        } catch (SQLException e) {
367 2663 sgarg
        	logMetacat.info("Error while logging event to database: "
368
                            + e.getMessage());
369 2111 jones
        } finally {
370
            // Return database connection to the pool
371
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
372
        }
373
        return resultDoc.toString();
374 2110 jones
    }
375 2111 jones
376 8896 tao
    /**
377
     * A utility method to determine if the given docid was deleted.
378
     * @param docid the specified docid
379
     * @return true if there is a delete event for the id; false otherwise.
380
     */
381
    public boolean isDeleted(String docid) {
382
        boolean deleted =false;
383
        if(docid != null || !docid.trim().equals("")) {
384
            String[] docids = new String[1];
385
            docids[0] = docid;
386
            String[] events = new String[1];
387
            events[0]= DELETE;
388
            String[] ipAddress = null;
389
            String[] principal = null;
390
            Timestamp startDate = null;
391
            Timestamp endDate = null;
392
            boolean anonymous = false;
393
394
            String report =getReport(ipAddress, principal, docids,
395
                     events, startDate, endDate, anonymous);
396
            //System.out.println("the report is "+report);
397
            if(report != null && report.contains("<event>"+DELETE+"</event>") ){
398
                deleted = true;
399
            }
400
        }
401
        return deleted;
402
    }
403 7285 leinfelder
404
    public Log getD1Report(String[] ipAddress, String[] principal, String[] docid,
405 8810 leinfelder
            String event, Timestamp startDate, Timestamp endDate, boolean anonymous, Integer start, Integer count)
406 7285 leinfelder
    {
407
408
        Log log = new Log();
409
410
    	NodeReference memberNode = new NodeReference();
411
        String nodeId = "localhost";
412
        try {
413
            nodeId = PropertyService.getProperty("dataone.nodeId");
414
        } catch (PropertyNotFoundException e1) {
415
            // TODO Auto-generated catch block
416
            e1.printStackTrace();
417
        }
418
        memberNode.setValue(nodeId);
419
420 7451 leinfelder
        String countClause = "select count(*) ";
421
        String fieldsClause = "select " +
422 7285 leinfelder
        		"entryid, " +
423
        		"id.guid as identifier, " +
424
        		"ip_address, " +
425
        		"user_agent, " +
426
        		"principal, " +
427
        		"case " +
428
        		"	when event = 'insert' then 'create' " +
429
        		"	else event " +
430
        		"end as event, " +
431 7451 leinfelder
        		"date_logged ";
432
433
        StringBuffer queryWhereClause = new StringBuffer();
434
        queryWhereClause.append(
435 7285 leinfelder
        		"from access_log al, identifier id " +
436
        		"where al.docid = id.docid||'.'||id.rev "
437
        );
438
439 7287 leinfelder
        boolean clauseAdded = true;
440 7285 leinfelder
441
        List<String> paramValues = new ArrayList<String>();
442
        if (ipAddress != null) {
443 7309 leinfelder
        	if (clauseAdded) {
444 7451 leinfelder
                queryWhereClause.append(" and ");
445 7309 leinfelder
            }
446 7451 leinfelder
        	queryWhereClause.append("ip_address in (");
447 7285 leinfelder
        	for (int i = 0; i < ipAddress.length; i++) {
448
        		if (i > 0) {
449 7451 leinfelder
            		queryWhereClause.append(", ");
450 7285 leinfelder
        		}
451 7451 leinfelder
        		queryWhereClause.append("?");
452 7285 leinfelder
        		paramValues.add(ipAddress[i]);
453
        	}
454 7451 leinfelder
        	queryWhereClause.append(") ");
455 7285 leinfelder
            clauseAdded = true;
456
        }
457
        if (principal != null) {
458 7309 leinfelder
        	if (clauseAdded) {
459 7451 leinfelder
                queryWhereClause.append(" and ");
460 7309 leinfelder
            }
461 7451 leinfelder
        	queryWhereClause.append("principal in (");
462 7285 leinfelder
        	for (int i = 0; i < principal.length; i++) {
463
        		if (i > 0) {
464 7451 leinfelder
            		queryWhereClause.append(", ");
465 7285 leinfelder
        		}
466 7451 leinfelder
        		queryWhereClause.append("?");
467 7285 leinfelder
        		paramValues.add(principal[i]);
468
        	}
469 7451 leinfelder
        	queryWhereClause.append(") ");
470 7285 leinfelder
            clauseAdded = true;
471
        }
472
        if (docid != null) {
473 7309 leinfelder
        	if (clauseAdded) {
474 7451 leinfelder
                queryWhereClause.append(" and ");
475 7309 leinfelder
            }
476 7451 leinfelder
        	queryWhereClause.append("al.docid in (");
477 7285 leinfelder
        	for (int i = 0; i < docid.length; i++) {
478
        		if (i > 0) {
479 7451 leinfelder
            		queryWhereClause.append(", ");
480 7285 leinfelder
        		}
481 7451 leinfelder
        		queryWhereClause.append("?");
482 7285 leinfelder
        		paramValues.add(docid[i]);
483
        	}
484 7451 leinfelder
        	queryWhereClause.append(") ");
485 7285 leinfelder
            clauseAdded = true;
486
        }
487
        if (event != null) {
488 7309 leinfelder
        	if (clauseAdded) {
489 7451 leinfelder
                queryWhereClause.append(" and ");
490 7309 leinfelder
            }
491 7451 leinfelder
        	queryWhereClause.append("event in (");
492
    		queryWhereClause.append("?");
493 8810 leinfelder
    		String eventString = event;
494
    		if (eventString.equals(Event.CREATE.xmlValue())) {
495 7285 leinfelder
    			eventString = "insert";
496
    		}
497
    		paramValues.add(eventString);
498 7451 leinfelder
        	queryWhereClause.append(") ");
499 7285 leinfelder
            clauseAdded = true;
500
        }
501 8810 leinfelder
502 7285 leinfelder
        if (startDate != null) {
503
            if (clauseAdded) {
504 7451 leinfelder
                queryWhereClause.append(" and ");
505 7285 leinfelder
            }
506 7451 leinfelder
            queryWhereClause.append("date_logged >= ?");
507 7285 leinfelder
            clauseAdded = true;
508
        }
509
        if (endDate != null) {
510
            if (clauseAdded) {
511 7451 leinfelder
                queryWhereClause.append(" and ");
512 7285 leinfelder
            }
513 7451 leinfelder
            queryWhereClause.append("date_logged < ?");
514 7285 leinfelder
            clauseAdded = true;
515
        }
516 7437 leinfelder
517
        // order by
518 7451 leinfelder
        String orderByClause = " order by entryid ";
519 7437 leinfelder
520 7451 leinfelder
        // select the count
521
        String countQuery = countClause + queryWhereClause.toString();
522
523
		// select the fields
524
        String pagedQuery = DatabaseService.getInstance().getDBAdapter().getPagedQuery(fieldsClause + queryWhereClause.toString() + orderByClause, start, count);
525 7437 leinfelder
526 7285 leinfelder
        DBConnection dbConn = null;
527
        int serialNumber = -1;
528
        try {
529
            // Get a database connection from the pool
530
            dbConn = DBConnectionPool.getDBConnection("EventLog.getD1Report");
531
            serialNumber = dbConn.getCheckOutSerialNumber();
532
533
            // Execute the query statement
534 7451 leinfelder
            PreparedStatement fieldsStmt = dbConn.prepareStatement(pagedQuery);
535
            PreparedStatement countStmt = dbConn.prepareStatement(countQuery);
536
537 7285 leinfelder
            //set the param values
538
            int parameterIndex = 1;
539
            for (String val: paramValues) {
540 7451 leinfelder
            	countStmt.setString(parameterIndex, val);
541
            	fieldsStmt.setString(parameterIndex, val);
542
            	parameterIndex++;
543 7285 leinfelder
            }
544
            if (startDate != null) {
545 7451 leinfelder
            	countStmt.setTimestamp(parameterIndex, startDate);
546
                fieldsStmt.setTimestamp(parameterIndex, startDate);
547
            	parameterIndex++;
548 7285 leinfelder
            }
549
            if (endDate != null) {
550 7451 leinfelder
            	countStmt.setTimestamp(parameterIndex, endDate);
551
            	fieldsStmt.setTimestamp(parameterIndex, endDate);
552
            	parameterIndex++;
553 7285 leinfelder
            }
554 7451 leinfelder
555
            // for the return Log list
556 7285 leinfelder
            List<LogEntry> logs = new Vector<LogEntry>();
557
558 7451 leinfelder
            // get the fields form the query
559
            if (count != 0) {
560
	            fieldsStmt.execute();
561
	            ResultSet rs = fieldsStmt.getResultSet();
562
	            //process the result and return it
563
	            while (rs.next()) {
564
	            	LogEntry logEntry = new LogEntry();
565
	            	logEntry.setEntryId(rs.getString(1));
566
567
	            	Identifier identifier = new Identifier();
568
	            	identifier.setValue(rs.getString(2));
569
					logEntry.setIdentifier(identifier);
570
571
	            	logEntry.setIpAddress(anonymous ? "N/A" : rs.getString(3));
572
	            	String userAgent = "N/A";
573
	            	if (rs.getString(4) != null) {
574
	            		userAgent = rs.getString(4);
575
	            	}
576
	            	logEntry.setUserAgent(userAgent);
577
578
	            	Subject subject = new Subject();
579
	            	subject.setValue(anonymous ? "N/A" : rs.getString(5));
580
					logEntry.setSubject(subject);
581
582
					String logEventString = rs.getString(6);
583 9323 tao
					if(logEventString == null) {
584 9324 tao
					    logEventString = "unknown";
585 9323 tao
					}
586 8810 leinfelder
					logEntry.setEvent(logEventString);
587 7451 leinfelder
					logEntry.setDateLogged(rs.getTimestamp(7));
588
589
					logEntry.setNodeIdentifier(memberNode);
590
					logs.add(logEntry);
591
	            }
592
	            fieldsStmt.close();
593 7285 leinfelder
            }
594
595 7451 leinfelder
            // set what we have
596
            log.setLogEntryList(logs);
597 7285 leinfelder
		    log.setStart(start);
598
		    log.setCount(logs.size());
599 7451 leinfelder
600
			// get total for out query
601
		    int total = 0;
602
            countStmt.execute();
603
            ResultSet countRs = countStmt.getResultSet();
604
            if (countRs.next()) {
605
            	total = countRs.getInt(1);
606
            }
607
            countStmt.close();
608 7285 leinfelder
		    log.setTotal(total);
609
610
        } catch (SQLException e) {
611 7287 leinfelder
        	logMetacat.error("Error while getting log events: " + e.getMessage(), e);
612 7285 leinfelder
        } finally {
613
            // Return database connection to the pool
614
            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
615
        }
616
        return log;
617
    }
618
619 2111 jones
    /**
620
     * Format each returned log record as an XML structure.
621
     *
622
     * @param entryId the identifier of the log entry
623
     * @param ipAddress the internet protocol address for the event
624 6542 leinfelder
     * @param the agent making the request
625 2111 jones
	 * @param principal the principal for the event (a username, etc)
626
	 * @param docid the identifier of the document to which the event applies
627
	 * @param event the string code for the event
628
     * @param dateLogged the date on which the event occurred
629
     * @return String containing the formatted XML
630
     */
631 6542 leinfelder
    private String generateXmlRecord(String entryId, String ipAddress, String userAgent,
632 2113 jones
            String principal, String docid, String event, Timestamp dateLogged)
633 2111 jones
    {
634
        StringBuffer rec = new StringBuffer();
635
        rec.append("<logEntry>");
636 2113 jones
        rec.append(generateXmlElement("entryid", entryId));
637
        rec.append(generateXmlElement("ipAddress", ipAddress));
638 6542 leinfelder
        rec.append(generateXmlElement("userAgent", userAgent));
639 2113 jones
        rec.append(generateXmlElement("principal", principal));
640
        rec.append(generateXmlElement("docid", docid));
641
        rec.append(generateXmlElement("event", event));
642 6944 leinfelder
        rec.append(generateXmlElement("dateLogged", DateTimeMarshaller.serializeDateToUTC(dateLogged)));
643 2111 jones
        rec.append("</logEntry>\n");
644
645
        return rec.toString();
646
    }
647
648
    /**
649
     * Return an XML formatted element for a given name/value pair.
650
     *
651
     * @param name the name of the xml element
652
     * @param value the content of the xml element
653
     * @return the formatted XML element as a String
654
     */
655 2113 jones
    private String generateXmlElement(String name, String value)
656 2111 jones
    {
657
        return "<" + name + ">" + value + "</" + name + ">";
658
    }
659 2096 jones
}