Changeset 5039


Ignore:
Timestamp:
04/24/14 09:59:48 (10 years ago)
Author:
yana.panchenko@uni-tuebingen.de
Message:

Language selection changed, other UI minor changes, code refactoring, scanned data location change:

sort languages by the name for the UI (before was by code)
display only those languages for selection, for which there is a corpus that has this language as the only one
create Language class to keep its data: language name and its codes in three ISO standards
separate search-result rendering into separate class
store start-end record offset in search-result
separate corpus-list rendering into a base class extended by live or cached rendering implementations
unite all scan requests into one method inside ScanCrawler?
add method in WebAppListener? for running in cache read only mode with scan crawl not scheduled (eg for testing)
separate reusable Aggregator ZK component creation into one class (ZKComp)
create SearchResultContent? class for extracting textual content of search result in defferent representations
typo in about page corrected, info in help page modified
add tooltips to prev/next buttons in search results page
move location to store scan data on server to /data/...

Location:
SRUAggregator/trunk/src/main
Files:
4 added
1 deleted
15 edited
1 copied

Legend:

Unmodified
Added
Removed
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/Aggregator.java

    r5035 r5039  
    7171    @Wire
    7272    A nextButton;
     73    @Wire
     74    Label tooltipPrevText;
     75    @Wire
     76    Label tooltipNextText;
    7377   
    7478    @Wire
     
    111115            int maxRecords = searchOptionsComposer.getMaxRecords();
    112116            String searchLang = searchOptionsComposer.getSearchLang();
     117            //searchOffset = new int[]{1, 0};
    113118            searchOffset = new int[]{1, 0};
    114             searchResultsComposer.executeSearch(selectedCorpora, maxRecords, searchString.getText(), searchOffset, searchLang);
     119            searchOffset[0] = searchOffset[0] + searchOffset[1];
     120            searchOffset[1] = maxRecords;
     121            searchResultsComposer.executeSearch(selectedCorpora, searchOffset[0], maxRecords, searchString.getText(), searchLang);
    115122            if (searchLang.equals("anylang")) {
    116123                this.weblichtTcf.setVisible(false);
     
    182189            Executions.getCurrent().sendRedirect(WEBLICHT_URL
    183190                + url, "_blank");
    184         } else {
    185             Messagebox.show("Sorry, drop-off/WebLicht error!");
    186191        }
    187192    }
     
    193198            Executions.getCurrent().sendRedirect(WEBLICHT_URL
    194199                + url, "_blank");
    195         } else {
    196             Messagebox.show("Sorry, drop-off/WebLicht error!");
    197200        }
    198201    }
     
    253256    @Listen("onClick = #srLabel")
    254257    public void onClickSearchResult(Event ev) {
     258        setupPrevNextSearchTooltips();
    255259        this.pagesVisibility.openSearchResult();
    256260        if (this.searchResultsComposer.hasSearchInProgress()) {
     
    261265            this.controlsVisibility.enableControls2();
    262266        }
     267       
    263268    }
    264269
     
    280285            int maxRecords = searchOptionsComposer.getMaxRecords();
    281286            String searchLang = searchOptionsComposer.getSearchLang();
    282             searchOffset[0] = searchOffset[0] - 2 * searchOffset[1];
     287            //searchOffset[0] = searchOffset[0] - searchOffset[1];
     288            searchOffset[0] = searchOffset[0] - maxRecords;
    283289            if (searchOffset[0] < 1) {
    284290                searchOffset[0] = 1;
    285                 searchOffset[1] = 0;
    286             }
    287             searchResultsComposer.executeSearch(selectedCorpora, maxRecords, searchString.getText(), searchOffset, searchLang);
     291            }
     292            searchOffset[1] = maxRecords;
     293            searchResultsComposer.executeSearch(selectedCorpora, searchOffset[0], maxRecords, searchString.getText(), searchLang);
    288294            if (searchLang.equals("anylang")) {
    289295                this.weblichtTcf.setVisible(false);
     
    294300        }
    295301    }
     302
    296303
    297304    @Listen("onClick = #nextButton")
     
    312319            int maxRecords = searchOptionsComposer.getMaxRecords();
    313320            String searchLang = searchOptionsComposer.getSearchLang();
    314             searchResultsComposer.executeSearch(selectedCorpora, maxRecords, searchString.getText(), searchOffset, searchLang);
     321            searchOffset[0] = searchOffset[0] + searchOffset[1];
     322            searchOffset[1] = maxRecords;
     323            searchResultsComposer.executeSearch(selectedCorpora, searchOffset[0], maxRecords, searchString.getText(), searchLang);
    315324            if (searchLang.equals("anylang")) {
    316325                this.weblichtTcf.setVisible(false);
     
    341350        LOGGER.log(Level.INFO, "Received parameter: operation[{0}], ", operationString);
    342351    }
     352
     353    private void setupPrevNextSearchTooltips() {
     354        int startHit = searchOffset[0] - searchOptionsComposer.getMaxRecords();
     355        if (startHit < 1) {
     356            startHit = 1;
     357        }
     358        int endHit = searchOffset[0] - 1;
     359        tooltipPrevText.setValue("hits " +
     360                    startHit + "-" + endHit);
     361        startHit = searchOffset[0] + searchOffset[1];
     362        endHit = startHit + searchOptionsComposer.getMaxRecords() - 1;
     363        tooltipNextText.setValue("hits " +
     364                    startHit + "-" + endHit);
     365    }
    343366}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/SearchOptions.java

    r5036 r5039  
    1616import eu.clarin.sru.fcs.aggregator.sopt.CorpusModelLive;
    1717import eu.clarin.sru.fcs.aggregator.sopt.CorpusRendererCached;
    18 import eu.clarin.sru.fcs.aggregator.sopt.CorpusRendererI;
    1918import eu.clarin.sru.fcs.aggregator.sopt.CorpusRendererLive;
    2019import eu.clarin.sru.fcs.aggregator.sopt.Languages;
    2120import eu.clarin.sru.fcs.aggregator.cache.ScanCache;
     21import eu.clarin.sru.fcs.aggregator.sopt.CorpusRenderer;
     22import eu.clarin.sru.fcs.aggregator.sopt.Language;
    2223import eu.clarin.sru.fcs.aggregator.util.SRUCQL;
    2324import java.lang.reflect.Type;
     
    7374   
    7475    private CorpusModelI corporaModel;
    75     private CorpusRendererI corpusRenderer;
     76    private CorpusRenderer corpusRenderer;
    7677   
    7778    private boolean liveMode = false;
     
    135136            }
    136137        }
     138        onSelectAll(null);
    137139    }
    138140
     
    151153        Treechildren openTreeItems = tree.getTreechildren();
    152154        for (Treeitem openItem : openTreeItems.getItems()) {
    153             corpusRenderer.updateItem(openItem, true);
     155            if (openItem.isVisible()) {
     156                corpusRenderer.updateItem(openItem, true);
     157            }
    154158        }
    155159    }
     
    161165           
    162166            DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) openItem.getValue();
    163             Corpus data = node.getData();
    164             System.out.println(data);
     167            //Corpus data = node.getData();
     168            //System.out.println(data);
    165169           
    166170            corpusRenderer.updateItem(openItem, false);
     
    227231            DefaultTreeNode<Corpus> node = item.getValue();
    228232            Corpus corpus = node.getData();
    229             for (String langCode : corpus.getLanguages()) {
    230                 availableLangs.add(langCode);
    231             }
    232         }
    233 
    234         List<String> sortedAvailableLanguages = new ArrayList<String>(availableLangs.size());
    235         sortedAvailableLanguages.addAll(availableLangs);
    236         Collections.sort(sortedAvailableLanguages);
    237         for (String langCode : sortedAvailableLanguages) {
    238             String name = this.languages.nameForCode(langCode);
    239             if (name != null) {
    240                 Comboitem item = this.languageSelect.appendItem(name);
    241                 item.setValue(langCode);
    242             }
     233            // offer for selection only those langauges
     234            // that are unique for a corpus
     235            if (corpus.getLanguages().size() == 1) {
     236                availableLangs.add(corpus.getLanguages().iterator().next());
     237            }
     238            //for (String langCode : corpus.getLanguages()) {
     239            //    availableLangs.add(langCode);
     240            //}
     241        }
     242
     243        //List<String> sortedAvailableLanguages = new ArrayList<String>(availableLangs.size());
     244        //sortedAvailableLanguages.addAll(availableLangs);
     245        //Collections.sort(sortedAvailableLanguages);
     246        List<Language> sortedLangs = new ArrayList<Language>(availableLangs.size());
     247        for (String langCode : availableLangs) {
     248            Language lang = this.languages.langForCode(langCode);
     249            if (lang != null) {
     250                sortedLangs.add(lang);
     251            }
     252        }
     253        Collections.sort(sortedLangs);
     254        for (Language lang : sortedLangs) {
     255                Comboitem item = this.languageSelect.appendItem(lang.getNameEn());
     256                item.setValue(lang.getCode());
    243257        }
    244258    }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/SearchResults.java

    r5035 r5039  
    2121import org.zkoss.zk.ui.select.annotation.Wire;
    2222import org.zkoss.zul.Groupbox;
    23 import org.zkoss.zul.Label;
    2423import org.zkoss.zul.Messagebox;
    2524import eu.clarin.sru.client.SRUClientException;
    26 import eu.clarin.sru.client.SRURecord;
    2725import eu.clarin.sru.client.SRUSearchRetrieveRequest;
    2826import eu.clarin.sru.client.SRUSearchRetrieveResponse;
     
    3129import eu.clarin.sru.fcs.aggregator.sopt.Corpus;
    3230import eu.clarin.sru.fcs.aggregator.sopt.Languages;
    33 import eu.clarin.sru.fcs.aggregator.sresult.Kwic;
    3431import eu.clarin.sru.fcs.aggregator.sresult.SearchResult;
    35 import eu.clarin.sru.fcs.aggregator.sresult.SearchResultRecordRenderer;
     32import eu.clarin.sru.fcs.aggregator.sresult.SearchResultContent;
     33import eu.clarin.sru.fcs.aggregator.sresult.SearchResultGroupRenderer;
    3634import eu.clarin.sru.fcs.aggregator.util.SRUCQL;
    37 import eu.clarin.weblicht.wlfxb.io.WLDObjector;
    38 import eu.clarin.weblicht.wlfxb.io.WLFormatException;
    39 import eu.clarin.weblicht.wlfxb.md.xb.MetaData;
    40 import eu.clarin.weblicht.wlfxb.tc.api.MatchedCorpus;
    41 import eu.clarin.weblicht.wlfxb.tc.api.Token;
    42 import eu.clarin.weblicht.wlfxb.tc.xb.TextCorpusStored;
    43 import eu.clarin.weblicht.wlfxb.xb.WLData;
    44 import java.io.ByteArrayOutputStream;
    4535import java.io.IOException;
    46 import java.io.UnsupportedEncodingException;
    4736import java.text.SimpleDateFormat;
    4837import java.util.Date;
    49 import java.util.HashSet;
    5038import java.util.Random;
    5139import java.util.Timer;
     
    5341import java.util.concurrent.Future;
    5442import java.util.concurrent.atomic.AtomicBoolean;
    55 import opennlp.tools.tokenize.TokenizerME;
    56 import opennlp.tools.tokenize.TokenizerModel;
    57 import org.apache.poi.ss.usermodel.Cell;
    58 import org.apache.poi.ss.usermodel.CellStyle;
    59 import org.apache.poi.ss.usermodel.Font;
    60 import org.apache.poi.ss.usermodel.Row;
    61 import org.apache.poi.ss.usermodel.Sheet;
    62 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    6343import org.zkoss.zhtml.Filedownload;
    6444import org.zkoss.zk.ui.event.EventListener;
    65 import org.zkoss.zul.Column;
    66 import org.zkoss.zul.Columns;
    67 import org.zkoss.zul.Grid;
    68 import org.zkoss.zul.ListModel;
    69 import org.zkoss.zul.SimpleListModel;
    7045import org.zkoss.zul.Vlayout;
    7146
     
    9267    private AtomicBoolean hasResults = new AtomicBoolean(false);
    9368    private AtomicBoolean searchInProgress = new AtomicBoolean(false);
    94     private int[] searchOffset;
     69    //private int[] searchOffset = new int[2];
     70    private int startRecord;
    9571    private int maxRecords;
    9672    private static final String WSPACE_SERVER_URL = "http://egi-cloud21.zam.kfa-juelich.de";
     
    10480    private static final String DROP_OFF_URL = "http://ws1-clarind.esc.rzg.mpg.de/drop-off/storage/";
    10581
     82    private Groupbox firstNoResultsGb = null;
     83    private final Object firstNoResultsGbLoc = new Object();
     84   
     85    private SearchResultGroupRenderer srItemRenderer;
     86    private SearchResultContent srExporter;
     87   
     88    private static final String SEARCH_RESULTS_ENCODING = "UTF-8";
    10689
    10790    @Override
     
    118101        Set<SearchResults> activeControllers = (Set<SearchResults>) Executions.getCurrent().getDesktop().getWebApp().getAttribute(WebAppListener.ACTIVE_SEARCH_CONTROLLERS);
    119102        activeControllers.add(this);
     103       
     104        srItemRenderer = new SearchResultGroupRenderer();
     105        srExporter = new SearchResultContent();
    120106    }
    121107
     
    126112        this.controlsVisibility.disableControls2();
    127113        resultsBox.getChildren().clear();
     114        synchronized (firstNoResultsGbLoc) {
     115        firstNoResultsGb = null;
     116        }
    128117        this.searchInProgress.set(false);
    129118        this.hasResults.set(false);
    130119    }
    131120
    132     void executeSearch(Map<String, Set<Corpus>> selectedCorpora, int maxRecords, String searchString, int[] searchOffset, String searchLanguage) {
     121    void executeSearch(Map<String, Set<Corpus>> selectedCorpora, int startRecord, int maxRecords, String searchString, String searchLanguage) {
    133122
    134123        this.controlsVisibility.disableControls1();
     
    142131        this.hasResults.set(false);
    143132        this.searchInProgress.set(true);
    144         this.searchOffset = searchOffset;
     133        this.startRecord = startRecord;
    145134
    146135        // terminate previous search requests and corresponding response processing
     
    156145        resultsProcessed = new ArrayList<SearchResult>();
    157146        resultsUnprocessed = new ArrayList<SearchResult>();
    158 
     147        synchronized (firstNoResultsGbLoc) {
     148        firstNoResultsGb = null;
     149        }
     150       
    159151        // set up timer, so that when it takes too much time to get the response to cancell the request
    160152        timer = new Timer();
     
    173165
    174166    private SearchResult executeSearch(Corpus corpus, String searchString) {
    175         SearchResult resultsItem = new SearchResult(corpus, searchString);
     167        SearchResult resultsItem = new SearchResult(corpus, searchString, startRecord, startRecord + maxRecords - 1);
    176168        LOGGER.log(Level.INFO, "Executing search for {0} query={1} maxRecords={2}",
    177169                new Object[]{corpus.toString(), searchString, maxRecords});
     
    183175        //searchRequest.setQuery("%22" + searchString + "%22");
    184176        searchRequest.setQuery("\"" + searchString + "\"");
    185         searchRequest.setStartRecord(searchOffset[0] + searchOffset[1]);
     177        //searchRequest.setStartRecord(searchOffset[0] + searchOffset[1]);
     178        searchRequest.setStartRecord(this.startRecord);
    186179        if (resultsItem.hasCorpusHandler()) {
    187180            searchRequest.setExtraRequestData(SRUCQL.SEARCH_CORPUS_HANDLE_PARAMETER, resultsItem.getCorpus().getHandle());
     
    233226    }
    234227
     228
    235229    private class UpdateResultsThread extends Thread {
    236230
     
    242236                if (!resultsItem.isWaitingForResponse()) {
    243237                    resultsItem.consumeResponse();
    244                     Executions.schedule(resultsBox.getDesktop(), new SearchResults.ResponseListener(resultsItem, currentRequestId), new Event("onDummy"));
     238                    Executions.schedule(resultsBox.getDesktop(), new SearchResults.ResponseListener(srItemRenderer, resultsItem, currentRequestId), new Event("onDummy"));
    245239                    // this alternative to Executions.schedule() - sinchronious update -
    246240                    // doesn't work: if interrupted here (exception thrown), then
     
    273267        int requestId;
    274268        SearchResult resultsItem;
    275 
    276         public ResponseListener(SearchResult resultsItem, int requestId) {
     269        SearchResultGroupRenderer srRenderer;
     270
     271        public ResponseListener(SearchResultGroupRenderer srRenderer, SearchResult resultsItem, int requestId) {
     272            this.srRenderer = srRenderer;
    277273            this.resultsItem = resultsItem;
    278274            this.requestId = requestId;
     
    283279
    284280            // create groupbox with search results item
    285             Groupbox groupbox = createRecordsGroup(resultsItem);
    286 
    287             // appand this search result only if it
     281            //Groupbox groupbox = createRecordsGroup(resultsItem);
     282            Groupbox groupbox = this.srRenderer.createRecordsGroup(resultsItem);
     283
     284            // append this search result only if it
    288285            // is a result of the current request
    289286            if (requestId == currentRequestId) {
    290                 resultsBox.appendChild(groupbox);
     287                // if the item has results, append it before
     288                // the item that has no resuls (if exists):
     289                if (groupbox.getAttribute(SearchResultGroupRenderer.NO_RESULTS) == null) {
     290                    resultsBox.insertBefore(groupbox, firstNoResultsGb);
     291                // if there are no results in this item,
     292                // append it a the end:
     293                } else {
     294                    resultsBox.appendChild(groupbox);
     295                    synchronized (firstNoResultsGbLoc) {
     296                        if (firstNoResultsGb == null) {
     297                            firstNoResultsGb = groupbox;
     298                        }
     299                    }
     300                }
     301
    291302            }
    292303
     
    295306            if (requestId != currentRequestId) {
    296307                groupbox.detach();
     308                synchronized (firstNoResultsGbLoc) {
     309                    firstNoResultsGb = null;
     310                }
    297311            }
    298312
     
    302316                if (last) {
    303317                    controlsVisibility.disableProgressMeter();
    304                     searchOffset[0] = searchOffset[0] + searchOffset[1];
    305                     searchOffset[1] = maxRecords;
    306318                    pagesVisibility.openSearchResult();
    307319
    308                     if (searchOffset[0] > 1) {
     320                    if (startRecord > 1) {
    309321                        controlsVisibility.enablePrevButton();
    310322                    }
     
    321333    }
    322334
    323     private Groupbox createRecordsGroup(SearchResult resultsItem) {
    324 
    325         Groupbox recordsGroup = new Groupbox();
    326         recordsGroup.setMold("3d");
    327         recordsGroup.setSclass("ccsLightBlue");
    328         recordsGroup.setContentStyle("border:0;");
    329         recordsGroup.setStyle("margin:10px;10px;10px;10px;");
    330         recordsGroup.setClosable(true);
    331         // create title
    332         StringBuilder sb = new StringBuilder();
    333         if (resultsItem.hasCorpusHandler()) {
    334             if (resultsItem.getCorpus().getDisplayName() != null) {
    335 //                sb.append(" ");
    336                 sb.append(resultsItem.getCorpus().getDisplayName());
    337                 sb.append(", ");
    338             }
    339         }
    340         sb.append(resultsItem.getCorpus().getInstitution().getName());
    341         recordsGroup.setTitle(sb.toString());
    342 
    343         // populate it with records grid or failure message
    344         if (resultsItem.getResponse() == null) { // there was an error in response
    345             recordsGroup.appendChild(new Label("Sorry, the search failed!"));
    346         } else if (resultsItem.getResponse().hasRecords()) { // the response was fine and there >=1 records
    347             Grid grid = new Grid();
    348 //            grid.setWidth("100%");
    349 //            grid.setMold("paging");
    350 //            grid.setPageSize(10);
    351             Columns columns = new Columns();
    352             Column c;
    353 
    354             c = new Column();
    355             //c.setLabel("Left");
    356             columns.appendChild(c);
    357             //c.setHflex("2");
    358             c = new Column();
    359             //c.setLabel("Hit");
    360             c.setHflex("min");
    361             //c.setHflex("1");
    362             columns.appendChild(c);
    363             c = new Column();
    364             //c.setHflex("2");
    365             //c.setLabel("Right");
    366             // info column
    367             columns.appendChild(c);
    368             c = new Column();
    369             c.setHflex("min");
    370             columns.appendChild(c);
    371             grid.appendChild(columns);
    372 
    373             List<SRURecord> sruRecords = resultsItem.getResponse().getRecords();
    374             ListModel lmodel = new SimpleListModel(sruRecords);
    375             grid.setModel(lmodel);
    376             grid.setRowRenderer(new SearchResultRecordRenderer(resultsItem));
    377             recordsGroup.appendChild(grid);
    378             grid.setStyle("margin:10px;border:0px;");
    379         } else { // the response was fine, but there are no records
    380             recordsGroup.appendChild(new Label("no results"));
    381         }
    382         return recordsGroup;
    383     }
     335
    384336   
    385337    public void exportTCF() {
    386             byte[] bytes = getExportTokenizedTCF();
     338            byte[] bytes = srExporter.getExportTokenizedTCF(resultsProcessed, searchLanguage, languages);
    387339            if (bytes != null) {
    388340                Filedownload.save(bytes, "text/tcf+xml", "ClarinDFederatedContentSearch.xml");
     
    391343   
    392344    public void exportText() {
    393             String text = getExportText().toString();
     345            String text = srExporter.getExportText(resultsProcessed);
    394346            if (text != null) {
    395347                Filedownload.save(text, "text/plain", "ClarinDFederatedContentSearch.txt");
     
    400352    void exportExcel() {
    401353       
    402         byte[] bytes = getExportExcel();
     354        byte[] bytes = srExporter.getExportExcel(resultsProcessed);
    403355            if (bytes != null) {
    404356                Filedownload.save(bytes, "text/tcf+xml", "ClarinDFederatedContentSearch.xls");
     
    406358    }
    407359
    408     private byte[] getExportExcel() {
    409        
    410         boolean noResult = true;
    411         SXSSFWorkbook workbook = null;
    412         ByteArrayOutputStream excelStream = new ByteArrayOutputStream();
    413         if (resultsProcessed != null && !resultsProcessed.isEmpty()) {
    414             try {
    415                 String[] headers = new String[] {
    416                     "LEFT CONTEXT", "KEYWORD", "RIGHT CONTEXT", "PID", "REFERENCE"};
    417            
    418                 workbook = new SXSSFWorkbook();
    419                 Sheet sheet = workbook.createSheet();
    420 
    421                 Font boldFont = workbook.createFont();
    422                 boldFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
    423 
    424                 // Header
    425                 CellStyle headerStyle = workbook.createCellStyle();
    426                 headerStyle.setFont(boldFont);
    427 
    428                 Row row = sheet.createRow(0);
    429 
    430                 for (int j = 0; j < headers.length; ++j) {
    431                     Cell cell = row.createCell(j, Cell.CELL_TYPE_STRING);
    432                     cell.setCellValue(headers[j]);
    433                     cell.setCellStyle(headerStyle);
    434                 }
    435 
    436                 // Body
    437                 Cell cell;
    438                 for (int k = 0; k < resultsProcessed.size(); k++) {
    439                     SearchResult result = resultsProcessed.get(k);
    440                     List<Kwic> kwics = result.getKwics();
    441                     for (int i = 0; i < kwics.size(); i++) {
    442                         Kwic kwic = kwics.get(i);
    443                         row = sheet.createRow(k + i + 1);
    444                         cell = row.createCell(0, Cell.CELL_TYPE_STRING);
    445                         cell.setCellValue(kwic.getLeft());
    446                         cell = row.createCell(1, Cell.CELL_TYPE_STRING);
    447                         cell.setCellValue(kwic.getKeyword());
    448                         cell = row.createCell(2, Cell.CELL_TYPE_STRING);
    449                         cell.setCellValue(kwic.getRight());
    450                         if (kwic.getPid() != null) {
    451                             cell = row.createCell(3, Cell.CELL_TYPE_STRING);
    452                             cell.setCellValue(kwic.getPid());
    453                         }
    454                         if (kwic.getReference() != null) {
    455                             cell = row.createCell(3, Cell.CELL_TYPE_STRING);
    456                             cell.setCellValue(kwic.getReference());
    457                         }
    458                         noResult = false;
    459                     }
    460                 }
    461                 workbook.write(excelStream);
    462             } catch (IOException ex) {
    463                 // should not happen
    464                 Logger.getLogger(SearchResults.class.getName()).log(Level.SEVERE, null, ex);
    465             } finally {
    466                 if (workbook != null) {
    467                     workbook.dispose();
    468                 }
    469             }
    470         }
    471         if (noResult) {
    472             Messagebox.show("Nothing to export!");
    473             return null;
    474         } else {
    475             return excelStream.toByteArray();
    476         }
    477        
    478     }
     360 
    479361
    480362    void exportPWText(String user, String pass) {
    481363        byte[] bytes = null;
    482364        try {
    483             bytes = getExportText().toString().getBytes("UTF-8");
    484         } catch (UnsupportedEncodingException ex) {
     365            String text = srExporter.getExportText(resultsProcessed);
     366            if (text != null) {
     367                bytes = text.getBytes(SEARCH_RESULTS_ENCODING);
     368            }
     369        } catch (Exception ex) {
    485370            Logger.getLogger(SearchResults.class.getName()).log(Level.SEVERE, null, ex);
    486371        }
     
    491376   
    492377    String useWebLichtOnText() {
    493         byte[] bytes = null;
    494378        String url = null;
    495379        try {
    496             bytes = getExportText().toString().getBytes("UTF-8");
    497         } catch (UnsupportedEncodingException ex) {
     380            String text = srExporter.getExportText(resultsProcessed);
     381            if (text != null) {
     382                byte[] bytes = text.getBytes(SEARCH_RESULTS_ENCODING);
     383                url = uploadToDropOff(bytes, "text/plan",".txt");
     384            }
     385        } catch (Exception ex) {
    498386            Logger.getLogger(SearchResults.class.getName()).log(Level.SEVERE, null, ex);
    499         }
    500         if (bytes != null) {
    501             url = uploadToDropOff(bytes, "text/plan",".txt");
    502387        }
    503388        return url;
     
    506391    String useWebLichtOnToks() {
    507392        String url = null;
    508         byte[] bytes = getExportTokenizedTCF();
     393        byte[] bytes = srExporter.getExportTokenizedTCF(resultsProcessed, searchLanguage, languages);
    509394        if (bytes != null) {
    510395            url = uploadToDropOff(bytes, "text/tcf+xml",".tcf");
     
    514399
    515400    void exportPWExcel(String user, String pass) {
    516         byte[] bytes = getExportExcel();
     401        byte[] bytes = srExporter.getExportExcel(resultsProcessed);
    517402            if (bytes != null) {
    518403                uploadToPW(user, pass, bytes, "application/vnd.ms-excel",".xls");
     
    522407   public void exportPWTCF(String user, String pass) {
    523408       
    524        byte[] bytes = getExportTokenizedTCF();
     409       byte[] bytes = srExporter.getExportTokenizedTCF(resultsProcessed, searchLanguage, languages);
    525410            if (bytes != null) {
    526411                uploadToPW(user, pass, bytes, "text/tcf+xml",".tcf");
    527412        }
    528413    }
    529    
    530     private byte[] getExportTCF() {
    531         StringBuilder text = new StringBuilder();
    532         Set<String> resultsLangs = new HashSet<String>();
    533         if (resultsProcessed != null && !resultsProcessed.isEmpty()) {
    534             for (SearchResult result : resultsProcessed) {
    535                 resultsLangs.addAll(result.getCorpus().getLanguages());
    536                 for (Kwic kwic : result.getKwics()) {
    537                     text.append(kwic.getLeft());
    538                     text.append(" ");
    539                     text.append(kwic.getKeyword());
    540                     text.append(" ");
    541                     text.append(kwic.getRight());
    542                     text.append("\n");
    543                 }
    544             }
    545 
    546         }
    547         ByteArrayOutputStream os = null;
    548         if (text.length() == 0) {
    549             Messagebox.show("Nothing to export!");
    550         } else {
    551             WLData data;
    552             MetaData md = new MetaData();
    553             String resultsLang = "unknown";
    554             if (resultsLangs.size() == 1) {
    555                 resultsLang = resultsLangs.iterator().next();
    556                 String code2 = languages.code2ForCode(resultsLang);
    557                 if (code2 != null) {
    558                     resultsLang = code2;
    559                 }
    560             } else if (!searchLanguage.equals("anylang")) {
    561                 String code2 = languages.code2ForCode(searchLanguage);
    562                 if (code2 == null) {
    563                     resultsLang = searchLanguage;
    564                 } else {
    565                     resultsLang = code2;
    566                 }
    567             }
    568             TextCorpusStored tc = new TextCorpusStored(resultsLang);
    569             tc.createTextLayer().addText(text.toString());
    570             data = new WLData(md, tc);
    571             os = new ByteArrayOutputStream();
    572             try {
    573                 WLDObjector.write(data, os);
    574             } catch (WLFormatException ex) {
    575                 LOGGER.log(Level.SEVERE, "Error exporting TCF {0} {1}", new String[]{ex.getClass().getName(), ex.getMessage()});
    576                 Messagebox.show("Sorry, export error!");
    577             }
    578         }
    579         if (os == null) {
    580             return null;
    581         } else {
    582             return os.toByteArray();
    583         }
    584     }
    585    
    586    
    587         private byte[] getExportTokenizedTCF() {
    588         StringBuilder text = new StringBuilder();
    589         Set<String> resultsLangs = new HashSet<String>();
    590         if (resultsProcessed != null && !resultsProcessed.isEmpty()) {
    591             for (SearchResult result : resultsProcessed) {
    592                 resultsLangs.addAll(result.getCorpus().getLanguages());
    593                 for (Kwic kwic : result.getKwics()) {
    594                     text.append(kwic.getLeft());
    595                     text.append(" ");
    596                     text.append(kwic.getKeyword());
    597                     text.append(" ");
    598                     text.append(kwic.getRight());
    599                     text.append("\n");
    600                 }
    601             }
    602 
    603         }
    604         ByteArrayOutputStream os = null;
    605         if (text.length() == 0) {
    606             Messagebox.show("Nothing to export!");
    607         } else {
    608             WLData data;
    609             MetaData md = new MetaData();
    610             String resultsLang = "unknown";
    611             if (resultsLangs.size() == 1) {
    612                 resultsLang = resultsLangs.iterator().next();
    613                 String code2 = languages.code2ForCode(resultsLang);
    614                 if (code2 != null) {
    615                     resultsLang = code2;
    616                 }
    617             } else if (!searchLanguage.equals("anylang")) {
    618                 String code2 = languages.code2ForCode(searchLanguage);
    619                 if (code2 == null) {
    620                     resultsLang = searchLanguage;
    621                 } else {
    622                     resultsLang = code2;
    623                 }
    624             }
    625             TextCorpusStored tc = new TextCorpusStored(resultsLang);
    626             tc.createTextLayer().addText(text.toString());
    627             addTokensSentencesMatches(tc);
    628             data = new WLData(md, tc);
    629             os = new ByteArrayOutputStream();
    630             try {
    631                 WLDObjector.write(data, os);
    632             } catch (WLFormatException ex) {
    633                 LOGGER.log(Level.SEVERE, "Error exporting TCF {0} {1}", new String[]{ex.getClass().getName(), ex.getMessage()});
    634                 Messagebox.show("Sorry, export error!");
    635             }
    636         }
    637         if (os == null) {
    638             return null;
    639         } else {
    640             return os.toByteArray();
    641         }
    642     }
    643    
    644        
    645     private void addTokensSentencesMatches(TextCorpusStored tc) {
    646        
    647         TokenizerModel model = (TokenizerModel) Executions.getCurrent().getDesktop().getWebApp().getAttribute(WebAppListener.DE_TOK_MODEL);
    648        
    649         if (model == null || !tc.getLanguage().equals("de")) {
    650             return;
    651         }
    652         TokenizerME tokenizer = new TokenizerME(model);
    653        
    654         if (resultsProcessed != null && !resultsProcessed.isEmpty()) {
    655             tc.createTokensLayer();
    656             tc.createSentencesLayer();
    657             tc.createMatchesLayer("FCS", resultsProcessed.get(0).getSearchString());
    658             for (SearchResult result : resultsProcessed) {
    659                 MatchedCorpus mCorpus = tc.getMatchesLayer().addCorpus(result.getCorpus().getDisplayName(), result.getCorpus().getHandle());
    660                 for (Kwic kwic : result.getKwics()) {
    661                     List<Token> tokens = new ArrayList<Token>();
    662                     addToTcfTokens(tokens, tc, tokenizer.tokenize(kwic.getLeft()));
    663                     String[] target = tokenizer.tokenize(kwic.getKeyword());
    664                     List<Token> targetTokens = addToTcfTokens(tokens, tc, target);
    665                     addToTcfTokens(tokens, tc, tokenizer.tokenize(kwic.getRight()));
    666                     tc.getSentencesLayer().addSentence(tokens);
    667                     List<String> pidAndRef = new ArrayList<String>();
    668                     if (kwic.getPid() != null) {
    669                         pidAndRef.add(kwic.getPid());
    670                     }
    671                     if (kwic.getReference() != null) {
    672                         pidAndRef.add(kwic.getReference());
    673                     }
    674                     tc.getMatchesLayer().addItem(mCorpus, targetTokens, pidAndRef);
    675                 }
    676             }
    677         }
    678     }
    679    
    680    
    681     private List<Token> addToTcfTokens(List<Token> tokens, TextCorpusStored tc, String[] tokenStrings) {
    682         List<Token> addedTokens = new ArrayList<Token>(tokenStrings.length);
    683         for (String tokenString : tokenStrings) {
    684             Token token = tc.getTokensLayer().addToken(tokenString);
    685             addedTokens.add(token);
    686             tokens.add(token);
    687         }
    688         return addedTokens;
    689     }
    690    
    691     private CharSequence getExportText() {
    692         StringBuilder text = new StringBuilder();
    693         //Set<String> resultsLangs = new HashSet<String>();
    694         if (resultsProcessed != null && !resultsProcessed.isEmpty()) {
    695             for (SearchResult result : resultsProcessed) {
    696                 //resultsLangs.addAll(result.getCorpus().getLanguages());
    697                 for (Kwic kwic : result.getKwics()) {
    698                     text.append(kwic.getLeft());
    699                     text.append(" ");
    700                     text.append(kwic.getKeyword());
    701                     text.append(" ");
    702                     text.append(kwic.getRight());
    703                     text.append("\n");
    704                 }
    705             }
    706 
    707         }
    708         if (text.length() == 0) {
    709             Messagebox.show("Nothing to export!");
    710             return null;
    711         } else {
    712             return text;
    713         }
    714     }
     414
    715415   
    716416    public void exportCSV() {
    717         String csv = getExportCSV(";");
     417        String csv = srExporter.getExportCSV(resultsProcessed, ";");
    718418        if (csv != null) {
    719419            Filedownload.save(csv.toString(), "text/plain", "ClarinDFederatedContentSearch.csv");
     
    723423   
    724424    public void exportPWCSV(String user, String pass) {
    725         String csv = getExportCSV(";");
     425        //String csv = getExportCSV(";");
     426        String csv = srExporter.getExportCSV(resultsProcessed, ";");
    726427        if (csv != null) {
    727428            uploadToPW(user, pass, csv.getBytes(), "text/csv",".csv");
    728429        }
    729430    }
    730 
    731     private String getExportCSV(String separator) {
    732 
    733         boolean noResult = true;
    734         StringBuilder csv = new StringBuilder();
    735         if (resultsProcessed != null && !resultsProcessed.isEmpty()) {
    736             String[] headers = new String[] {
    737                     "LEFT CONTEXT", "KEYWORD", "RIGHT CONTEXT", "PID", "REFERENCE"};
    738             for (String header : headers) {
    739                 csv.append("\""); csv.append(header); csv.append("\"");
    740                 csv.append(separator);
    741             }
    742             csv.append("\n");
    743 
    744             for (SearchResult result : resultsProcessed) {
    745                 for (Kwic kwic : result.getKwics()) {
    746                     csv.append("\""); csv.append(escapeQuotes(kwic.getLeft())); csv.append("\"");
    747                     csv.append(separator);
    748                     csv.append("\""); csv.append(escapeQuotes(kwic.getKeyword())); csv.append("\"");
    749                     csv.append(separator);
    750                     csv.append("\""); csv.append(escapeQuotes(kwic.getRight())); csv.append("\"");
    751                     csv.append(separator);
    752                     csv.append("\"");
    753                     if (kwic.getPid() != null) {
    754                         csv.append(escapeQuotes(kwic.getPid()));
    755                     }
    756                     csv.append("\"");
    757                     csv.append(separator);
    758                     csv.append("\"");
    759                     if (kwic.getReference() != null) {
    760                         csv.append(escapeQuotes(kwic.getReference()));
    761                     }
    762                     csv.append("\"");
    763                     csv.append("\n");
    764                     noResult = false;
    765                 }
    766             }
    767         }
    768         if (noResult) {
    769             Messagebox.show("Nothing to export!");
    770             return null;
    771         } else {
    772             return csv.toString();
    773         }
    774     }
    775    
    776     private CharSequence escapeQuotes(String text) {
    777         StringBuilder sb = new StringBuilder();
    778         for (int i = 0; i < text.length(); i++) {
    779             char ch = text.charAt(i);
    780             if (ch == '"') {
    781                 sb.append('"');
    782             }
    783             sb.append(ch);
    784         }
    785         return sb;
    786     }
    787    
    788     private void uploadToPW(String user, String pass, byte[] bytes, String mimeType, String fileExtention) {
     431   
     432        private void uploadToPW(String user, String pass, byte[] bytes, String mimeType, String fileExtention) {
    789433        try {
    790434                Sardine sardine = SardineFactory.begin();
     
    850494    }
    851495
     496
    852497    private void setUpSRUVersion() {
    853498        String[] paramValue = Executions.getCurrent().getParameterMap().get(SRUCQL.VERSION);
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/WebAppListener.java

    r5037 r5039  
    5151    private static final String SCAN_DIR_NAME = "scan";
    5252    private static final TimeUnit CACHE_UPDATE_INTERVAL_UNIT = TimeUnit.HOURS;
    53     private static final int CACHE_UPDATE_INTERVAL = 5;
    54     private static final int CACHE_MAX_DEPTH = 2;
     53    private static final int CACHE_UPDATE_INTERVAL = 6;
     54    private static final int CACHE_MAX_DEPTH = 3;
    5555    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
    5656    public static final String CORPUS_CRAWLER = "CORPUS_CRAWLER";
     
    7272       
    7373        setUpScanCache(webapp);
     74        //setUpScanCacheForReadOnly(webapp);
    7475       
    7576        setUpTokenizers(webapp);
     
    9192
    9293    private String getScanDirectory() {
    93         File aggregatorDir = new File(System.getProperty("user.home"), "/." + AGGREGATOR_DIR_NAME);
     94        //File aggregatorDir = new File(System.getProperty("user.home"), "/." + AGGREGATOR_DIR_NAME);
    9495        //File aggregatorDir = new File("/var/www", "/." + AGGREGATOR_DIR_NAME);
     96        File aggregatorDir = new File("/data/fcsAggregator");
    9597       
    9698        if (!aggregatorDir.exists()) {
    97             aggregatorDir.mkdir();
     99            if (!aggregatorDir.mkdir()) {
     100                LOGGER.info("Scan directory does not exist and cannot be created: "
     101                        + aggregatorDir.getAbsolutePath());
     102            }
    98103        }
    99104        File scanDir = new File(aggregatorDir, SCAN_DIR_NAME);
     
    105110        return scanPath;
    106111    }
     112   
     113    /**
     114     * Use this method instead of setUpScanCache() method if it is necessary
     115     * to run the application without scan data crawl, given that the scan
     116     * data was crawled before and was stored as cache under appropriate
     117     * location (useful when testing or when smth is wrong with the endpoint
     118     * scan responses).
     119     *
     120     * @param webapp
     121     */
     122    private void setUpScanCacheForReadOnly(WebApp webapp) {
     123        ScanCacheFiled scanCacheFiled = new ScanCacheFiled(getScanDirectory());
     124        ScanCache scanCache;
     125        LOGGER.info("Start cache read");
     126        try {
     127            scanCache = scanCacheFiled.read();
     128            LOGGER.info("Finished cache read, number of root corpora: " + scanCache.getRootCorpora().size());
     129        } catch (Exception e) {
     130            LOGGER.log(Level.SEVERE, "Error while reading the scan cache!", e);
     131            scanCache = new SimpleInMemScanCache();
     132        }
     133        webapp.setAttribute(CORPUS_CACHE, scanCache);
     134    }
    107135
    108136    private void setUpScanCache(WebApp webapp) {
     
    111139        CenterRegistryI centerRegistry = new CenterRegistryLive();
    112140        SRUThreadedClient sruScanClient = (SRUThreadedClient) webapp.getAttribute(WebAppListener.SHARED_SRU_CLIENT);
    113         EndpointUrlFilter filter = new EndpointUrlFilter();
    114         //filter.urlShouldContainAnyOf("leipzig", ".mpi.nl");
     141        //EndpointUrlFilter filter = new EndpointUrlFilter();
     142        //filter.urlShouldContainAnyOf("leipzig");
    115143        //filter.urlShouldContainAnyOf("uni-tuebingen.de");
    116         filter.urlShouldContainAnyOf("uni-tuebingen.de", ".mpi.nl");
     144        //filter.urlShouldContainAnyOf("uni-tuebingen.de", ".mpi.nl");
    117145        //filter.urlShouldContainAnyOf("dspin.dwds.de", "lindat.");
    118         ScanCrawler scanCrawler = new ScanCrawler(centerRegistry, sruScanClient, filter, CACHE_MAX_DEPTH);
    119         //ScanCrawler scanCrawler = new ScanCrawler(centerRegistry, sruScanClient, null, CACHE_MAX_DEPTH);
     146        //ScanCrawler scanCrawler = new ScanCrawler(centerRegistry, sruScanClient, filter, CACHE_MAX_DEPTH);
     147        ScanCrawler scanCrawler = new ScanCrawler(centerRegistry, sruScanClient, null, CACHE_MAX_DEPTH);
    120148        ScanCache scanCache;
    121149
     
    191219        webapp.setAttribute(DE_TOK_MODEL, model);
    192220    }
     221
    193222}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/cache/ScanCacheFiled.java

    r5037 r5039  
    2222 * Utility for reading/writing scan data (endpoints descriptions) from/to
    2323 * ScanCache from/to local files.
     24 *
     25 * The data saved in a folder into files has the following format:
     26 * inst.txt lists all the centers and the endpoints that have CQL compliant
     27 * resources, with each CQL endpoint top resources assigned a number.
     28 * Number that represents a resource corresponds to a folder name, inside which
     29 * resource info is stored in a file corpus.txt. If a resource has sub-resources,
     30 * the folder contains sub-folders, also named by numbers, with their
     31 * corresponding corpus.txt files, and so on.
     32 * The corpus.txt file contains each piece of info on a separate line. Line 1
     33 * is resource endpoint, line 2 - handle, line 3 - display name, line 4 - landing
     34 * page, 5 - desription, 6 - languages (multiple languages are separated by |
     35 * separator), 7 - number of records.
    2436 *
    2537 * @author yanapanchenko
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/cache/ScanCrawler.java

    r5037 r5039  
    11package eu.clarin.sru.fcs.aggregator.cache;
    22
     3import eu.clarin.sru.client.SRUClientException;
    34import eu.clarin.sru.client.SRUScanRequest;
    45import eu.clarin.sru.client.SRUScanResponse;
     
    1011import eu.clarin.sru.fcs.aggregator.sopt.Institution;
    1112import eu.clarin.sru.fcs.aggregator.util.SRUCQL;
     13import java.util.ArrayList;
    1214import java.util.List;
     15import java.util.concurrent.ExecutionException;
    1316import java.util.concurrent.Future;
    1417import java.util.concurrent.TimeUnit;
     
    7275    }
    7376
    74     // TODO: ask Oliver to add API support for the extra info in the
     77
     78
     79    private void addCorpora(SRUThreadedClient sruScanClient, String endpointUrl,
     80            Institution institution, int depth, Corpus parentCorpus, ScanCache cache) {
     81       
     82
     83        depth++;
     84        if (depth > maxDepth) {
     85            return;
     86        }
     87
     88
     89            List<Corpus> childrenCorpora = doScan(sruScanClient, endpointUrl, institution, parentCorpus);
     90           
     91            //if (childrenCorpora.isEmpty()) {
     92                for (Corpus c : childrenCorpora) {
     93                    // don't add corpus that introduces cyclic references
     94                    // as of March 2014, there are 2 such endpoints...
     95                    if (cache.getCorpus(c.getHandle())!= null) {
     96                        LOGGER.warning("Cyclic reference in corpus " + c.getHandle() + " of endpoint " + endpointUrl);
     97                        continue;
     98                    }
     99                    //Corpus c = createCorpus(institution, endpointUrl, term);
     100                    //Corpus c = new Corpus(institution, endpointUrl);
     101//                    c.setHandle(term.getValue());
     102//                    c.setDisplayName(term.getDisplayTerm());
     103//                    if (term.getNumberOfRecords() > 0) {
     104//                        c.setNumberOfRecords(term.getNumberOfRecords());
     105//                    }
     106//                    addExtraInfo(c, term);
     107                    cache.addCorpus(c, parentCorpus);
     108                    // how not to query default corpus???
     109                    addCorpora(sruScanClient, c.getEndpointUrl(), c.getInstitution(),
     110                            depth, c, cache);
     111                }
     112                //} else if () {
     113                // TODO if diagnistics came back, try simple scan without the
     114                // SRUCQLscan.RESOURCE_INFO_PARAMETER
     115//            }
     116//else {
     117//                if (parentCorpus == null) { // means root
     118                    // create default root corpus:
     119//                    Corpus c = new Corpus(institution, endpointUrl);
     120//                    cache.addCorpus(c);
     121//                }
     122//            }
     123           
     124           
     125//            SRUScanResponse response = doScan(sruScanClient, endpointUrl, parentCorpus);
     126//           
     127//           
     128//            if (response != null && response.hasTerms()) {
     129//                for (SRUTerm term : response.getTerms()) {
     130//                    // don't add corpus that introduces cyclic references
     131//                    // as of March 2014, there are 2 such endpoints...
     132//                    if (cache.getCorpus(term.getValue())!= null) {
     133//                        LOGGER.warning("Cyclic reference in corpus " + term.getValue() + " of endpoint " + endpointUrl);
     134//                        continue;
     135//                    }
     136//                    Corpus c = createCorpus(institution, endpointUrl, term);
     137//                    //Corpus c = new Corpus(institution, endpointUrl);
     138////                    c.setHandle(term.getValue());
     139////                    c.setDisplayName(term.getDisplayTerm());
     140////                    if (term.getNumberOfRecords() > 0) {
     141////                        c.setNumberOfRecords(term.getNumberOfRecords());
     142////                    }
     143////                    addExtraInfo(c, term);
     144//                    cache.addCorpus(c, parentCorpus);
     145//                    addCorpora(sruScanClient, c.getEndpointUrl(), c.getInstitution(),
     146//                            depth, c, cache);
     147//                }
     148//                //} else if () {
     149//                // TODO if diagnistics came back, try simple scan without the
     150//                // SRUCQLscan.RESOURCE_INFO_PARAMETER
     151//            } else {
     152//                if (parentCorpus == null) { // means root
     153//                    // create default root corpus:
     154//                    Corpus c = new Corpus(institution, endpointUrl);
     155//                    cache.addCorpus(c);
     156//                }
     157//            }
     158       
     159    }
     160
     161    private static String normalizeHandle(Corpus corpus, boolean root) {
     162        if (root) {
     163            return Corpus.ROOT_HANDLE;
     164        }
     165        String handle = corpus.getHandle();
     166        if (Corpus.HANDLE_WITH_SPECIAL_CHARS.matcher(handle).matches()) {
     167            //resourceValue = "%22" + resourceValue + "%22";
     168            handle = "\"" + handle + "\"";
     169        }
     170        return handle;
     171    }
     172
     173//    public static SRUScanResponse doScan(SRUThreadedClient sruScanClient,
     174//            String endpointUrl, Corpus parentCorpus) {
     175//       
     176//        Future<SRUScanResponse> corporaResponse = null;
     177//        SRUScanResponse response = null;
     178//        try {
     179//                    SRUScanRequest corporaRequest = new SRUScanRequest(endpointUrl);
     180//            StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
     181//            scanClause.append("=");
     182//            String normalizedHandle = normalizeHandle(parentCorpus, parentCorpus == null);
     183//            scanClause.append(normalizedHandle);
     184//            corporaRequest.setScanClause(scanClause.toString());
     185//            corporaRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER,
     186//                    SRUCQL.SCAN_RESOURCE_INFO_PARAMETER_DEFAULT_VALUE);
     187//            corporaResponse = sruScanClient.scan(corporaRequest);
     188//            Thread.sleep(5000);
     189//            response = corporaResponse.get(600, TimeUnit.SECONDS);
     190//            return response;
     191//        }    catch (TimeoutException ex) {
     192//            LOGGER.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
     193//                    new String[]{Corpus.ROOT_HANDLE, endpointUrl, ex.getClass().getName(), ex.getMessage()});
     194//        } catch (Exception ex) {
     195//            LOGGER.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     196//                    new String[]{Corpus.ROOT_HANDLE, endpointUrl, ex.getClass().getName(), ex.getMessage()});
     197//        } finally {
     198//            if (corporaResponse != null && !corporaResponse.isDone()) {
     199//                corporaResponse.cancel(true);
     200//            }
     201//        }
     202//       
     203//        return response;
     204//    }
     205   
     206   
     207        public static List<Corpus> doScan(SRUThreadedClient sruScanClient,
     208            String endpointUrl, Institution institution, Corpus parentCorpus) {
     209       
     210        List<Corpus> corpora = new ArrayList<Corpus>();
     211        Future<SRUScanResponse> corporaResponse = null;
     212        SRUScanResponse response = null;
     213        try {
     214                    SRUScanRequest corporaRequest = new SRUScanRequest(endpointUrl);
     215            StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
     216            scanClause.append("=");
     217            String normalizedHandle = normalizeHandle(parentCorpus, parentCorpus == null);
     218            scanClause.append(normalizedHandle);
     219            corporaRequest.setScanClause(scanClause.toString());
     220            corporaRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER,
     221                    SRUCQL.SCAN_RESOURCE_INFO_PARAMETER_DEFAULT_VALUE);
     222            corporaResponse = sruScanClient.scan(corporaRequest);
     223            Thread.sleep(5000);
     224            response = corporaResponse.get(600, TimeUnit.SECONDS);
     225        }    catch (TimeoutException ex) {
     226            LOGGER.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
     227                    new String[]{Corpus.ROOT_HANDLE, endpointUrl, ex.getClass().getName(), ex.getMessage()});
     228        } catch (Exception ex) {
     229            LOGGER.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     230                    new String[]{Corpus.ROOT_HANDLE, endpointUrl, ex.getClass().getName(), ex.getMessage()});
     231        } finally {
     232            if (corporaResponse != null && !corporaResponse.isDone()) {
     233                corporaResponse.cancel(true);
     234            }
     235        }
     236       
     237       
     238        if (response != null && response.hasTerms()) {
     239                for (SRUTerm term : response.getTerms()) {
     240                    // don't add corpus that introduces cyclic references
     241                    // as of March 2014, there are 2 such endpoints...
     242                    //if (cache.getCorpus(term.getValue())!= null) {
     243                    //    LOGGER.warning("Cyclic reference in corpus " + term.getValue() + " of endpoint " + endpointUrl);
     244                    //    continue;
     245                    //}
     246                    Corpus c = createCorpus(institution, endpointUrl, term);
     247                    corpora.add(c);
     248                }
     249                //} else if () {
     250                // TODO if diagnistics came back, try simple scan without the
     251                // SRUCQLscan.RESOURCE_INFO_PARAMETER
     252            } else {
     253                if (parentCorpus == null) { // means root
     254                    // create default root corpus:
     255                    Corpus c = new Corpus(institution, endpointUrl);
     256                    corpora.add(c);
     257                }
     258            }
     259        return corpora;
     260    }
     261
     262    private static Corpus createCorpus(Institution institution, String endpointUrl, SRUTerm term) {
     263                    Corpus c = new Corpus(institution, endpointUrl);
     264                    c.setHandle(term.getValue());
     265                    c.setDisplayName(term.getDisplayTerm());
     266                    if (term.getNumberOfRecords() > 0) {
     267                        c.setNumberOfRecords(term.getNumberOfRecords());
     268                    }
     269                    addExtraInfo(c, term);
     270                    return c;
     271    }
     272   
     273        // TODO: ask Oliver to add API support for the extra info in the
    75274    // SRU client/server libraries, so that it's not necessary to work
    76275    // with DocumentFragment
    77     private void addExtraInfo(Corpus c, SRUTerm term) {
     276    private static void addExtraInfo(Corpus c, SRUTerm term) {
    78277
    79278        DocumentFragment extraInfo = term.getExtraTermData();
     
    116315        }
    117316    }
    118 
    119     private void addCorpora(SRUThreadedClient sruScanClient, String endpointUrl,
    120             Institution institution, int depth, Corpus parentCorpus, ScanCache cache) {
    121        
    122         Future<SRUScanResponse> corporaResponse = null;
    123 
    124         depth++;
    125         if (depth > maxDepth) {
    126             return;
    127         }
    128         try {
    129             boolean root = false;
    130             if (parentCorpus == null) {
    131                 root = true;
    132             }
    133 
    134             SRUScanRequest corporaRequest = new SRUScanRequest(endpointUrl);
    135             StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
    136             scanClause.append("=");
    137             String normalizedHandle = normalizeHandle(parentCorpus, root);
    138             scanClause.append(normalizedHandle);
    139             corporaRequest.setScanClause(scanClause.toString());
    140             corporaRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER,
    141                     SRUCQL.SCAN_RESOURCE_INFO_PARAMETER_DEFAULT_VALUE);
    142             corporaResponse = sruScanClient.scan(corporaRequest);
    143             Thread.sleep(5000);
    144             SRUScanResponse response = corporaResponse.get(600, TimeUnit.SECONDS);
    145             if (response != null && response.hasTerms()) {
    146                 for (SRUTerm term : response.getTerms()) {
    147                     // don't add corpus that introduces cyclic references
    148                     // as of March 2014, there are 2 such endpoints...
    149                     if (cache.getCorpus(term.getValue())!= null) {
    150                         LOGGER.warning("Cyclic reference in corpus " + term.getValue() + " of endpoint " + endpointUrl);
    151                         continue;
    152                     }
    153                     Corpus c = new Corpus(institution, endpointUrl);
    154                     c.setHandle(term.getValue());
    155                     c.setDisplayName(term.getDisplayTerm());
    156                     if (term.getNumberOfRecords() > 0) {
    157                         c.setNumberOfRecords(term.getNumberOfRecords());
    158                     }
    159                     addExtraInfo(c, term);
    160                     cache.addCorpus(c, parentCorpus);
    161                     addCorpora(sruScanClient, c.getEndpointUrl(), c.getInstitution(),
    162                             depth, c, cache);
    163                 }
    164                 //} else if () {
    165                 // TODO if diagnistics came back, try simple scan without the
    166                 // SRUCQLscan.RESOURCE_INFO_PARAMETER
    167             } else {
    168                 if (root) {
    169                     // create default root corpus:
    170                     Corpus c = new Corpus(institution, endpointUrl);
    171                     cache.addCorpus(c);
    172                 }
    173             }
    174         } catch (TimeoutException ex) {
    175             LOGGER.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
    176                     new String[]{Corpus.ROOT_HANDLE, endpointUrl, ex.getClass().getName(), ex.getMessage()});
    177         } catch (Exception ex) {
    178             LOGGER.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    179                     new String[]{Corpus.ROOT_HANDLE, endpointUrl, ex.getClass().getName(), ex.getMessage()});
    180         } finally {
    181             if (corporaResponse != null && !corporaResponse.isDone()) {
    182                 corporaResponse.cancel(true);
    183             }
    184         }
    185     }
    186 
    187     private String normalizeHandle(Corpus corpus, boolean root) {
    188         if (root) {
    189             return Corpus.ROOT_HANDLE;
    190         }
    191         String handle = corpus.getHandle();
    192         if (Corpus.HANDLE_WITH_SPECIAL_CHARS.matcher(handle).matches()) {
    193             //resourceValue = "%22" + resourceValue + "%22";
    194             handle = "\"" + handle + "\"";
    195         }
    196         return handle;
    197     }
    198317}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sopt/CorpusModelLive.java

    r5035 r5039  
    77import eu.clarin.sru.client.SRUThreadedClient;
    88import eu.clarin.sru.fcs.aggregator.app.WebAppListener;
     9import eu.clarin.sru.fcs.aggregator.cache.ScanCrawler;
    910import static eu.clarin.sru.fcs.aggregator.sopt.Corpus.ROOT_HANDLE;
    1011import eu.clarin.sru.fcs.aggregator.util.SRUCQL;
     
    136137
    137138    public void loadChildren(Treeitem item) {
     139         logger.info("LOADING CHILDREN");
    138140        // get first child
    139141        Treeitem childTreeitem = (Treeitem) item.getTreechildren().getChildren().get(0);
     
    144146        Corpus childCorpus = childNodeValue.getData();
    145147        if (childCorpus.isTemporary()) {
     148            logger.info("REPLACING TEMP WITH REAL");
    146149            // remove temporary node
    147150            remove(openedNodeValue, childTreeitem.getIndex());
     
    186189
    187190    private void initRootChildren(CenterRegistryI startingPoint) {
     191        logger.info("INITIALIZING ROOT CHILDREN");
    188192        for (Institution instit : startingPoint.getCQLInstitutions()) {
    189193            for (Endpoint endp : instit.getEndpoints()) {
    190                 try {
     194                //try {
    191195                    //TODO: temp for testing, this 3 lines are to be removed:
    192196                    //if (//!endp.getUrl().contains("uni-leipzig.de") &&
     
    196200                    //    continue;
    197201                    //}
    198 
    199                     Future<SRUScanResponse> corporaResponse = null;
    200                     SRUScanRequest corporaRequest = new SRUScanRequest(endp.getUrl());
    201                     StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
    202                     scanClause.append("=");
    203                     scanClause.append(ROOT_HANDLE);
    204                     corporaRequest.setScanClause(scanClause.toString());
    205                     corporaRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER, "true");
    206                     corporaResponse = sruClient.scan(corporaRequest);
    207                     SRUScanResponse response = corporaResponse.get(200, TimeUnit.SECONDS);
    208                     if (response != null && response.hasTerms()) {
    209                         for (SRUTerm term : response.getTerms()) {
    210                             Corpus c = new Corpus(instit, endp.getUrl());
    211                             c.setHandle(term.getValue());
    212                             c.setDisplayName(term.getDisplayTerm());
    213                             c.setNumberOfRecords(term.getNumberOfRecords());
    214                             addExtraInfo(c, term);
    215                             DefaultTreeNode<Corpus> rootChild = createNodeWithTempChildren(c);
    216                             super.getRoot().add(rootChild);
    217                         }
    218                     } else {
    219                         Corpus endpCorpus = new Corpus(endp.getInstitution(), endp.getUrl());
    220                         DefaultTreeNode<Corpus> rootChild = createNodeWithTempChildren(endpCorpus);
     202                   
     203                    List<Corpus> rootCorpora = ScanCrawler.doScan(sruClient, endp.getUrl(), instit, null);
     204                    for (Corpus c : rootCorpora) {
     205                        DefaultTreeNode<Corpus> rootChild = createNodeWithTempChildren(c);
    221206                        super.getRoot().add(rootChild);
    222207                    }
    223                 } catch (SRUClientException ex) {
    224                     logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    225                             new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
    226                 } catch (InterruptedException ex) {
    227                     logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    228                             new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
    229                 } catch (ExecutionException ex) {
    230                     logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    231                             new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
    232                 } catch (TimeoutException ex) {
    233                     logger.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
    234                             new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
    235                 }
    236             }
    237 
    238         }
    239     }
    240 
     208//                    Future<SRUScanResponse> corporaResponse = null;
     209//                    SRUScanRequest corporaRequest = new SRUScanRequest(endp.getUrl());
     210//                    StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
     211//                    scanClause.append("=");
     212//                    scanClause.append(ROOT_HANDLE);
     213//                    corporaRequest.setScanClause(scanClause.toString());
     214//                    corporaRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER, "true");
     215//                    corporaResponse = sruClient.scan(corporaRequest);
     216//                    SRUScanResponse response = corporaResponse.get(200, TimeUnit.SECONDS);
     217//                    if (response != null && response.hasTerms()) {
     218//                        for (SRUTerm term : response.getTerms()) {
     219//                            Corpus c = new Corpus(instit, endp.getUrl());
     220//                            c.setHandle(term.getValue());
     221//                            c.setDisplayName(term.getDisplayTerm());
     222//                            c.setNumberOfRecords(term.getNumberOfRecords());
     223//                            addExtraInfo(c, term);
     224//                            DefaultTreeNode<Corpus> rootChild = createNodeWithTempChildren(c);
     225//                            super.getRoot().add(rootChild);
     226//                        }
     227//                    } else {
     228//                        Corpus endpCorpus = new Corpus(endp.getInstitution(), endp.getUrl());
     229//                        DefaultTreeNode<Corpus> rootChild = createNodeWithTempChildren(endpCorpus);
     230//                        super.getRoot().add(rootChild);
     231//                    }
     232//                } catch (SRUClientException ex) {
     233//                    logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     234//                            new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
     235//                } catch (InterruptedException ex) {
     236//                    logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     237//                            new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
     238//                } catch (ExecutionException ex) {
     239//                    logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     240//                            new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
     241//                } catch (TimeoutException ex) {
     242//                    logger.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
     243//                            new String[]{ROOT_HANDLE, endp.getUrl(), ex.getClass().getName(), ex.getMessage()});
     244//                }
     245            }
     246
     247        }
     248    }
     249   
    241250    private Iterable<Corpus> getSubcorpora(Corpus corpus) {
    242 
    243         ArrayList<Corpus> subCorpora = new ArrayList<Corpus>();
    244         try {
    245             SRUScanRequest corporaRequest = new SRUScanRequest(corpus.getEndpointUrl());
    246             StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
    247             scanClause.append("=");
    248             String resourceValue = corpus.getHandle();
    249             if (corpus.getHandle() == null) {
    250                 resourceValue = ROOT_HANDLE;
    251             }
    252             if (Corpus.HANDLE_WITH_SPECIAL_CHARS.matcher(resourceValue).matches()) {
    253                 resourceValue = "%22" + resourceValue + "%22";
    254             }
    255             scanClause.append(resourceValue);
    256             corporaRequest.setScanClause(scanClause.toString());
    257             //!!!TODO request doesn't work for scan with resource handle???
    258             //corporaRequest.setExtraRequestData(SRUCQLscan.RESOURCE_INFO_PARAMETER, "true");
    259             Future<SRUScanResponse> corporaResponse = sruClient.scan(corporaRequest);
    260             SRUScanResponse response = corporaResponse.get(200, TimeUnit.SECONDS);
    261             if (response != null && response.hasTerms()) {
    262             for (SRUTerm term : response.getTerms()) {
    263                 Corpus c = new Corpus(corpus.getInstitution(), corpus.getEndpointUrl());
    264                 c.setHandle(term.getValue());
    265                 c.setDisplayName(term.getDisplayTerm());
    266                 c.setNumberOfRecords(term.getNumberOfRecords());
    267                 addExtraInfo(c, term);
    268                 subCorpora.add(c);
    269             }
    270             System.out.println("Found " + subCorpora.size() + " children");
    271         }
    272         } catch (SRUClientException ex) {
    273             logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    274                     new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
    275         } catch (InterruptedException ex) {
    276             logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    277                     new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
    278         } catch (ExecutionException ex) {
    279             logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
    280                     new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
    281         } catch (TimeoutException ex) {
    282             logger.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
    283                     new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
    284         }
    285 
    286         return subCorpora;
    287     }
     251        //get rid of institution and endpoint? get get this info from corpus
     252        return ScanCrawler.doScan(sruClient, corpus.getEndpointUrl(), corpus.getInstitution(), corpus);
     253    }
     254
     255//    private Iterable<Corpus> getSubcorpora(Corpus corpus) {
     256//        logger.info("OBTAINING SUBCORPORA");
     257//        ArrayList<Corpus> subCorpora = new ArrayList<Corpus>();
     258//        try {
     259//           
     260//           
     261//            SRUScanRequest corporaRequest = new SRUScanRequest(corpus.getEndpointUrl());
     262//            StringBuilder scanClause = new StringBuilder(SRUCQL.SCAN_RESOURCE_PARAMETER);
     263//            scanClause.append("=");
     264//            String resourceValue = corpus.getHandle();
     265//            if (corpus.getHandle() == null) {
     266//                resourceValue = ROOT_HANDLE;
     267//            }
     268//            if (Corpus.HANDLE_WITH_SPECIAL_CHARS.matcher(resourceValue).matches()) {
     269//                resourceValue = "%22" + resourceValue + "%22";
     270//            }
     271//            scanClause.append(resourceValue);
     272//            corporaRequest.setScanClause(scanClause.toString());
     273//            //!!!TODO request doesn't work for scan with resource handle???
     274//            //corporaRequest.setExtraRequestData(SRUCQLscan.RESOURCE_INFO_PARAMETER, "true");
     275//            Future<SRUScanResponse> corporaResponse = sruClient.scan(corporaRequest);
     276//            logger.info("BEFORE get " + resourceValue);
     277//            SRUScanResponse response = corporaResponse.get(200, TimeUnit.SECONDS);
     278//            logger.info("AFTER get " + resourceValue);
     279//            if (response != null && response.hasTerms()) {
     280//            for (SRUTerm term : response.getTerms()) {
     281//                Corpus c = new Corpus(corpus.getInstitution(), corpus.getEndpointUrl());
     282//                c.setHandle(term.getValue());
     283//                c.setDisplayName(term.getDisplayTerm());
     284//                c.setNumberOfRecords(term.getNumberOfRecords());
     285//                addExtraInfo(c, term);
     286//                subCorpora.add(c);
     287//            }
     288//            logger.info("OBTAINED SUBCORPORA " + subCorpora.size());
     289//        }
     290//        } catch (SRUClientException ex) {
     291//            logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     292//                    new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
     293//        } catch (InterruptedException ex) {
     294//            logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     295//                    new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
     296//        } catch (ExecutionException ex) {
     297//            logger.log(Level.SEVERE, "Error accessing corpora {0} at {1} {2} {3}",
     298//                    new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
     299//        } catch (TimeoutException ex) {
     300//            logger.log(Level.SEVERE, "Timeout scanning corpora {0} at {1} {2} {3}",
     301//                    new String[]{corpus.getHandle(), corpus.getEndpointUrl(), ex.getClass().getName(), ex.getMessage()});
     302//        }
     303//       
     304//        return subCorpora;
     305//    }
    288306
    289307    private void addExtraInfo(Corpus c, SRUTerm term) {
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sopt/CorpusRenderer.java

    r5038 r5039  
    22
    33import eu.clarin.sru.fcs.aggregator.app.WebAppListener;
     4import eu.clarin.sru.fcs.aggregator.util.ZKComp;
    45import org.zkoss.zk.ui.Component;
    56import org.zkoss.zk.ui.Executions;
    67import org.zkoss.zk.ui.event.Event;
    78import org.zkoss.zk.ui.event.EventListener;
    8 import org.zkoss.zk.ui.event.Events;
    99import org.zkoss.zul.A;
    1010import org.zkoss.zul.Checkbox;
     
    1515import org.zkoss.zul.Treechildren;
    1616import org.zkoss.zul.Treeitem;
    17 import org.zkoss.zul.TreeitemRenderer;
    1817import org.zkoss.zul.Treerow;
    1918
    2019/**
     20 * Provides methods to render a corpus tree displaying such information as
     21 * corpus name, institution, description, landing page, number of records,
     22 * language. Provides functionality for selecting/deselecting a resource in the
     23 * rendered corpus tree.
    2124 *
    2225 * @author Yana Panchenko
    23  */
    24 /**
    25  * The structure of tree
    26  *
     26 *
     27 * The structure of tree:
    2728 * <pre>
    2829 * &lt;treeitem>
     
    3637 * </pre>
    3738 */
    38 public class CorpusRendererCached implements TreeitemRenderer<DefaultTreeNode<Corpus>>, CorpusRendererI  {
    39 
    40     private Languages languages;
    41     private CorpusModelCached model;
    42 
    43     public CorpusRendererCached(CorpusModelCached model) {
    44         languages = (Languages) Executions.getCurrent().getDesktop().getWebApp().getAttribute(WebAppListener.LANGUAGES);
     39public abstract class CorpusRenderer {
     40
     41    CorpusModelI model;
     42    Languages languages;
     43
     44    public CorpusRenderer(CorpusModelI model) {
    4545        this.model = model;
    46     }
    47 
    48     @Override
    49     public void render(Treeitem treeItem, DefaultTreeNode<Corpus> treeNode, int index) throws Exception {
    50 
    51         Treerow dataRow = new Treerow();
    52         dataRow.setParent(treeItem);
    53         treeItem.setValue(treeNode);
    54         treeItem.setOpen(false);
    55         Corpus data = treeNode.getData();
    56         addCorpusDataIntoRow(dataRow, data);
    57 
    58         treeItem.addEventListener(Events.ON_OPEN, new EventListener<Event>() {
    59             @Override
    60             public void onEvent(Event event) throws Exception {
    61 
    62                 Treeitem openedTreeitem = (Treeitem) event.getTarget();
    63                 //if (openedTreeitem.isOpen()) {
    64                 //    if (model.hasChildren(openedTreeitem)) {
    65                 //        model.loadChildren(openedTreeitem);
    66                 //        openedTreeitem.setOpen(model.hasChildren(openedTreeitem));
    67                 //    } else {
    68                 //        openedTreeitem.setOpen(false);
    69                 //    }
    70                 //}
    71 
    72                 if (model.isCorpusSelected((DefaultTreeNode<Corpus>) openedTreeitem.getValue())) {
    73                     selectChildren(openedTreeitem);
    74                 }
    75             }
    76         });
    77 
    78     }
    79 
    80     //TODO check if it's working only on open children???
    81     public void selectChildren(Treeitem openedTreeitem) {
    82 
    83         for (Component comp : openedTreeitem.getChildren()) {
    84             if (comp instanceof Treechildren) {
    85                 Treechildren item = (Treechildren) comp;
    86                 for (Treeitem childItem : item.getItems()) {
    87                     updateItem(childItem, true);
    88                 }
    89                 break;
    90             }
    91         }
    92 
     46        this.languages = (Languages) Executions.getCurrent().getDesktop().getWebApp().getAttribute(WebAppListener.LANGUAGES);
    9347    }
    9448
     
    11468    }
    11569
    116     private void updateParentItem(Treeitem item, boolean checked) {
    117 
    118         // if item becomes unselected, unselect it parent
    119         if (!checked) {
    120             Treeitem parent = item.getParentItem();
    121             if (parent != null) {
    122                 for (Component comp : parent.getChildren()) {
    123                     // update the item row
    124                     if (comp instanceof Treerow) {
    125                         Treerow row = (Treerow) comp;
    126                         Checkbox checkbox = (Checkbox) row.getFirstChild().getFirstChild();
    127                         DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) parent.getValue();
    128                         checkbox.setChecked(checked);
    129                         toggleCorpusCheckbox(node.getData(), checkbox, row);
    130                         updateParentItem(parent, checked);
    131                         break;
    132                     }
    133                 }
    134 
    135             }
    136         }
    137     }
    138 
    139     private void toggleCorpusCheckbox(Corpus corpus, Checkbox checkbox, Treerow row) {
    140         if (checkbox.isChecked()) {
    141             row.setZclass("z-treerow z-treerow-seld");
    142             model.addToSelected(corpus);
    143         } else {
    144             row.setZclass("z-treerow");
    145             model.removeFromSelected(corpus);
    146         }
    147     }
    148 
    149     private void addCorpusDataIntoRow(Treerow dataRow, Corpus data) {
     70    public void selectChildren(Treeitem openedTreeitem) {
     71
     72        for (Component comp : openedTreeitem.getChildren()) {
     73            if (comp instanceof Treechildren) {
     74                Treechildren item = (Treechildren) comp;
     75                for (Treeitem childItem : item.getItems()) {
     76                    updateItem(childItem, true);
     77                }
     78                break;
     79            }
     80        }
     81    }
     82
     83    protected void addCorpusDataIntoRow(Treerow dataRow, Corpus data) {
    15084        Treecell cell1 = createCellForSelectCorpus(data, dataRow);
    15185        dataRow.appendChild(cell1);
     
    194128        Treeitem eventItem = (Treeitem) dataRow.getParent();
    195129        DefaultTreeNode<Corpus> eventNode = (DefaultTreeNode<Corpus>) eventItem.getValue();
    196         if (model.isSelected(eventNode)) {
     130        if (model.isCorpusSelected(eventNode)) {
    197131            checkbox.setChecked(true);
    198132            toggleCorpusCheckbox(eventNode.getData(), checkbox, dataRow);
     
    226160        return cell;
    227161    }
    228    
     162
    229163    private Treecell createCellForCorpusNumberOfRecords(Corpus data) {
    230164        Treecell cell = new Treecell();
     
    245179            label.setParent(cell);
    246180        } else {
    247 
    248             A link = new A();
    249             link.setTarget("_blank");
    250             link.setHref(data.getLandingPage());
    251             link.setImage("img/go-home.png");
     181            A link = ZKComp.createCorpusHomeLink(data.getLandingPage());
    252182            link.setParent(cell);
    253183        }
     
    278208//        return cell;
    279209//    }
    280    
    281      private Treecell createCellForCorpusLanguage(Corpus data) {
     210    private Treecell createCellForCorpusLanguage(Corpus data) {
    282211        Treecell cell = new Treecell();
    283212        if (data.getLanguages().isEmpty()) {
     
    309238            label.setParent(langPanel);
    310239            langPanel.setParent(cell);
    311            
     240
    312241        }
    313242        return cell;
     
    319248            int okLength = 125;
    320249            if (data.getDescription().length() > okLength) {
    321                 String descrStart = // data.getDescription().substring(0, 35) + " ...";
    322                         getDisplayedText(data.getDescription(), okLength);
     250                String descrStart = getDisplayedText(data.getDescription(), okLength);
    323251                Label label = new Label(descrStart);
    324252                label.setTooltiptext(data.getDescription());
    325253                label.setParent(cell);
    326254            } else {
    327             Label label = new Label(data.getDescription());
    328             label.setMultiline(true);
    329             label.setParent(cell);
    330            
    331             //ideally should contain html5 <details> element, but only
    332             //chrome supports it as of now:
    333             //<details>
    334             //<summary>First sentence</summary>
    335             //Rest sentences.
    336             //</details>
    337            
    338            
     255                Label label = new Label(data.getDescription());
     256                label.setMultiline(true);
     257                label.setParent(cell);
     258
     259                //ideally should contain html5 <details> element, but only
     260                //chrome supports it as of now:
     261                //<details>
     262                //<summary>First sentence</summary>
     263                //Rest sentences.
     264                //</details>
     265
     266
    339267            }
    340268        } else {
     
    353281        return description.substring(0, dotIndex) + "...";
    354282    }
     283
     284    private void toggleCorpusCheckbox(Corpus corpus, Checkbox checkbox, Treerow row) {
     285        if (checkbox.isChecked()) {
     286            row.setZclass("z-treerow z-treerow-seld");
     287            model.addToSelected(corpus);
     288        } else {
     289            row.setZclass("z-treerow");
     290            model.removeFromSelected(corpus);
     291        }
     292    }
     293
     294    private void updateParentItem(Treeitem item, boolean checked) {
     295
     296        // if item becomes unselected, unselect it parent
     297        if (!checked) {
     298            Treeitem parent = item.getParentItem();
     299            if (parent != null) {
     300                for (Component comp : parent.getChildren()) {
     301                    // update the item row
     302                    if (comp instanceof Treerow) {
     303                        Treerow row = (Treerow) comp;
     304                        Checkbox checkbox = (Checkbox) row.getFirstChild().getFirstChild();
     305                        DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) parent.getValue();
     306                        checkbox.setChecked(checked);
     307                        toggleCorpusCheckbox(node.getData(), checkbox, row);
     308                        updateParentItem(parent, checked);
     309                        break;
     310                    }
     311                }
     312
     313            }
     314        }
     315    }
    355316}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sopt/CorpusRendererCached.java

    r5037 r5039  
    11package eu.clarin.sru.fcs.aggregator.sopt;
    22
    3 import eu.clarin.sru.fcs.aggregator.app.WebAppListener;
    4 import org.zkoss.zk.ui.Component;
    5 import org.zkoss.zk.ui.Executions;
    63import org.zkoss.zk.ui.event.Event;
    74import org.zkoss.zk.ui.event.EventListener;
    85import org.zkoss.zk.ui.event.Events;
    9 import org.zkoss.zul.A;
    10 import org.zkoss.zul.Checkbox;
    116import org.zkoss.zul.DefaultTreeNode;
    12 import org.zkoss.zul.Groupbox;
    13 import org.zkoss.zul.Label;
    14 import org.zkoss.zul.Treecell;
    15 import org.zkoss.zul.Treechildren;
    167import org.zkoss.zul.Treeitem;
    178import org.zkoss.zul.TreeitemRenderer;
     
    1910
    2011/**
     12 * Renders treeitem of corpora tree from corpora cache. I.e. corpora sub-resources
     13 * are pre-loaded and the information about them is taken from CorpusModelCached,
     14 * which accesses the cache.
    2115 *
    2216 * @author Yana Panchenko
     17 *
    2318 */
    24 /**
    25  * The structure of tree
    26  *
    27  * <pre>
    28  * &lt;treeitem>
    29  *   &lt;treerow>
    30  *     &lt;treecell>...&lt;/treecell>
    31  *   &lt;/treerow>
    32  *   &lt;treechildren>
    33  *     &lt;treeitem>...&lt;/treeitem>
    34  *   &lt;/treechildren>
    35  * &lt;/treeitem>
    36  * </pre>
    37  */
    38 public class CorpusRendererCached implements TreeitemRenderer<DefaultTreeNode<Corpus>>, CorpusRendererI  {
    39 
    40     private Languages languages;
    41     private CorpusModelCached model;
     19public class CorpusRendererCached extends CorpusRenderer
     20        implements TreeitemRenderer<DefaultTreeNode<Corpus>> {
    4221
    4322    public CorpusRendererCached(CorpusModelCached model) {
    44         languages = (Languages) Executions.getCurrent().getDesktop().getWebApp().getAttribute(WebAppListener.LANGUAGES);
    45         this.model = model;
     23        super(model);
    4624    }
    4725
     
    5937            @Override
    6038            public void onEvent(Event event) throws Exception {
    61 
    6239                Treeitem openedTreeitem = (Treeitem) event.getTarget();
    63                 //if (openedTreeitem.isOpen()) {
    64                 //    if (model.hasChildren(openedTreeitem)) {
    65                 //        model.loadChildren(openedTreeitem);
    66                 //        openedTreeitem.setOpen(model.hasChildren(openedTreeitem));
    67                 //    } else {
    68                 //        openedTreeitem.setOpen(false);
    69                 //    }
    70                 //}
    71 
    7240                if (model.isCorpusSelected((DefaultTreeNode<Corpus>) openedTreeitem.getValue())) {
    7341                    selectChildren(openedTreeitem);
     
    7846    }
    7947
    80     //TODO check if it's working only on open children???
    81     public void selectChildren(Treeitem openedTreeitem) {
    82 
    83         for (Component comp : openedTreeitem.getChildren()) {
    84             if (comp instanceof Treechildren) {
    85                 Treechildren item = (Treechildren) comp;
    86                 for (Treeitem childItem : item.getItems()) {
    87                     updateItem(childItem, true);
    88                 }
    89                 break;
    90             }
    91         }
    92 
    93     }
    94 
    95     public void updateItem(Treeitem item, boolean select) {
    96 
    97         for (Component comp : item.getChildren()) {
    98             // update the item row
    99             if (comp instanceof Treerow) {
    100                 Treerow row = (Treerow) comp;
    101                 Checkbox checkbox = (Checkbox) row.getFirstChild().getFirstChild();
    102                 DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) item.getValue();
    103                 checkbox.setChecked(select);
    104                 toggleCorpusCheckbox(node.getData(), checkbox, row);
    105                 // update the item children
    106             } else if (comp instanceof Treechildren) {
    107                 Treechildren children = (Treechildren) comp;
    108                 for (Treeitem childItem : children.getItems()) {
    109                     updateItem(childItem, select);
    110                 }
    111             }
    112         }
    113 
    114     }
    115 
    116     private void updateParentItem(Treeitem item, boolean checked) {
    117 
    118         // if item becomes unselected, unselect it parent
    119         if (!checked) {
    120             Treeitem parent = item.getParentItem();
    121             if (parent != null) {
    122                 for (Component comp : parent.getChildren()) {
    123                     // update the item row
    124                     if (comp instanceof Treerow) {
    125                         Treerow row = (Treerow) comp;
    126                         Checkbox checkbox = (Checkbox) row.getFirstChild().getFirstChild();
    127                         DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) parent.getValue();
    128                         checkbox.setChecked(checked);
    129                         toggleCorpusCheckbox(node.getData(), checkbox, row);
    130                         updateParentItem(parent, checked);
    131                         break;
    132                     }
    133                 }
    134 
    135             }
    136         }
    137     }
    138 
    139     private void toggleCorpusCheckbox(Corpus corpus, Checkbox checkbox, Treerow row) {
    140         if (checkbox.isChecked()) {
    141             row.setZclass("z-treerow z-treerow-seld");
    142             model.addToSelected(corpus);
    143         } else {
    144             row.setZclass("z-treerow");
    145             model.removeFromSelected(corpus);
    146         }
    147     }
    148 
    149     private void addCorpusDataIntoRow(Treerow dataRow, Corpus data) {
    150         Treecell cell1 = createCellForSelectCorpus(data, dataRow);
    151         dataRow.appendChild(cell1);
    152         Treecell cell4 = createCellForHome(data);
    153         dataRow.appendChild(cell4);
    154         Treecell cell2 = createCellForCorpusLanguage(data);
    155         dataRow.appendChild(cell2);
    156         Treecell cell6 = createCellForCorpusNumberOfRecords(data);
    157         dataRow.appendChild(cell6);
    158         Treecell cell5 = createCellForCorpusInstitution(data);
    159         dataRow.appendChild(cell5);
    160         Treecell cell3 = createCellForCorpusDescription(data);
    161         dataRow.appendChild(cell3);
    162     }
    163 
    164     private Treecell createCellForSelectCorpus(Corpus data, Treerow dataRow) {
    165         Treecell cell = new Treecell();
    166         Checkbox corpusCheckbox = createCheckboxForSelectCorpus(dataRow);
    167         corpusCheckbox.setParent(cell);
    168         if (data.getDisplayName() == null) {
    169             Label corpusLabel = new Label("");
    170             corpusLabel.setParent(cell);
    171         } else {
    172             String name = data.getDisplayName();
    173             // TODO: this is temp, before some endpoint
    174             // fix long names for their resources, that look
    175             // more like a description
    176             if (name.length() > 50) {
    177                 int firstWordEnd = name.indexOf(" ");
    178                 if (firstWordEnd > 0) {
    179                     data.setDisplayName(name.substring(0, firstWordEnd));
    180                     if (data.getDescription() == null) {
    181                         data.setDescription(name);
    182                     }
    183                 }
    184             }
    185             Label corpusLabel = new Label(data.getDisplayName());
    186             corpusLabel.setParent(cell);
    187         }
    188         return cell;
    189     }
    190 
    191     private Checkbox createCheckboxForSelectCorpus(Treerow dataRow) {
    192         Checkbox checkbox = new Checkbox();
    193         checkbox.setValue(dataRow);
    194         Treeitem eventItem = (Treeitem) dataRow.getParent();
    195         DefaultTreeNode<Corpus> eventNode = (DefaultTreeNode<Corpus>) eventItem.getValue();
    196         if (model.isSelected(eventNode)) {
    197             checkbox.setChecked(true);
    198             toggleCorpusCheckbox(eventNode.getData(), checkbox, dataRow);
    199         }
    200         checkbox.addEventListener("onCheck", new EventListener() {
    201             @Override
    202             public void onEvent(Event event) throws Exception {
    203                 Checkbox eventCheckbox = (Checkbox) event.getTarget();
    204                 Treerow eventRow = (Treerow) eventCheckbox.getValue();
    205                 Treeitem eventItem = (Treeitem) eventRow.getParent();
    206                 DefaultTreeNode<Corpus> eventNode = (DefaultTreeNode<Corpus>) eventItem.getValue();
    207                 toggleCorpusCheckbox(eventNode.getData(), eventCheckbox, eventRow);
    208                 updateParentItem(eventItem, eventCheckbox.isChecked());
    209                 for (Treeitem item : eventItem.getTreechildren().getItems()) {
    210                     updateItem(item, eventCheckbox.isChecked());
    211                 }
    212             }
    213         });
    214         return checkbox;
    215     }
    216 
    217     private Treecell createCellForCorpusInstitution(Corpus data) {
    218         Treecell cell = new Treecell();
    219         if (data.getInstitution() == null) {
    220             Label label = new Label("");
    221             label.setParent(cell);
    222         } else {
    223             Label label = new Label(data.getInstitution().getName());
    224             label.setParent(cell);
    225         }
    226         return cell;
    227     }
    228    
    229     private Treecell createCellForCorpusNumberOfRecords(Corpus data) {
    230         Treecell cell = new Treecell();
    231         if (data.getNumberOfRecords() == null) {
    232             Label label = new Label("");
    233             label.setParent(cell);
    234         } else {
    235             Label label = new Label(data.getNumberOfRecords().toString());
    236             label.setParent(cell);
    237         }
    238         return cell;
    239     }
    240 
    241     private Treecell createCellForHome(Corpus data) {
    242         Treecell cell = new Treecell();
    243         if (data.getLandingPage() == null) {
    244             Label label = new Label("");
    245             label.setParent(cell);
    246         } else {
    247 
    248             A link = new A();
    249             link.setTarget("_blank");
    250             link.setHref(data.getLandingPage());
    251             link.setImage("img/go-home.png");
    252             link.setParent(cell);
    253         }
    254         return cell;
    255     }
    256 
    257 //    private Treecell createCellForCorpusLanguage(Corpus data) {
    258 //        Treecell cell = new Treecell();
    259 //        if (!data.getLanguages().isEmpty()) {
    260 //            StringBuilder langs = new StringBuilder();
    261 //            for (String lang : data.getLanguages()) {
    262 //                String langName = languages.nameForCode(lang);
    263 //                if (langName != null) {
    264 //                    langs.append(langName);
    265 //                } else {
    266 //                    langs.append(lang);
    267 //                }
    268 //                langs.append("\n ");
    269 //
    270 //            }
    271 //            Label label = new Label(langs.toString());
    272 //            label.setMultiline(true);
    273 //            label.setParent(cell);
    274 //        } else {
    275 //            Label label = new Label("");
    276 //            label.setParent(cell);
    277 //        }
    278 //        return cell;
    279 //    }
    280    
    281      private Treecell createCellForCorpusLanguage(Corpus data) {
    282         Treecell cell = new Treecell();
    283         if (data.getLanguages().isEmpty()) {
    284             Label label = new Label("");
    285             label.setParent(cell);
    286         } else if (data.getLanguages().size() == 1) {
    287             Label label = new Label(languages.nameForCode(data.getLanguages().iterator().next()));
    288             label.setParent(cell);
    289         } else {
    290             Groupbox langPanel = new Groupbox();
    291             langPanel.setMold("3d");
    292             langPanel.setContentStyle("border:0");
    293             langPanel.setClosable(true);
    294             langPanel.setOpen(false);
    295             langPanel.setTitle("multiple");
    296             StringBuilder langs = new StringBuilder();
    297             for (String lang : data.getLanguages()) {
    298                 String langName = languages.nameForCode(lang);
    299                 if (langName != null) {
    300                     langs.append(langName);
    301                 } else {
    302                     langs.append(lang);
    303                 }
    304                 langs.append("\n ");
    305 
    306             }
    307             Label label = new Label(langs.toString());
    308             label.setMultiline(true);
    309             label.setParent(langPanel);
    310             langPanel.setParent(cell);
    311            
    312         }
    313         return cell;
    314     }
    315 
    316     private Treecell createCellForCorpusDescription(Corpus data) {
    317         Treecell cell = new Treecell();
    318         if (data.getDescription() != null) {
    319             int okLength = 125;
    320             if (data.getDescription().length() > okLength) {
    321                 String descrStart = // data.getDescription().substring(0, 35) + " ...";
    322                         getDisplayedText(data.getDescription(), okLength);
    323                 Label label = new Label(descrStart);
    324                 label.setTooltiptext(data.getDescription());
    325                 label.setParent(cell);
    326             } else {
    327             Label label = new Label(data.getDescription());
    328             label.setMultiline(true);
    329             label.setParent(cell);
    330            
    331             //ideally should contain html5 <details> element, but only
    332             //chrome supports it as of now:
    333             //<details>
    334             //<summary>First sentence</summary>
    335             //Rest sentences.
    336             //</details>
    337            
    338            
    339             }
    340         } else {
    341             Label label = new Label("");
    342             label.setParent(cell);
    343         }
    344 
    345         return cell;
    346     }
    347 
    348     private String getDisplayedText(String description, int okLength) {
    349         int dotIndex = description.indexOf(" ", okLength);
    350         if (dotIndex < 0 || dotIndex > okLength + 50) {
    351             dotIndex = okLength;
    352         }
    353         return description.substring(0, dotIndex) + "...";
    354     }
    35548}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sopt/CorpusRendererLive.java

    r3058 r5039  
    11package eu.clarin.sru.fcs.aggregator.sopt;
    22
    3 import eu.clarin.sru.fcs.aggregator.app.WebAppListener;
    4 import org.zkoss.zk.ui.Component;
    5 import org.zkoss.zk.ui.Executions;
    63import org.zkoss.zk.ui.event.Event;
    74import org.zkoss.zk.ui.event.EventListener;
    85import org.zkoss.zk.ui.event.Events;
    9 import org.zkoss.zul.A;
    10 import org.zkoss.zul.Checkbox;
    116import org.zkoss.zul.DefaultTreeNode;
    12 import org.zkoss.zul.Label;
    13 import org.zkoss.zul.Treecell;
    14 import org.zkoss.zul.Treechildren;
    157import org.zkoss.zul.Treeitem;
    168import org.zkoss.zul.TreeitemRenderer;
     
    1810
    1911/**
     12 * Renders treeitem of corpora tree in a 'live' mode. I.e. corpora sub-resources
     13 * are loaded on demand. It is necessary that CorpusModelLive is used with this
     14 * renderer.
     15 *
     16 * TODO: maybe remove the loaded sub-resources from the tree when they are
     17 * closed by the user.
    2018 *
    2119 * @author Yana Panchenko
    2220 */
    23 /**
    24  * The structure of tree
    25  *
    26  * <pre>
    27  * &lt;treeitem>
    28  *   &lt;treerow>
    29  *     &lt;treecell>...&lt;/treecell>
    30  *   &lt;/treerow>
    31  *   &lt;treechildren>
    32  *     &lt;treeitem>...&lt;/treeitem>
    33  *   &lt;/treechildren>
    34  * &lt;/treeitem>
    35  * </pre>
    36  */
    37 public class CorpusRendererLive implements TreeitemRenderer<DefaultTreeNode<Corpus>>, CorpusRendererI {
    38 
    39     private Languages languages;
    40     private CorpusModelLive model;
     21public class CorpusRendererLive extends CorpusRenderer
     22        implements TreeitemRenderer<DefaultTreeNode<Corpus>> {
    4123
    4224    public CorpusRendererLive(CorpusModelLive model) {
    43         languages = (Languages) Executions.getCurrent().getDesktop().getWebApp().getAttribute(WebAppListener.LANGUAGES);
    44         this.model = model;
     25        super(model);
    4526    }
    4627
     
    6647                if (openedTreeitem.isOpen()) {
    6748                    if (model.hasChildren(openedTreeitem)) {
    68                         model.loadChildren(openedTreeitem);
     49                        ((CorpusModelLive) model).loadChildren(openedTreeitem);
    6950                        openedTreeitem.setOpen(model.hasChildren(openedTreeitem));
    7051                    } else {
     
    8061
    8162    }
    82 
    83     //TODO check if it's working only on open children???
    84     public void selectChildren(Treeitem openedTreeitem) {
    85 
    86         for (Component comp : openedTreeitem.getChildren()) {
    87             if (comp instanceof Treechildren) {
    88                 Treechildren item = (Treechildren) comp;
    89                 for (Treeitem childItem : item.getItems()) {
    90                     updateItem(childItem, true);
    91                 }
    92                 break;
    93             }
    94         }
    95 
    96     }
    97 
    98     public void updateItem(Treeitem item, boolean select) {
    99 
    100         for (Component comp : item.getChildren()) {
    101             // update the item row
    102             if (comp instanceof Treerow) {
    103                 Treerow row = (Treerow) comp;
    104                 Checkbox checkbox = (Checkbox) row.getFirstChild().getFirstChild();
    105                 DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) item.getValue();
    106                 checkbox.setChecked(select);
    107                 toggleCorpusCheckbox(node.getData(), checkbox, row);
    108                 // update the item children
    109             } else if (comp instanceof Treechildren) {
    110                 Treechildren children = (Treechildren) comp;
    111                 for (Treeitem childItem : children.getItems()) {
    112                     updateItem(childItem, select);
    113                 }
    114             }
    115         }
    116 
    117     }
    118 
    119     private void updateParentItem(Treeitem item, boolean checked) {
    120 
    121         // if item becomes unselected, unselect it parent
    122         if (!checked) {
    123             Treeitem parent = item.getParentItem();
    124             if (parent != null) {
    125                 for (Component comp : parent.getChildren()) {
    126                     // update the item row
    127                     if (comp instanceof Treerow) {
    128                         Treerow row = (Treerow) comp;
    129                         Checkbox checkbox = (Checkbox) row.getFirstChild().getFirstChild();
    130                         DefaultTreeNode<Corpus> node = (DefaultTreeNode<Corpus>) parent.getValue();
    131                         checkbox.setChecked(checked);
    132                         toggleCorpusCheckbox(node.getData(), checkbox, row);
    133                         updateParentItem(parent, checked);
    134                         break;
    135                     }
    136                 }
    137 
    138             }
    139         }
    140     }
    141 
    142     private void toggleCorpusCheckbox(Corpus corpus, Checkbox checkbox, Treerow row) {
    143         if (checkbox.isChecked()) {
    144             row.setZclass("z-treerow z-treerow-seld");
    145             model.addToSelected(corpus);
    146         } else {
    147             row.setZclass("z-treerow");
    148             model.removeFromSelected(corpus);
    149         }
    150     }
    151 
    152     private void addCorpusDataIntoRow(Treerow dataRow, Corpus data) {
    153         Treecell cell1 = createCellForSelectCorpus(data, dataRow);
    154         dataRow.appendChild(cell1);
    155         Treecell cell4 = createCellForHome(data);
    156         dataRow.appendChild(cell4);
    157         Treecell cell2 = createCellForCorpusLanguage(data);
    158         dataRow.appendChild(cell2);
    159         Treecell cell5 = createCellForCorpusInstitution(data);
    160         dataRow.appendChild(cell5);
    161         Treecell cell3 = createCellForCorpusDescription(data);
    162         dataRow.appendChild(cell3);
    163     }
    164 
    165     private Treecell createCellForSelectCorpus(Corpus data, Treerow dataRow) {
    166         Treecell cell = new Treecell();
    167         Checkbox corpusCheckbox = createCheckboxForSelectCorpus(dataRow);
    168         corpusCheckbox.setParent(cell);
    169         if (data.getDisplayName() == null) {
    170             Label corpusLabel = new Label("");
    171             corpusLabel.setParent(cell);
    172         } else {
    173             Label corpusLabel = new Label(data.getDisplayName());
    174             corpusLabel.setParent(cell);
    175         }
    176         return cell;
    177     }
    178 
    179     private Checkbox createCheckboxForSelectCorpus(Treerow dataRow) {
    180         Checkbox checkbox = new Checkbox();
    181         checkbox.setValue(dataRow);
    182         Treeitem eventItem = (Treeitem) dataRow.getParent();
    183         DefaultTreeNode<Corpus> eventNode = (DefaultTreeNode<Corpus>) eventItem.getValue();
    184         if (model.isSelected(eventNode)) {
    185             checkbox.setChecked(true);
    186             toggleCorpusCheckbox(eventNode.getData(), checkbox, dataRow);
    187         }
    188         checkbox.addEventListener("onCheck", new EventListener() {
    189             @Override
    190             public void onEvent(Event event) throws Exception {
    191                 Checkbox eventCheckbox = (Checkbox) event.getTarget();
    192                 Treerow eventRow = (Treerow) eventCheckbox.getValue();
    193                 Treeitem eventItem = (Treeitem) eventRow.getParent();
    194                 DefaultTreeNode<Corpus> eventNode = (DefaultTreeNode<Corpus>) eventItem.getValue();
    195                 toggleCorpusCheckbox(eventNode.getData(), eventCheckbox, eventRow);
    196                 updateParentItem(eventItem, eventCheckbox.isChecked());
    197                 for (Treeitem item : eventItem.getTreechildren().getItems()) {
    198                     updateItem(item, eventCheckbox.isChecked());
    199                 }
    200             }
    201         });
    202         return checkbox;
    203     }
    204 
    205     private Treecell createCellForCorpusInstitution(Corpus data) {
    206         Treecell cell = new Treecell();
    207         if (data.getInstitution() == null) {
    208             Label label = new Label("");
    209             label.setParent(cell);
    210         } else {
    211             Label label = new Label(data.getInstitution().getName());
    212             label.setParent(cell);
    213         }
    214         return cell;
    215     }
    216 
    217     private Treecell createCellForHome(Corpus data) {
    218         Treecell cell = new Treecell();
    219         if (data.getLandingPage() == null) {
    220             Label label = new Label("");
    221             label.setParent(cell);
    222         } else {
    223 
    224             A link = new A();
    225             link.setTarget("_blank");
    226             link.setHref(data.getLandingPage());
    227             link.setImage("img/go-home.png");
    228             link.setParent(cell);
    229         }
    230         return cell;
    231     }
    232 
    233     private Treecell createCellForCorpusLanguage(Corpus data) {
    234         Treecell cell = new Treecell();
    235         if (!data.getLanguages().isEmpty()) {
    236             StringBuilder langs = new StringBuilder();
    237             for (String lang : data.getLanguages()) {
    238                 String langName = languages.nameForCode(lang);
    239                 if (langName != null) {
    240                     langs.append(langName);
    241                 } else {
    242                     langs.append(lang);
    243                 }
    244                 langs.append("\n ");
    245 
    246             }
    247             Label label = new Label(langs.toString());
    248             label.setMultiline(true);
    249             label.setParent(cell);
    250         } else {
    251             Label label = new Label("");
    252             label.setParent(cell);
    253         }
    254         return cell;
    255     }
    256 
    257     private Treecell createCellForCorpusDescription(Corpus data) {
    258         Treecell cell = new Treecell();
    259         if (data.getDescription() != null) {
    260             //if (data.getDescription().length() > 40) {
    261             //    String descrStart = data.getDescription().substring(0, 35) + " ...";
    262             //    Label label = new Label(descrStart);
    263             //    label.setTooltiptext(data.getDescription());
    264             //    label.setParent(cell);
    265             //} else {
    266             Label label = new Label(data.getDescription());
    267             label.setMultiline(true);
    268             label.setParent(cell);
    269             //}
    270         } else {
    271             Label label = new Label("");
    272             label.setParent(cell);
    273         }
    274 
    275         return cell;
    276     }
    27763}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sopt/Languages.java

    r5035 r5039  
    1717public class Languages {
    1818   
    19     private Map<String,String> code2Name = new HashMap<String,String>();
    20     private Map<String,String> code22Code = new HashMap<String,String>();
     19   
     20    private Map<String,Language> code2Lang = new HashMap<String,Language>();
     21   
    2122    public static final String LANGUAGES_FILE_PATH = "/lang/ISO-639-2_utf-8.txt";
    2223    public static final String LANGUAGES_FILE_ENCODING = "UTF-8";
     
    2728    }
    2829   
    29     public String nameForCode(String code) {
    30         return this.code2Name.get(code);
     30    /**
     31     * Gets language by its ISO 639 language code.
     32     *
     33     * @param code ISO 639/1, 639/2T or 639/2B language code
     34     * @return language
     35     */
     36    public Language langForCode(String code) {
     37        return this.code2Lang.get(code);
    3138    }
    3239   
    33     public String code2ForCode(String code) {
    34         return this.code22Code.get(code);
     40    /**
     41     * Gets language name by the ISO 639 language code.
     42     *
     43     * @param code ISO 639/1, 639/2T or 639/2B language code
     44     * @return language name in English
     45     */
     46    public String nameForCode(String code) {
     47        if (this.code2Lang.containsKey(code)) {
     48            return this.code2Lang.get(code).getNameEn();
     49        }
     50        return code;
    3551    }
    36    
     52
     53    /**
     54     * Gets all known to it ISO 639/1, 639/2T and 639/2B language codes.
     55     *
     56     * @return language codes
     57     */
    3758    public Set<String> getCodes() {
    38         return this.code2Name.keySet();
     59        return this.code2Lang.keySet();
    3960    }
    4061
     
    5374                    String alpha2 = splitted[2];
    5475                    String enName = splitted[3];
     76                    Language lang = new Language(alpha2, alpha3t, alpha3b, enName);
    5577                    if (!alpha3b.isEmpty()) {
    56                         this.code2Name.put(alpha3b, enName);
    57                         this.code22Code.put(alpha3b, alpha2);
     78                        this.code2Lang.put(alpha3b, lang);
    5879                    }
    5980                    if (!alpha3t.isEmpty()) {
    60                         this.code2Name.put(alpha3t, enName);
    61                         this.code22Code.put(alpha3t, alpha2);
     81                        this.code2Lang.put(alpha3t, lang);
    6282                    }
    6383                    if (!alpha2.isEmpty()) {
    64                         this.code2Name.put(alpha2, enName);
    65                         this.code22Code.put(alpha2, alpha2);
     84                        this.code2Lang.put(alpha2, lang);
    6685                    }
    6786                }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sresult/SearchResult.java

    r4069 r5039  
    2121    private Corpus corpus;
    2222    private String searchString;
     23    private int startRecord;
     24    private int endRecord;
    2325    private Future<SRUSearchRetrieveResponse> futureResponse;
    2426    private SRUSearchRetrieveResponse response;
     
    3638    }
    3739   
    38     public SearchResult(Corpus corpus, String searchString) {
     40    public SearchResult(Corpus corpus, String searchString, int startRecord , int endRecord) {
    3941        this.corpus = corpus;
    4042        this.searchString = searchString;
     43        this.startRecord = startRecord;
     44        this.endRecord = endRecord;
     45    }
     46
     47    public int getStartRecord() {
     48        return startRecord;
     49    }
     50
     51    public int getEndRecord() {
     52        return endRecord;
    4153    }
    4254
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/sresult/SearchResultRecordRenderer.java

    r3038 r5039  
    77import eu.clarin.sru.client.fcs.DataViewKWIC;
    88import eu.clarin.sru.client.fcs.Resource;
    9 import eu.clarin.sru.fcs.aggregator.sresult.SearchResult;
    10 import java.util.ArrayList;
    119import java.util.List;
    1210import java.util.logging.Level;
     
    1715import org.zkoss.zul.A;
    1816import org.zkoss.zul.Cell;
    19 import org.zkoss.zul.Checkbox;
    20 import org.zkoss.zul.DefaultTreeNode;
    2117import org.zkoss.zul.Hlayout;
    2218import org.zkoss.zul.Image;
    2319import org.zkoss.zul.Label;
    24 import org.zkoss.zul.Popup;
    2520import org.zkoss.zul.Row;
    2621import org.zkoss.zul.RowRenderer;
    27 import org.zkoss.zul.Treeitem;
    28 import org.zkoss.zul.Treerow;
    2922import org.zkoss.zul.Vlayout;
    3023import org.zkoss.zul.Window;
     
    194187    }
    195188   
     189   
     190   
    196191}
  • SRUAggregator/trunk/src/main/webapp/about-fcs.html

    r5038 r5039  
    2222        <p style="text-align:left">
    2323        Currently, 11 centers from Germany, Netherlands and Czech Republic make more than 40 resources available
    24         to the linguistic researches via the common interface,
     24        to the linguistic researchers via the common interface,
    2525        and this number is growing.
    2626        </p>
  • SRUAggregator/trunk/src/main/webapp/help-fcs.html

    r5038 r5039  
    1414        <h3>Search Options - adjusting search criteria</h3>
    1515        <p style="text-align:left">To select specific corpora based on their name or language and to specify number of search results
    16             per corpus per page, click on the 'Search options' link. Here, you can filter resources based on the language,
    17             select specific resources, set the number of hits per corpus per page.</p>
     16            (hits) per corpus per page, click on the 'Search options' link. Here, you can filter resources based on the language,
     17            select specific resources, set the maximum number of hits.</p>
    1818        <br/>
    1919        <h3>Search Results - inspecting search results</h3>
     
    2323            go to the menu and select either 'Export to Personal Workspace', 'Download' or 'Use WebLicht' menu item.
    2424            This menu appears only after all the results on the page have been loaded.
    25             To get the next N records from each corpus, click the 'next' arrow at the bottom of 'Search results' page.
     25            To get the next hits from each corpus, click the 'next' arrow at the bottom of 'Search results' page.
    2626        </p>
    2727        <br/>
     
    3030            <a target="_blank" href="http://weblicht.sfs.uni-tuebingen.de/weblichtwiki/index.php/FCS_Aggregator">
    3131                Aggegator wiki page</a>.
    32             If you still cannot not find an answer to your question, or if want to send a feedback,
     32            If you still cannot find an answer to your question, or if want to send a feedback,
    3333            you can write to Clarin-D helpdesk:
    3434        </p>
  • SRUAggregator/trunk/src/main/webapp/index.zul

    r5037 r5039  
    100100                            <progressmeter visible="false" id="pMeter" value="0" width="300px"/>
    101101                            <hlayout>
    102                                 <a id="prevButton" visible="false" image="img/arrow_left_blue.png"
     102                                <a id="prevButton" visible="false" image="img/arrow_left_blue.png" tooltip="tooltipPrev"
    103103                                    hoverImage="img/arrow_left_green.png" style="margin-right:20px;"/>
    104                                 <a id="nextButton" visible="false" image="img/arrow_right_blue.png"
     104                                <a id="nextButton" visible="false" image="img/arrow_right_blue.png" tooltip="tooltipNext"
    105105                                    hoverImage="img/arrow_right_green.png" dir="reverse"
    106106                                    style="margin-left:20px;"/>
     
    159159            </grid>
    160160        </popup>
     161       
     162        <popup id="tooltipPrev"><label id="tooltipPrevText" value="previous N hits from each resource" style="font-weight:bold"/></popup>
     163        <popup id="tooltipNext"><label id="tooltipNextText" value="next N hits from each resource" style="font-weight:bold"/></popup>
    161164
    162165    </window>
Note: See TracChangeset for help on using the changeset viewer.