1 16 package dlog4j.search; 17 18 import java.io.File ; 19 import java.io.FileInputStream ; 20 import java.io.FileOutputStream ; 21 import java.io.IOException ; 22 import java.io.InputStream ; 23 import java.io.OutputStream ; 24 import java.util.Date ; 25 import java.util.Iterator ; 26 import java.util.Properties ; 27 28 import javax.servlet.ServletException ; 29 30 import net.sf.hibernate.Query; 31 import net.sf.hibernate.Session; 32 33 import org.apache.commons.lang.StringUtils; 34 import org.apache.commons.logging.Log; 35 import org.apache.commons.logging.LogFactory; 36 import org.apache.lucene.analysis.Analyzer; 37 import org.apache.lucene.analysis.standard.StandardAnalyzer; 38 import org.apache.lucene.document.DateField; 39 import org.apache.lucene.document.Document; 40 import org.apache.lucene.document.Field; 41 import org.apache.lucene.index.IndexWriter; 42 import org.apache.struts.action.PlugIn; 43 import org.apache.struts.action.ActionServlet; 44 import org.apache.struts.config.ModuleConfig; 45 46 import dlog4j.ManagerBase; 47 import dlog4j.formbean.LogForm; 48 import dlog4j.formbean.ReplyForm; 49 50 55 public class SearchEnginePlugIn implements PlugIn, Runnable { 56 57 60 private static Analyzer analyzer; 61 62 protected static ActionServlet servlet = null; 63 64 65 protected int activeInterval = 600; 66 protected static String logIndexPath = "/WEB-INF/log_index"; 67 protected static String replyIndexPath = "/WEB-INF/reply_index"; 68 protected String statusFile = "/WEB-INF/lastActiveTime.sav"; 69 70 protected String analyzerClass; 71 private Thread daemon; 72 73 77 public void init(ActionServlet servlet, ModuleConfig config) throws ServletException { 78 SearchEnginePlugIn.servlet = servlet; 79 if(analyzerClass==null) 80 analyzerClass = StandardAnalyzer.class.getName(); 81 try{ 82 analyzer = (Analyzer)Class.forName(analyzerClass).newInstance(); 83 }catch(Exception e){ 84 servlet.log("Initialize Analyzer Failed.",e); 85 } 86 daemon = new Thread (this); 87 daemon.setDaemon(true); 88 daemon.start(); 89 } 90 94 public void destroy() { 95 stop = true; 96 97 try { 98 Thread.sleep(1000); 99 }catch(InterruptedException e) {} 100 } 101 106 protected IndexWriter getLogIndexWriter() throws IOException { 107 String logPath = getLogIndexPath(); 108 File rp = new File (logPath); 109 if(!rp.exists()) 110 rp.mkdirs(); 111 File segments = new File (logPath + File.separator + "segments"); 112 boolean bCreate = !segments.exists(); 113 return new IndexWriter(logPath,analyzer,bCreate); 114 } 115 120 protected IndexWriter getReplyIndexWriter() throws IOException { 121 String replyPath = getReplyIndexPath(); 122 File rp = new File (replyPath); 123 if(!rp.exists()) 124 rp.mkdirs(); 125 File segments = new File (replyPath + File.separator + "segments"); 126 boolean bCreate = !segments.exists(); 127 return new IndexWriter(replyPath,analyzer,bCreate); 128 } 129 135 protected int buildLogIndex(IndexWriter writer, LastInfo lastInfo) throws Exception { 136 Session ssn = ManagerBase.getSession(); 137 int logCount = 0; 138 try { 139 Date begin = new Date (lastInfo.lastLogTime); 140 String hql = "FROM " + LogForm.class.getName() + " AS log WHERE log.logTime>? ORDER BY log.logTime ASC"; 141 Query query = ssn.createQuery(hql); 142 query.setDate(0,new Date (lastInfo.lastLogTime)); 143 Iterator logs = query.list().iterator(); 144 while(logs.hasNext()) { 145 LogForm log = (LogForm)logs.next(); 146 if(!log.getLogTime().after(begin) || log.getContent()==null) 147 continue; 148 Document doc = new Document(); 149 doc.add(Field.Keyword("logId", Integer.toString(log.getId()))); 150 doc.add(new Field("author", log.getOwnerName(),false,true,false)); 151 doc.add(new Field("siteId", Integer.toString(log.getSite().getId()),false,true,false)); 152 doc.add(new Field("categoryId", Integer.toString(log.getCategoryId()),false,true, false)); 153 doc.add(Field.UnStored("title", StringUtils.deleteWhitespace(log.getTitle()))); 154 doc.add(Field.UnStored("content", log.getContent())); 155 doc.add(new Field("logDate", DateField.dateToString(log.getLogTime()),false,true,false)); 156 writer.addDocument(doc); 157 logCount ++; 158 lastInfo.lastLogTime = log.getLogTime().getTime(); 160 161 } 162 }finally { 163 ManagerBase.closeSession(ssn); 164 } 165 return logCount; 166 } 167 172 protected int buildReplyIndex(IndexWriter writer, LastInfo lastInfo) throws Exception { 173 Session ssn = ManagerBase.getSession(); 174 int replyCount = 0; 175 try { 176 Date begin = new Date (lastInfo.lastReplyTime); 177 String hql = "FROM " + ReplyForm.class.getName() + " AS r WHERE r.writeTime>? ORDER BY r.writeTime ASC"; 178 Query query = ssn.createQuery(hql); 179 query.setDate(0,new Date (lastInfo.lastReplyTime)); 180 Iterator replies = query.list().iterator(); 181 while(replies.hasNext()) { 182 ReplyForm reply = (ReplyForm)replies.next(); 183 if(!reply.getWriteTime().after(begin)) 184 continue; 185 Document doc = new Document(); 186 doc.add(Field.Keyword("replyId", Integer.toString(reply.getId()))); 187 doc.add(Field.Keyword("logId", Integer.toString(reply.getLogId()))); 188 doc.add(new Field("categoryId", Integer.toString(reply.getLog().getCategoryId()),false,true, false)); 189 doc.add(new Field("author", reply.getAuthorName(),false,true,false)); 190 doc.add(new Field("siteId", Integer.toString(reply.getSite().getId()),false,true,false)); 191 doc.add(Field.UnStored("content", reply.getContent())); 192 doc.add(new Field("replyDate", DateField.dateToString(reply.getWriteTime()),false,true,false)); 193 writer.addDocument(doc); 194 replyCount++; 195 lastInfo.lastReplyTime = System.currentTimeMillis(); 197 198 } 199 }finally { 200 ManagerBase.closeSession(ssn); 201 } 202 return replyCount; 203 } 204 205 private boolean stop = false; 206 207 210 public void run() { 211 Log log = LogFactory.getLog(SearchEnginePlugIn.class); 212 while(!stop) { 213 IndexWriter logWriter = null; 214 IndexWriter replyWriter = null; 215 try { 216 LastInfo lastInfo = getLastInfo(); 218 logWriter = getLogIndexWriter(); 220 int lc = buildLogIndex(logWriter,lastInfo); 221 logWriter.optimize(); 222 log.info("Build "+lc +" log's index success."); 223 replyWriter = getReplyIndexWriter(); 225 int rc = buildReplyIndex(replyWriter,lastInfo); 226 replyWriter.optimize(); 227 log.info("Build "+rc +" reply's index success."); 228 229 saveLastInfo(lastInfo); 230 }catch(Exception e) { 231 log.error("SearchEnginePlugIn.AutoIndexBuild",e); 232 }catch(Throwable t) { 233 log.fatal("SearchEnginePlugIn.AutoIndexBuild",t); 234 }finally { 235 if(logWriter!=null) 236 try { 237 logWriter.close(); 238 }catch(Exception e) {} 239 if(replyWriter!=null) 240 try { 241 replyWriter.close(); 242 }catch(Exception e) {} 243 try { 245 int i; 246 for(i=0;!stop&&i<2400;i++) 247 Thread.sleep(activeInterval*1000/2400); 248 if(i<2400) 249 break; 250 }catch(Exception e) { 251 break; 252 } 253 } 254 } 255 log.info("SearchEnginePlugIn terminal."); 256 } 257 262 private LastInfo getLastInfo() throws Exception { 263 File f_status = new File (getStatusFile()); 264 Properties p = null; 265 if(f_status.exists()) { 266 InputStream is = null; 267 try { 268 is = new FileInputStream (f_status); 269 p = new Properties (); 270 p.load(is); 271 }finally { 272 if(is!=null) 273 is.close(); 274 } 275 } 276 return new LastInfo(p); 277 } 278 283 private void saveLastInfo(LastInfo props) throws IOException { 284 File f_status = new File (getStatusFile()); 285 OutputStream out = null; 286 try { 287 out = new FileOutputStream (f_status); 288 props.getProperties().store(out,"SearchEngine Data Saved."); 289 }finally { 290 if(out!=null) 291 out.close(); 292 } 293 } 294 298 private class LastInfo{ 299 public final static String REPLY_KEY = "LAST_REPLY_TIME"; 300 public final static String LOG_KEY = "LAST_LOG_TIME"; 301 public LastInfo(Properties p) { 302 if(p!=null) { 303 try { 304 lastReplyTime = Long.parseLong(p.getProperty(REPLY_KEY,"0")); 305 }catch(Exception e) {} 306 try { 307 lastLogTime = Long.parseLong(p.getProperty(LOG_KEY,"0")); 308 }catch(Exception e) {} 309 } 310 } 311 public Properties getProperties() { 312 Properties ps = new Properties (); 313 ps.setProperty(LOG_KEY,String.valueOf(lastLogTime)); 314 ps.setProperty(REPLY_KEY,String.valueOf(lastReplyTime)); 315 return ps; 316 } 317 public long lastReplyTime; 318 public long lastLogTime; 319 } 320 321 322 public int getActiveInterval() { 323 return activeInterval; 324 } 325 public void setActiveInterval(int activeInterval) { 326 this.activeInterval = activeInterval; 327 } 328 332 public static String getLogIndexPath() { 333 if(logIndexPath.toUpperCase().startsWith("/WEB-INF")) 334 return servlet.getServletContext().getRealPath(logIndexPath); 335 return logIndexPath; 336 } 337 public void setLogIndexPath(String indexPath) { 338 logIndexPath = indexPath; 339 } 340 344 public static String getReplyIndexPath() { 345 if(replyIndexPath.toUpperCase().startsWith("/WEB-INF")) 346 return servlet.getServletContext().getRealPath(replyIndexPath); 347 return replyIndexPath; 348 } 349 public void setReplyIndexPath(String indexPath) { 350 replyIndexPath = indexPath; 351 } 352 356 public String getStatusFile() { 357 if(statusFile.startsWith("/")) 358 return servlet.getServletContext().getRealPath(statusFile); 359 return statusFile; 360 } 361 public void setStatusFile(String statusFile) { 362 this.statusFile = statusFile; 363 } 364 public static Analyzer getAnalyzer() { 365 return analyzer; 366 } 367 public String getAnalyzerClass() { 368 return analyzerClass; 369 } 370 public void setAnalyzerClass(String analyzerClass) { 371 this.analyzerClass = analyzerClass; 372 } 373 } 374 | Popular Tags |