edu.nps.moves.mmowgli.hibernate.SearchPopup.java Source code

Java tutorial

Introduction

Here is the source code for edu.nps.moves.mmowgli.hibernate.SearchPopup.java

Source

/*
  Copyright (C) 2010-2014 Modeling Virtual Environments and Simulation
  (MOVES) Institute at the Naval Postgraduate School (NPS)
  http://www.MovesInstitute.org and http://www.nps.edu
     
  This file is part of Mmowgli.
      
  Mmowgli is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  any later version.
    
  Mmowgli is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
    
  You should have received a copy of the GNU General Public License
  along with Mmowgli in the form of a file named COPYING.  If not,
  see <http://www.gnu.org/licenses/>
*/

package edu.nps.moves.mmowgli.hibernate;

import static edu.nps.moves.mmowgli.MmowgliEvent.ACTIONPLANSHOWCLICK;
import static edu.nps.moves.mmowgli.MmowgliEvent.CARDCLICK;
import static edu.nps.moves.mmowgli.MmowgliEvent.SHOWUSERPROFILECLICK;

import java.util.*;

import org.getopt.luke.TermInfo;

import com.vaadin.data.Container;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.util.BeanItemContainer;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Table.ColumnGenerator;

import edu.nps.moves.mmowgli.AppEvent;
import edu.nps.moves.mmowgli.Mmowgli2UI;
import edu.nps.moves.mmowgli.MmowgliController;
import edu.nps.moves.mmowgli.components.*;
import edu.nps.moves.mmowgli.components.WordCloudPanel.Word;
import edu.nps.moves.mmowgli.components.WordCloudPanel.WordButton;
import edu.nps.moves.mmowgli.components.WordCloudPanel.WordOrder;
import edu.nps.moves.mmowgli.db.ActionPlan;
import edu.nps.moves.mmowgli.db.Card;
import edu.nps.moves.mmowgli.db.User;
import edu.nps.moves.mmowgli.markers.*;

/**
 * SearchPopup.java
 * Created on May 30, 2011
 *
 * MOVES Institute
 * Naval Postgraduate School, Monterey, CA, USA
 * www.nps.edu
 *
 * @author Mike Bailey, jmbailey@nps.edu
 * @version $Id: SearchPopup.java 3056 2013-11-07 20:26:25Z jmbailey $
 */
public class SearchPopup extends Window implements ClickListener {
    private static final long serialVersionUID = -3173608977165486650L;
    private static String USERTYPEKEY = "Player";
    private static String CARDTYPEKEY = "Card";
    private static String ACTIONPLANTYPEKEY = "Action Plan";

    private TextField tf;
    private FireableButton searchButt;
    private Table resultsTable;
    private Label statusLabel;
    private Thread searchThread = null;
    private searcher searcherObj = null;
    private Button closeButt;
    private ClickListener closeListener;
    private String initialText = null;

    Map<String, Word> working = new HashMap<String, Word>();
    Map<String, Word> map = new HashMap<String, Word>();
    String[][] stemSets = { { "soma", "somal", "somaly", "somalia", "somalian", "somali" },
            { "pira", "pirat", "piracy", "piraci", "pirate" }, { "acceler", "accelerate" }, { "anoth", "another" },
            { "countri", "country" }, { "resourc", "resource" }, { "auster", "austere" }, { "bogu", "bogus" },
            { "navi", "navy" } };

    public SearchPopup() {
        this(null);
    }

    @SuppressWarnings("serial")
    public SearchPopup(String startingText) {
        super("Search for Players, Action Plans, Idea Cards");
        //setModal(true);   better not to be model

        this.initialText = startingText;
        setWidth("635px");
        setHeight("600px");
        center();

        VerticalLayout vLay = new VerticalLayout();
        vLay.setSizeFull();
        vLay.setMargin(true);
        vLay.setSpacing(true);
        setContent(vLay);

        WordCloudPanel wcPan = new WordCloudPanel(new ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                WordButton wb = (WordButton) event.getButton();
                tf.setValue(wb.word.text);
                searchButt.fireClick();
            }
        });
        wcPan.setImmediate(true);

        TermInfo[] tinfo = SearchManager.getHighFrequencyTerms();
        List<Word> wdLis = new ArrayList<Word>(tinfo.length);

        for (TermInfo inf : tinfo) {
            String txt = inf.term.text();
            Word wd = new Word(txt, inf.docFreq);
            wdLis.add(wd);
        }

        // V7
        /*
        TermStats[] tstats = SearchManager.getHighFrequencyTerms();
        List<Word> wdLis = new ArrayList<Word>(tstats.length);
        for(TermStats ts : tstats) {
          String txt = new String(ts.termtext.utf8ToString());
          Word wd = new Word(txt,ts.docFreq);
          wdLis.add(wd);
        }
        */

        wdLis = finalFilter(wdLis);
        // dumpList(wLis);
        wcPan.setWordData(wdLis, WordOrder.ALPHA);
        wcPan.setWidth("590px"); // won't work in ie"100%");
        vLay.addComponent(wcPan);

        HorizontalLayout topHL = new HorizontalLayout();
        vLay.addComponent(topHL);
        topHL.setWidth("100%");
        topHL.setMargin(true);
        topHL.setSpacing(true);

        topHL.addComponent(tf = new TextField());
        tf.addValueChangeListener(new TextFieldChangeListener());
        tf.setWidth("100%");
        //tf.setInputPrompt("Enter search terms");
        tf.setImmediate(true);
        tf.setTextChangeTimeout(5000);
        topHL.setExpandRatio(tf, 1.0f);
        if (startingText != null)
            tf.setValue(startingText);

        searchButt = new FireableButton("Search", this);
        topHL.addComponent(searchButt);
        searchButt.setClickShortcut(KeyCode.ENTER);

        vLay.addComponent(statusLabel = new HtmlLabel("&nbsp;"));
        statusLabel.setImmediate(true);

        resultsTable = new Table();
        resultsTable.addStyleName("m-actiondashboard-table");
        resultsTable.setImmediate(true);
        vLay.addComponent(resultsTable);
        resultsTable.setHeight("100%");
        resultsTable.setWidth("99%");
        vLay.setExpandRatio(resultsTable, 1.0f);

        BeanItemContainer<SearchResult> bCont = new BeanItemContainer<SearchResult>(SearchResult.class);
        bCont.addBean(new SearchResult("", "", "")); // fix for 6.7.0 bug
        resultsTable.addGeneratedColumn("text", new ToolTipAdder());
        resetTable(bCont);

        resultsTable.setNewItemsAllowed(false);
        resultsTable.setSelectable(true);

        resultsTable.addItemClickListener(new ItemClickListener() {
            @Override
            @MmowgliCodeEntry
            @HibernateOpened
            @HibernateClosed
            public void itemClick(ItemClickEvent event) {
                HSess.init();
                @SuppressWarnings("unchecked")
                BeanItem<SearchResult> bi = (BeanItem<SearchResult>) event.getItem();
                SearchResult sr = bi.getBean();
                MmowgliController controller = Mmowgli2UI.getGlobals().getController();
                if (sr.getType().equals(USERTYPEKEY))
                    controller.miscEventTL(new AppEvent(SHOWUSERPROFILECLICK, SearchPopup.this, sr.getHibId()));
                else if (sr.getType().equals(ACTIONPLANTYPEKEY))
                    controller.miscEventTL(new AppEvent(ACTIONPLANSHOWCLICK, SearchPopup.this, sr.getHibId()));
                else
                    controller.miscEventTL(new AppEvent(CARDCLICK, SearchPopup.this, sr.getHibId()));
                HSess.close();

                closeListener.buttonClick(null);
            }
        });

        vLay.addComponent(closeButt = new Button("Close"));
        vLay.setComponentAlignment(closeButt, Alignment.TOP_RIGHT);
        closeButt.addClickListener(closeListener = new ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                if (searchThread != null)
                    searcherObj.killed = true;
                //V7 SearchPopup.this.getParent().removeWindow(SearchPopup.this);
                SearchPopup.this.close();
            }
        });
    }

    private List<Word> finalFilter(List<Word> wLis) {
        working.clear();
        for (Word w : wLis) {
            big: {
                for (int i = 0; i < stemSets.length; i++) {
                    String[] line = stemSets[i];
                    for (String line1 : line) {
                        if (w.text.equalsIgnoreCase(line1)) {
                            handleException(w, i);
                            break big;
                        }
                    } // j
                } // i
                if (working.get(w.text) == null) // check for duplicates
                    working.put(w.text, w);
            } // big
        }

        wLis.clear();
        for (Iterator<Word> itr = working.values().iterator(); itr.hasNext();)
            wLis.add(itr.next());
        return wLis;
    }

    private void handleException(Word w, int idx) {
        int len = stemSets[idx].length;
        w.text = stemSets[idx][len - 1]; // use last in list
        Word mapped = map.get(w.text);
        if (mapped == null) {
            map.put(w.text, w);
            working.put(w.text, w);
        } else
            mapped.freq += w.freq;
    }

    //  private void dumpList(ArrayList<Word>lis)
    //  {
    //    for(Iterator<Word>itr = lis.iterator();itr.hasNext();) {
    //      Word w = itr.next();
    //      System.out.println(w.text+" --> "+w.freq);
    //    }
    //  }

    private void resetTable(Container cont) {
        resultsTable.setContainerDataSource(cont);
        resultsTable.setVisibleColumns((Object[]) new String[] { "typeAndId", "text" });
        resultsTable.setColumnHeaders(new String[] { "Item", "Content" });
        resultsTable.setColumnWidth("typeAndId", 100);
        resultsTable.setColumnExpandRatio("text", 1.0f);
        resultsTable.setImmediate(true);
    }

    @SuppressWarnings("serial")
    class ToolTipAdder implements ColumnGenerator {
        @Override
        public Object generateCell(Table source, Object itemId, Object columnId) {
            SearchResult res = (SearchResult) itemId;
            Label lab = new Label(res.getText());
            lab.setDescription(res.getText());
            return lab;
        }
    }

    public class SearchResult {
        private Object hibId = "";
        private String type = "";
        private String typeAndId;
        private String text = "";
        private String type2 = "";

        public SearchResult() {
        }

        public SearchResult(Object hibId, String type, String text) {
            this.hibId = hibId;
            this.type = type;
            this.text = text;
            handleTypeAndId();
        }

        public SearchResult(Object hibId, String type, String text, String type2) {
            this.hibId = hibId;
            this.type = type;
            this.text = text;
            this.type2 = type2;
            handleTypeAndId();
        }

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        public String getType() {
            return type;
        }

        public void setType(String type) {
            this.type = type;
            handleTypeAndId();
        }

        public void setType2(String type2) {
            this.type2 = type2;
            handleTypeAndId();
        }

        public Object getHibId() {
            return hibId;
        }

        public void setHibId(Object hibId) {
            this.hibId = hibId;
            handleTypeAndId();
        }

        public String getTypeAndId() {
            return typeAndId;
        }

        public void setTypeAndId(String typeAndId) {
            this.typeAndId = typeAndId;
        }

        private void handleTypeAndId() {
            typeAndId = type + " " + hibId.toString() + " " + type2;
            typeAndId = typeAndId.trim();
        }
    }

    // Search clicked
    @Override
    @MmowgliCodeEntry
    @HibernateConditionallyOpened
    @HibernateConditionallyClosed
    public void buttonClick(ClickEvent event) {
        String terms = tf.getValue().toString();
        if (terms == null || terms.length() <= 0)
            return;
        statusLabel.setValue("<span style='color:red;'>Searching...</span>");
        tf.selectAll();
        tf.focus();

        String[] tokenArray = terms.trim().split("\\s+");
        Object sessKey = HSess.checkInit();
        User me = Mmowgli2UI.getGlobals().getUserTL();

        // test Do it in another thread
        /*
        searchThread = new Thread(searcherObj=new searcher(me,tokenArray),"Searcher");
        searchThread.setPriority(Thread.NORM_PRIORITY);
        searchThread.start();
        */
        searcherObj = new searcher(me, tokenArray);
        searcherObj.run();
        HSess.checkClose(sessKey);
    }

    private class searcher implements Runnable {
        private String[] tokenArray;
        public boolean killed = false;
        private User me;

        public searcher(User me, String[] tokenArray) {
            this.me = me;
            this.tokenArray = tokenArray;
        }

        @Override
        public void run() {
            Collection<?> results = SearchManager.searchAll(tokenArray); // do the search
            BeanItemContainer<SearchResult> bCont = new BeanItemContainer<SearchResult>(SearchResult.class);
            if (!results.isEmpty()) {
                statusLabel.setValue("Found " + results.size());
                Iterator<?> itr = results.iterator();

                // Need to know if I'm a game master

                while (itr.hasNext()) {
                    if (killed)
                        return;
                    Object o = itr.next();
                    SearchResult sr = new SearchResult();
                    if (o instanceof Card) {
                        Card c = (Card) o;
                        if (c.isHidden() && !me.isGameMaster())
                            continue;
                        sr.setHibId(c.getId());
                        sr.setType(CARDTYPEKEY);
                        sr.setType2(c.getCardType().getTitle());
                        sr.setText(c.getText());
                    } else if (o instanceof User) {
                        User u = (User) o;
                        if (u.isAccountDisabled())
                            continue;
                        sr.setHibId(u.getId());
                        sr.setType(USERTYPEKEY);
                        sr.setText(u.getUserName() + ", " + u.getLocation() + ", " + u.getExpertise() + ", "
                                + u.getAffiliation());
                    } else if (o instanceof ActionPlan) {
                        ActionPlan ap = (ActionPlan) o;
                        if (ap.isHidden())
                            continue;
                        sr.setHibId(ap.getId());
                        sr.setType(ACTIONPLANTYPEKEY);
                        sr.setText(ap.getTitle());
                    }
                    bCont.addItem(sr);
                }
            }
            if (bCont.size() <= 0) {
                bCont.addBean(new SearchResult("", "", "")); // fix for 6.7.0 bug
                statusLabel.setValue("Found none.");
            }
            if (!killed) {
                resetTable(bCont);
                Mmowgli2UI.getAppUI().access(new Runnable() {
                    public void run() {
                        Mmowgli2UI.getAppUI().push();
                    }
                });
            }
            searchThread = null;
        }
    }

    @Override
    public void attach() {
        super.attach();
        tf.focus();

        if (initialText != null)
            searchButt.fireClick();
    }

    @SuppressWarnings("serial")
    private class FireableButton extends Button {
        public FireableButton(String s, ClickListener lis) {
            super(s, lis);
        }

        @Override
        public void fireClick() {
            super.fireClick();
        }
    }

    @SuppressWarnings("serial")
    class TextFieldChangeListener implements Property.ValueChangeListener {
        @Override
        public void valueChange(ValueChangeEvent event) {
            Object o = tf.getValue();
            // First time through, searchButt is null, and we don't want to do a double fire anyway, so it's all good
            if (searchButt != null && o != null && o.toString().length() > 0)
                searchButt.fireClick();
        }
    }
}