001: /*
002: * Copyright (c) JForum Team
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms,
006: * with or without modification, are permitted provided
007: * that the following conditions are met:
008: *
009: * 1) Redistributions of source code must retain the above
010: * copyright notice, this list of conditions and the
011: * following disclaimer.
012: * 2) Redistributions in binary form must reproduce the
013: * above copyright notice, this list of conditions and
014: * the following disclaimer in the documentation and/or
015: * other materials provided with the distribution.
016: * 3) Neither the name of "Rafael Steil" nor
017: * the names of its contributors may be used to endorse
018: * or promote products derived from this software without
019: * specific prior written permission.
020: *
021: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
022: * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
023: * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
024: * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
025: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR
026: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
027: * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
028: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
029: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES
030: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
031: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
032: * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
033: * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
034: * IN CONTRACT, STRICT LIABILITY, OR TORT
035: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
036: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
037: * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
038: *
039: * Created on 23/07/2007 15:14:27
040: *
041: * The JForum Project
042: * http://www.jforum.net
043: */
044: package net.jforum.view.admin;
045:
046: import java.io.File;
047: import java.io.IOException;
048: import java.util.Date;
049: import java.util.GregorianCalendar;
050:
051: import net.jforum.context.RequestContext;
052: import net.jforum.context.ResponseContext;
053: import net.jforum.exceptions.ForumException;
054: import net.jforum.repository.ForumRepository;
055: import net.jforum.search.LuceneManager;
056: import net.jforum.search.LuceneReindexArgs;
057: import net.jforum.search.LuceneReindexer;
058: import net.jforum.search.LuceneSettings;
059: import net.jforum.util.preferences.ConfigKeys;
060: import net.jforum.util.preferences.SystemGlobals;
061: import net.jforum.util.preferences.TemplateKeys;
062:
063: import org.apache.commons.lang.StringUtils;
064: import org.apache.lucene.index.IndexReader;
065:
066: import freemarker.template.SimpleHash;
067: import freemarker.template.Template;
068:
069: /**
070: * @author Rafael Steil
071: * @version $Id: LuceneStatsAction.java,v 1.24 2007/09/09 16:43:55 rafaelsteil Exp $
072: */
073: public class LuceneStatsAction extends AdminCommand {
074: /**
075: * @see net.jforum.Command#list()
076: */
077: public void list() {
078: IndexReader reader = null;
079:
080: try {
081: File indexDir = new File(SystemGlobals
082: .getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH));
083:
084: this .setTemplateName(TemplateKeys.SEARCH_STATS_LIST);
085: boolean isInformationAvailable = true;
086:
087: try {
088: reader = IndexReader.open(indexDir);
089: } catch (IOException e) {
090: isInformationAvailable = false;
091: }
092:
093: this .context.put("isInformationAvailable",
094: isInformationAvailable);
095: this .context.put("indexExists", IndexReader
096: .indexExists(indexDir));
097: this .context
098: .put(
099: "currentlyIndexing",
100: "1"
101: .equals(SystemGlobals
102: .getValue(ConfigKeys.LUCENE_CURRENTLY_INDEXING)));
103:
104: if (isInformationAvailable) {
105: this .context.put("isLocked", IndexReader
106: .isLocked(indexDir.getAbsolutePath()));
107: this .context.put("lastModified", new Date(IndexReader
108: .lastModified(indexDir)));
109: this .context.put("indexLocation", indexDir
110: .getAbsolutePath());
111: this .context.put("totalMessages", new Integer(
112: ForumRepository.getTotalMessages()));
113: this .context.put("indexVersion", new Long(reader
114: .getVersion()));
115: this .context.put("numberOfDocs", new Integer(reader
116: .numDocs()));
117: }
118: } catch (IOException e) {
119: throw new ForumException(e);
120: } finally {
121: if (reader != null) {
122: try {
123: reader.close();
124: } catch (Exception e) {
125: }
126: }
127: }
128: }
129:
130: public void createIndexDirectory() throws Exception {
131: this .settings().createIndexDirectory(
132: SystemGlobals
133: .getValue(ConfigKeys.LUCENE_INDEX_WRITE_PATH));
134: this .list();
135: }
136:
137: public void reconstructIndexFromScratch() {
138: LuceneReindexArgs args = this .buildReindexArgs();
139: boolean recreate = "recreate".equals(this .request
140: .getParameter("indexOperationType"));
141:
142: LuceneReindexer reindexer = new LuceneReindexer(
143: this .settings(), args, recreate);
144: reindexer.startBackgroundProcess();
145:
146: this .list();
147: }
148:
149: public void cancelIndexing() {
150: SystemGlobals.setValue(ConfigKeys.LUCENE_CURRENTLY_INDEXING,
151: "0");
152: this .list();
153: }
154:
155: public void luceneNotEnabled() {
156: this .setTemplateName(TemplateKeys.SEARCH_STATS_NOT_ENABLED);
157: }
158:
159: public Template process(RequestContext request,
160: ResponseContext response, SimpleHash context) {
161: if (!this .isSearchEngineLucene()) {
162: this .ignoreAction();
163: this .luceneNotEnabled();
164: }
165:
166: return super .process(request, response, context);
167: }
168:
169: private boolean isSearchEngineLucene() {
170: return LuceneManager.class
171: .getName()
172: .equals(
173: SystemGlobals
174: .getValue(ConfigKeys.SEARCH_INDEXER_IMPLEMENTATION))
175: || this .settings() == null;
176: }
177:
178: private LuceneSettings settings() {
179: return (LuceneSettings) SystemGlobals
180: .getObjectValue(ConfigKeys.LUCENE_SETTINGS);
181: }
182:
183: private LuceneReindexArgs buildReindexArgs() {
184: Date fromDate = this .buildDateFromRequest("from");
185: Date toDate = this .buildDateFromRequest("to");
186:
187: int firstPostId = 0;
188: int lastPostId = 0;
189:
190: if (!StringUtils.isEmpty(this .request
191: .getParameter("firstPostId"))) {
192: firstPostId = this .request.getIntParameter("firstPostId");
193: }
194:
195: if (!StringUtils.isEmpty(this .request
196: .getParameter("lastPostId"))) {
197: lastPostId = this .request.getIntParameter("lastPostId");
198: }
199:
200: return new LuceneReindexArgs(fromDate, toDate, firstPostId,
201: lastPostId, "yes".equals(this .request
202: .getParameter("avoidDuplicatedRecords")),
203: this .request.getIntParameter("type"));
204: }
205:
206: private Date buildDateFromRequest(String prefix) {
207: String day = this .request.getParameter(prefix + "Day");
208: String month = this .request.getParameter(prefix + "Month");
209: String year = this .request.getParameter(prefix + "Year");
210:
211: String hour = this .request.getParameter(prefix + "Hour");
212: String minutes = this .request.getParameter(prefix + "Minutes");
213:
214: Date date = null;
215:
216: if (!StringUtils.isEmpty(day) && !StringUtils.isEmpty(month)
217: && !StringUtils.isEmpty(year)
218: && !StringUtils.isEmpty(hour)
219: && !StringUtils.isEmpty(minutes)) {
220: date = new GregorianCalendar(Integer.parseInt(year),
221: Integer.parseInt(month) - 1,
222: Integer.parseInt(year), Integer.parseInt(hour),
223: Integer.parseInt(minutes), 0).getTime();
224: }
225:
226: return date;
227: }
228: }
|