Package com.uwyn.drone.webui.elements.pub

Source Code of com.uwyn.drone.webui.elements.pub.Search$SearchBean

/*
* Copyright 2002-2005 Uwyn bvba/sprl <info[remove] at uwyn dot com>
* Distributed under the terms of the GNU Lesser General Public
* License, v2.1 or later
*
* $Id: Search.java 2003 2005-06-04 14:33:27Z gbevin $
*/
package com.uwyn.drone.webui.elements.pub;

import java.util.*;
import org.apache.lucene.search.*;

import com.uwyn.drone.DroneConfig;
import com.uwyn.drone.core.Bot;
import com.uwyn.drone.core.BotsRunner;
import com.uwyn.drone.core.Channel;
import com.uwyn.drone.tools.LocaleProvider;
import com.uwyn.drone.tools.LocaleProviderConfig;
import com.uwyn.drone.tools.SearchTool;
import com.uwyn.rife.config.Config;
import com.uwyn.rife.engine.Element;
import com.uwyn.rife.site.ConstrainedProperty;
import com.uwyn.rife.site.PagedNavigation;
import com.uwyn.rife.site.Validation;
import com.uwyn.rife.site.ValidationError;
import com.uwyn.rife.template.Template;
import com.uwyn.rife.tools.ExceptionUtils;
import com.uwyn.rife.tools.Localization;
import com.uwyn.rife.tools.SortListComparables;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.DateField;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.MultiReader;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.search.highlight.QueryScorer;
import org.apache.lucene.search.highlight.SimpleHTMLFormatter;

public class Search extends Element
{
  private static final int         LIMIT = 100;
  private static final int         SPAN = 5;

  public static final SimpleDateFormat   INPUT_DATE_FORMAT_SHORT = new SimpleDateFormat("dd/MM/yyyy");
  public static final SimpleDateFormat   LUCENE_DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");

    public SimpleDateFormat  mDateFormat;
  public SimpleDateFormat  mOutputTimeFormat;
    public SimpleDateFormat  mOutputDateFormat;
 
  public LocaleProvider  mLocaleProvider = LocaleProviderConfig.SINGLETON;

  private Template   mTemplate = null;
  private HashMap    mNickColors = new HashMap();
  private int     mColorCounter = 0;
  private String     mCurrentDate = null;
  private String     mCurrentBotname = null;
  private String     mCurrentServername = null;
  private String     mCurrentChannelname = null;

  static
  {
    INPUT_DATE_FORMAT_SHORT.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
    LUCENE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
  }
 
  public void setLocaleProvider(LocaleProvider localeProvider)
  {
    mLocaleProvider = localeProvider;
  }

  public void initialize()
  {
    mTemplate = getHtmlTemplate("drone.pub.search");

    Locale locale = mLocaleProvider.retrieveLocale(this, mTemplate);
    mDateFormat = new SimpleDateFormat("yyyyMMdd", locale);
    mOutputTimeFormat = new SimpleDateFormat("HH:mm", locale);
    mOutputDateFormat = new SimpleDateFormat("dd-MMMM-yyyy", locale);
   
    mDateFormat.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
    mOutputTimeFormat.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
    mOutputDateFormat.setTimeZone(TimeZone.getTimeZone(DroneConfig.getTimezone()));
  }

  public void processElement()
  {
    SearchBean bean =  (SearchBean)getNamedInputBean("SearchBean");
    if (!bean.isValidSearch())
    {
      bean = (SearchBean)getNamedInputBean("OffsetBean");
    }

    if (bean.isValidSearch())
    {
      doSearch(bean, getInputInt("offset", 0));

      return;
    }

    print(mTemplate);
  }

  private void doSearch(SearchBean submission, int offset)
  {
    assert submission != null;

    BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE);

    SearchTool     search_tool = new SearchTool();
    BooleanQuery   query = search_tool.getSearchQuery(submission);

    setNamedOutputBean("OffsetBean", submission);

    if (submission.isValidSearch() && query != null)
    {
      Hits hits = null;

      try
      {
        MultiReader       reader = null;
        ParallelMultiSearcher   searcher = null;

        List           searchers = new ArrayList();
        List           readers = new ArrayList();
        Collection         bots = BotsRunner.getRepInstance().getBots();
        Iterator         iter = bots.iterator();

        while (iter.hasNext())
        {
          Bot bot = (Bot)iter.next();

          Iterator channels_it = bot.getJoinedChannels().iterator();
          while (channels_it.hasNext())
          {
            Channel     channel = ((Channel)channels_it.next());
            StringBuffer   key = new StringBuffer();
            key
              .append(Config.getRepInstance().getString("LUCENE_DIR"))
              .append(File.separator)
              .append(bot.getName())
              .append("-")
              .append(bot.getServer().getServerName())
              .append("-")
              .append(channel.getName().substring(1));
           
            if (submission.getChannel() == null ||
              submission.getChannel().equals(""))
            {
              IndexReader   r = IndexReader.open(key.toString());
              IndexSearcher   s = new IndexSearcher(r);

              searchers.add(s);
              readers.add(r);
            }
            else
            {
              String submissionChannel = submission.getChannel().substring(submission.getChannel().indexOf("#"));
              if (channel.getName().equals(submissionChannel))
              {
                IndexReader   r = IndexReader.open(key.toString());
                IndexSearcher   s = new IndexSearcher(r);

                searchers.add(s);
                readers.add(r);
              }
            }
          }
        }

        IndexSearcher[] searcherArray = (IndexSearcher[])searchers.toArray(new IndexSearcher[0]);
        IndexReader[]   readerArray = (IndexReader[])readers.toArray(new IndexReader[0]);

        searcher = new ParallelMultiSearcher(searcherArray);
        reader = new MultiReader(readerArray);

        SortField dateSort = new SortField("momentDateSort", SortField.AUTO, true);
        SortField timeSort = new SortField("momentTimeSort", SortField.AUTO, false);

        hits = searcher.search(query, new Sort(new SortField[] { dateSort, timeSort }));

        // only highlight in the message
        Query           keywordQuery = search_tool.getKeywordQuery();
        Highlighter       highlighter = null;
        if (keywordQuery != null)
        {
          Query         rewritten_query =  keywordQuery.rewrite(reader);
          SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class=\"highlighted\">", "</span>");
         
          highlighter = new Highlighter(formatter, new QueryScorer(rewritten_query));
        }

        for (int i = offset; i < LIMIT + offset; i++)
        {
          if (i >= hits.length())
          {
            // handle partial full pages
            break;
          }

          Document doc = hits.doc(i);

          // pull in our values
          String   nickname = doc.getField("nickname").stringValue();
          String   message = doc.getField("message").stringValue();
          String   channelname = doc.getField("channel").stringValue();
          String   botname = doc.getField("botname").stringValue();
          String   servername = doc.getField("servername").stringValue();
          Date   moment = DateField.stringToDate(doc.getField("moment").stringValue());
          String   day = mOutputDateFormat.format(moment);
          String   time = mOutputTimeFormat.format(moment);
          String   outputday = mDateFormat.format(moment);

          // stolen directly from ChannelLog
          String nickcolor = (String)mNickColors.get(nickname);
          if (null == nickcolor)
          {
            nickcolor = ChannelLog.NICK_COLORS[mColorCounter++%ChannelLog.NICK_COLORS.length];
            mNickColors.put(nickname, nickcolor);
          }
          mTemplate.setValue("bgcolor", nickcolor);

          channelname = "#" + channelname;

          // output a header if we're no longer in our little
          // section of the world, i.e. date, server, channel, or
          // bot changed
          if (mCurrentDate == null || !mCurrentDate.equals(day) ||
            mCurrentServername == null || !mCurrentServername.equals(servername) ||
            mCurrentBotname == null || !mCurrentBotname.equals(botname) ||
            mCurrentChannelname == null || !mCurrentChannelname.equals(channelname))
          {
            mTemplate.setValue("day", day);
            mTemplate.setValue("botname", botname);
            mTemplate.setValue("servername", servername);
            mTemplate.setValue("channelname", channelname);

            try
            {
              SearchBean bean = new SearchBean();
              bean.setKeyword(submission.getKeyword());
              bean.setChannel(botname + " - " + channelname);
              bean.setDate(INPUT_DATE_FORMAT_SHORT.format(mDateFormat.parse(outputday)));

              setNamedOutputBean("SearchBean", bean);
            }
            catch (ParseException e)
            {
              Logger
                .getLogger("com.uwyn.drone.webui.elements.pub")
                .severe(ExceptionUtils.getExceptionStackTrace(e));
            }

            setOutput("day", outputday);
            setOutput("channelname", channelname);
            setOutput("botname", botname);
            setExitQuery(mTemplate, "show_channel_log", null, null);

            mTemplate.setBlock("day_header", "day_header");

            mCurrentDate = day;
            mCurrentServername = servername;
            mCurrentBotname = botname;
            mCurrentChannelname = channelname;
          }
          else
          {
            mTemplate.setValue("day_header", "");
          }

          // output the message
          mTemplate.setValue("time", time);

          // translate the \u0001ACTION command which corresponds to
          // /me so that the user's nickname is used instead
          StringBuffer message_buf = new StringBuffer();
          if (message.startsWith(ChannelLog.IRC_ACTION))
          {
            message_buf
              .append(nickname)
              .append(message.substring(ChannelLog.IRC_ACTION.length()));
          }
          else
          {
            message_buf.append(message);
          }

          String encoded_message = encodeHtml(message_buf.toString());

          if (highlighter != null)
          {
            TokenStream tokenStream = new StandardAnalyzer().tokenStream("message", new StringReader(encoded_message));
            String highlighted = highlighter.getBestFragments(tokenStream, encoded_message, 25, "...");

            if (!highlighted.equals(""))
            {
              encoded_message = highlighted;
            }
          }
         
          encoded_message = ChannelLog.convertUrl(encoded_message, ChannelLog.URL_HIGHLIGHT);

          Matcher email_matcher = ChannelLog.EMAIL_HIGHLIGHT.matcher(encoded_message);
          encoded_message = email_matcher.replaceAll("<a href=\"mailto:$1\">$1</a>");

          mTemplate.setValue("nickname", nickname);
          mTemplate.setValue("message", encoded_message);

          mTemplate.appendBlock("messages", "message");
        }

        searcher.close();
        reader.close();
      }
      catch (IOException e)
      {
        Logger
          .getLogger("com.uwyn.drone.webui.elements.pub")
          .severe(ExceptionUtils.getExceptionStackTrace(e));
      }

      // finalize the results
      mTemplate.appendBlock("results", "results");

      if (hits != null &&
        hits.length() > LIMIT)
      {
        PagedNavigation.generateNavigation(this, mTemplate, hits.length(), LIMIT, offset, SPAN);

        mTemplate.setBlock("ranged_table", "ranged_table");
      }
    }

    generateForm(mTemplate, submission);

    print(mTemplate);
  }

  public void doSearch()
  {
    //reset offset
    setOutput("offset", 0);

    clearNamedOutputBean("OffsetBean");

    doSearch((SearchBean)getSubmissionBean(SearchBean.class), 0);
  }

  public static class SearchBean extends Validation
  {
    private String   mKeyword = null;
    private String   mDate = null;
    private String   mBeginDate = null;
    private String   mEndDate = null;
    private String   mUser = null;
    private String   mChannel = null;

    protected void activateValidation()
    {
      BotsRunner runner = BotsRunner.getRepInstance();
      if (runner != null)
      {
        Collection bots = runner.getBots();
        Iterator iter = bots.iterator();
 
        List channels = new ArrayList();
 
        while (iter.hasNext())
        {
          Bot bot = (Bot)iter.next();
 
          Iterator channelsIter = bot.getJoinedChannels().iterator();
          while (channelsIter.hasNext())
          {
            String name = bot.getName() + " - " + ((Channel)channelsIter.next()).getName();
            channels.add(name);
          }
        }
       
        new SortListComparables().sort(channels);
 
        addConstraint(new ConstrainedProperty("channel")
                  .inList((String[])channels.toArray(new String[0])));
        addConstraint(new ConstrainedProperty("keyword").notNull(true).notEmpty(true));
      }
    }

    public boolean isValidSearch()
    {
      if (mKeyword == null ||
        (mKeyword != null && mKeyword.equals("")))
      {
        addValidationError(new ValidationError.INVALID("keyword"));
       
        return false;
      }
     
      return true;
    }

    public void   setChannel(String channel)     { mChannel = channel; }
    public String   getChannel()           { return mChannel; }
    public void   setKeyword(String keyword)     { mKeyword = keyword; }
    public String   getKeyword()           { return mKeyword; }
    public void   setDate(String date)       { mDate = date; }
    public String   getDate()             { return mDate; }
    public void   setBeginDate(String beginDate)   { mBeginDate = beginDate; }
    public String   getBeginDate()           { return mBeginDate; }
    public void   setEndDate(String endDate)     { mEndDate = endDate; }
    public String   getEndDate()           { return mEndDate; }
    public void   setUser(String user)       { mUser = user; }
    public String   getUser()             { return mUser; }
  }
}
TOP

Related Classes of com.uwyn.drone.webui.elements.pub.Search$SearchBean

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.