Project

General

Profile

1 2732 sgarg
/**
2
 *  '$RCSfile$'
3
 *    Purpose: A Class that tracks sessions for MetaCatServlet users.
4
 *  Copyright: 2000 Regents of the University of California and the
5
 *             National Center for Ecological Analysis and Synthesis
6
 *    Authors: Matt Jones
7
 *
8
 *   '$Author$'
9
 *     '$Date$'
10
 * '$Revision$'
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.sql.PreparedStatement;
30
import java.sql.ResultSet;
31
import java.sql.SQLException;
32
import java.util.Vector;
33 2733 sgarg
import java.util.HashMap;
34
import java.lang.Comparable;
35 2732 sgarg
import edu.ucsb.nceas.metacat.MetaCatUtil;
36
import org.apache.log4j.Logger;
37
38
public class IndexingQueue {
39
40
	private Logger logMetacat = Logger.getLogger(IndexingQueue.class);
41 2733 sgarg
	//	 Map used to keep tracks of docids to be indexed
42
	private HashMap indexingMap = new HashMap();
43 2732 sgarg
	private Vector currentThreads = new Vector();
44 2733 sgarg
	public Vector currentDocidsBeingIndexed = new Vector();
45 2901 sgarg
	private boolean metacatRunning = true;
46 2732 sgarg
47
	private static IndexingQueue instance = null;
48
49
	final static int NUMBEROFINDEXINGTHREADS =
50
		Integer.parseInt(MetaCatUtil.getOption("numberOfIndexingThreads"));
51
	private int sleepTime = 2000;
52
53
    public IndexingQueue() {
54
	    for (int i = 0; i < NUMBEROFINDEXINGTHREADS; i++) {
55
	      Thread thread = new IndexingTask();
56
	      thread.start();
57 2902 sgarg
	      currentThreads.add(thread);
58 2732 sgarg
	    }
59
    }
60
61
	public static synchronized IndexingQueue getInstance(){
62
		if (instance == null) {
63
			instance = new IndexingQueue();
64
		}
65
		return instance;
66
	}//getInstance
67
68 2733 sgarg
    public void add(String docid, String rev) {
69
    	add(new IndexingQueueObject(docid, rev, 0));
70
    }
71 2732 sgarg
72 2733 sgarg
    protected void add(IndexingQueueObject queueObject) {
73
	    synchronized (indexingMap) {
74
	    	if(!indexingMap.containsKey(queueObject.getDocid())){
75
	    		indexingMap.put(queueObject.getDocid(), queueObject);
76
	    		indexingMap.notify();
77
	    	} else {
78
	    		IndexingQueueObject oldQueueObject =
79
	    			(IndexingQueueObject) indexingMap.get(queueObject.getDocid());
80
	    		if(oldQueueObject.compareTo(queueObject) < 0){
81
	    	  		indexingMap.put(queueObject.getDocid(), queueObject);
82
		    		indexingMap.notify();
83
	    		}
84
	    	}
85 2732 sgarg
	    }
86
	  }
87
88 2901 sgarg
	public boolean getMetacatRunning(){
89
		return this.metacatRunning;
90
	}
91 2732 sgarg
92 2901 sgarg
	public void setMetacatRunning(boolean metacatRunning){
93
		this.metacatRunning = metacatRunning;
94
95 2902 sgarg
		if(!metacatRunning){
96
			for(int count=0; count<currentThreads.size(); count++){
97
				((IndexingTask)currentThreads.get(count)).metacatRunning = false;
98
				((Thread)currentThreads.get(count)).interrupt();
99
			}
100 2901 sgarg
		}
101
	}
102
103 2732 sgarg
    protected IndexingQueueObject getNext() {
104
    	IndexingQueueObject returnVal = null;
105 2733 sgarg
        synchronized (indexingMap) {
106 2901 sgarg
          while (indexingMap.isEmpty() && metacatRunning) {
107 2732 sgarg
            try {
108 2733 sgarg
            	indexingMap.wait();
109 2732 sgarg
            } catch (InterruptedException ex) {
110
              System.err.println("Interrupted");
111
            }
112
          }
113 2901 sgarg
114
          if(metacatRunning){
115
        	  String docid = (String) indexingMap.keySet().iterator().next();
116
        	  returnVal = (IndexingQueueObject)indexingMap.get(docid);
117
        	  indexingMap.remove(docid);
118
          }
119 2732 sgarg
        }
120
        return returnVal;
121
      }
122
123
}
124
125
class IndexingTask extends Thread {
126
  	  private Logger logMetacat = Logger.getLogger(IndexingTask.class);
127 2733 sgarg
      protected final long MAXIMUMINDEXDELAY = Integer.
128
      	parseInt(MetaCatUtil.getOption("maximumIndexDelay"));;
129 2902 sgarg
      protected boolean metacatRunning = true;
130
131 2732 sgarg
	  public void run() {
132 2902 sgarg
	    while (metacatRunning) {
133 2732 sgarg
	      // blocks until job
134
	      IndexingQueueObject returnVal =
135
	    	  IndexingQueue.getInstance().getNext();
136 2733 sgarg
137 2901 sgarg
	      if(returnVal != null){
138
	    	  if(!IndexingQueue.getInstance().
139 2733 sgarg
	    			currentDocidsBeingIndexed.contains(returnVal.getDocid())){
140
    		  try {
141
    			  IndexingQueue.getInstance().
142
    			  		currentDocidsBeingIndexed.add(returnVal.getDocid());
143
    		      String docid = returnVal.getDocid() + "." + returnVal.getRev();
144 2764 sgarg
    			  if(checkDocumentTable(docid, "xml_documents")){
145
    				  logMetacat.warn("Calling buildIndex for " + docid);
146
    				  DocumentImpl doc = new DocumentImpl(docid, false);
147
    				  doc.buildIndex();
148
    			  } else {
149
    				  logMetacat.warn("Couldn't find the docid:" + docid
150
	                			+ " in xml_documents table");
151
	                  sleep(MAXIMUMINDEXDELAY);
152
	                  throw(new Exception("Couldn't find the docid:" + docid
153
	                			+ " in xml_documents table"));
154
    			  }
155 2901 sgarg
    		  	} catch (Exception e) {
156 2733 sgarg
    			  logMetacat.warn("Exception: " + e);
157
    			  e.printStackTrace();
158 2732 sgarg
159 2733 sgarg
    			  if(returnVal.getCount() < 25){
160
    				  returnVal.setCount(returnVal.getCount()+1);
161
    				  // add the docid back to the list
162
    				  IndexingQueue.getInstance().add(returnVal);
163
    			  } else {
164
    				  logMetacat.fatal("Docid " + returnVal.getDocid()
165 2732 sgarg
	        			+ " has been inserted to IndexingQueue "
166 2733 sgarg
	        			+ "more than 25 times. Not adding the docid to"
167
	        			+ " the queue again.");
168
    			  }
169 2901 sgarg
    		  	} finally {
170
    			  	IndexingQueue.getInstance().currentDocidsBeingIndexed
171
    			  		.remove(returnVal.getDocid());
172
    		  	}
173
	    	  } else {
174
	    		  returnVal.setCount(returnVal.getCount()+1);
175
	    		  IndexingQueue.getInstance().add(returnVal);
176
	    	  }
177
	      }
178 2732 sgarg
	    }
179
	  }
180
181 2764 sgarg
      private boolean checkDocumentTable(String docid, String tablename) throws Exception{
182 2732 sgarg
	        DBConnection dbConn = null;
183
	        int serialNumber = -1;
184 2764 sgarg
	        boolean inxmldoc = false;
185
186 2732 sgarg
	        String revision = docid.substring(docid.lastIndexOf(".")+1,docid.length());
187
	        docid = docid.substring(0,docid.lastIndexOf("."));
188
189 2764 sgarg
	        logMetacat.info("Checking if document exsists in xml_documents: docid is "
190
	        		+ docid + " and revision is " + revision);
191 2732 sgarg
192
	        try {
193
	            // Opening separate db connection for writing XML Index
194
	            dbConn = DBConnectionPool
195
	                    .getDBConnection("DBSAXHandler.checkDocumentTable");
196
	            serialNumber = dbConn.getCheckOutSerialNumber();
197
198 2764 sgarg
	            String xmlDocumentsCheck = "SELECT distinct docid FROM " + tablename
199
	                        + " WHERE docid ='" + docid
200
	                        + "' AND rev ='" + revision + "'";
201 2732 sgarg
202 2764 sgarg
                PreparedStatement xmlDocCheck = dbConn.prepareStatement(xmlDocumentsCheck);
203
                // Increase usage count
204
205
                dbConn.increaseUsageCount(1);
206
	            xmlDocCheck.execute();
207
	            ResultSet doccheckRS = xmlDocCheck.getResultSet();
208
	            boolean tableHasRows = doccheckRS.next();
209
	            if (tableHasRows) {
210
	            	inxmldoc = true;
211
	            }
212
	            doccheckRS.close();
213
	            xmlDocCheck.close();
214 2732 sgarg
	        } catch (SQLException e) {
215
	        	   e.printStackTrace();
216
	        } finally {
217
	            DBConnectionPool.returnDBConnection(dbConn, serialNumber);
218
	        }//finally
219 2764 sgarg
220
	        return inxmldoc;
221
      }
222 2732 sgarg
	}
223
224 2733 sgarg
class IndexingQueueObject implements Comparable{
225 2732 sgarg
	// the docid of the document to be indexed.
226
	private String docid;
227 2733 sgarg
	// the docid of the document to be indexed.
228
	private String rev;
229 2732 sgarg
	// the count of number of times the document has been in the queue
230
	private int count;
231
232 2733 sgarg
	IndexingQueueObject(String docid, String rev, int count){
233
		this.docid = docid;
234
		this.rev = rev;
235 2732 sgarg
		this.count = count;
236
	}
237
238
	public int getCount(){
239
		return count;
240
	}
241
242
	public String getDocid(){
243
		return docid;
244
	}
245
246 2733 sgarg
	public String getRev(){
247
		return rev;
248
	}
249
250 2732 sgarg
	public void setCount(int count){
251
		this.count = count;
252
	}
253
254
	public void setDocid(String docid){
255
		this.docid = docid;
256
	}
257 2733 sgarg
258
	public void setRev(String rev){
259
		this.rev = rev;
260
	}
261
262
	public int compareTo(Object o){
263
		if(o instanceof IndexingQueueObject){
264
			int revision = Integer.parseInt(rev);
265
			int oRevision = Integer.parseInt(((IndexingQueueObject)o).getRev());
266
267
			if(revision == oRevision) {
268
				return 0;
269
			} else if (revision > oRevision) {
270
				return 1;
271
			} else {
272
				return -1;
273
			}
274
		} else {
275
			throw new java.lang.ClassCastException();
276
		}
277
	}
278 3077 jones
}