Changeset 5957


Ignore:
Timestamp:
01/28/15 09:14:40 (9 years ago)
Author:
emanuel.dima@uni-tuebingen.de
Message:
  1. alpha15: added support for new spec explains/search; misc UI corrections
Location:
SRUAggregator/trunk
Files:
1 added
24 edited
2 copied

Legend:

Unmodified
Added
Removed
  • SRUAggregator/trunk/aggregator_development.yml

    r5954 r5957  
    1414
    1515  ENDPOINTS_SCAN_TIMEOUT_MS: 60000
    16   ENDPOINTS_SEARCH_TIMEOUT_MS: 10000
    17   EXECUTOR_SHUTDOWN_TIMEOUT_MS: 100
     16  ENDPOINTS_SEARCH_TIMEOUT_MS: 30000
     17  EXECUTOR_SHUTDOWN_TIMEOUT_MS: 1000
    1818
    1919# use the simple server factory, run on a single port
     
    3232  loggers:
    3333    eu.clarin.sru.fcs.aggregator: INFO
    34     eu.clarin.sru.client: INFO
     34    eu.clarin.sru.client: ERROR
    3535
    3636  appenders:
  • SRUAggregator/trunk/pom.xml

    r5954 r5957  
    88        <groupId>eu.clarin.sru.fcs</groupId>
    99        <artifactId>Aggregator2</artifactId>
    10         <version>2.0.0-alpha-14</version>
     10        <version>2.0.0-alpha-15</version>
    1111        <name>FCS Aggregator</name>
    1212
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/Aggregator.java

    r5954 r5957  
    1313import eu.clarin.sru.client.SRUVersion;
    1414import eu.clarin.sru.client.fcs.ClarinFCSClientBuilder;
     15import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescriptionParser;
    1516import eu.clarin.sru.fcs.aggregator.client.ThrottledClient;
    1617import eu.clarin.sru.fcs.aggregator.scan.Corpus;
     
    2526import java.io.IOException;
    2627import java.io.InputStream;
     28import java.util.ArrayList;
    2729import java.util.Collections;
    2830import java.util.HashMap;
     
    8688 * @author edima
    8789 *
    88  * TODO: support new spec-compatible centres, see Oliver's mail
    89  * (use SRUClient's extraResponseData POJOs)
     90 * DONE: support new spec-compatible centre
    9091 *
    9192 * TODO: version page: credits, open source, see vcr/version page
     
    9697 *
    9798 * TODO: disable popups easily
    98  *
    99  * TODO: Fix activeSearch memory leak (gc searches older than...)
    10099 *
    101100 * TODO: Use weblicht with results
     
    209208                                .setSocketTimeout(params.ENDPOINTS_SCAN_TIMEOUT_MS)
    210209                                .addDefaultDataViewParsers()
     210                                .registerExtraResponseDataParser(
     211                                                new ClarinFCSEndpointDescriptionParser())
    211212                                .enableLegacySupport()
    212213                                .buildThreadedClient(),
    213                                 params.SCAN_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT,
    214                                 params.SEARCH_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT
     214                                params.SCAN_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT
    215215                );
    216216                sruSearchClient = new ThrottledClient(
     
    221221                                .enableLegacySupport()
    222222                                .buildThreadedClient(),
    223                                 params.SCAN_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT,
    224223                                params.SEARCH_MAX_CONCURRENT_REQUESTS_PER_ENDPOINT
    225224                );
     
    269268                        Search sr = new Search(sruSearchClient, version, searchStatsAtom.get(),
    270269                                        corpora, searchString, searchLang, 1, maxRecords);
     270                        if ((activeSearches.size() % 100) == 0) {
     271                                List<Long> toBeRemoved = new ArrayList<Long>();
     272                                long t0 = System.currentTimeMillis();
     273                                for (Map.Entry<Long, Search> e : activeSearches.entrySet()) {
     274                                        if (t0 - e.getValue().getCreatedAt() > 1800 * 1000) {
     275                                                toBeRemoved.add(e.getKey());
     276                                        }
     277                                }
     278                                for (Long l : toBeRemoved) {
     279                                        activeSearches.remove(l);
     280                                }
     281                        }
    271282                        activeSearches.put(sr.getId(), sr);
    272283                        return sr;
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/client/ExplainOperation.java

    r5937 r5957  
    33import eu.clarin.sru.client.SRUCallback;
    44import eu.clarin.sru.client.SRUClientException;
    5 import eu.clarin.sru.client.SRUScanRequest;
    6 import eu.clarin.sru.client.SRUScanResponse;
     5import eu.clarin.sru.client.SRUExplainRequest;
     6import eu.clarin.sru.client.SRUExplainResponse;
    77import eu.clarin.sru.client.SRUThreadedClient;
    88
     
    1111 * @author edima
    1212 */
    13 class ScanOperation implements Operation<SRUScanRequest, SRUScanResponse>, SRUCallback<SRUScanRequest, SRUScanResponse> {
    14         SRUScanRequest request;
    15         ThrottledClient.ScanCallback callback;
     13class ExplainOperation implements Operation<SRUExplainRequest, SRUExplainResponse>, SRUCallback<SRUExplainRequest, SRUExplainResponse> {
     14        SRUExplainRequest request;
     15        ThrottledClient.ExplainCallback callback;
    1616        GenericClient client;
    1717        OpStats stats;
    1818
    19         public ScanOperation(SRUScanRequest request, ThrottledClient.ScanCallback callback) {
     19        public ExplainOperation(SRUExplainRequest request, ThrottledClient.ExplainCallback callback) {
    2020                this.request = request;
    2121                this.callback = callback;
     
    3131        public void execute(SRUThreadedClient sruClient) {
    3232                try {
    33                         sruClient.scan(request, this);
     33                        sruClient.explain(request, this);
    3434                } catch (SRUClientException xc) {
    3535                        onError(request, xc);
     
    3838
    3939        @Override
    40         public void onSuccess(SRUScanResponse response) {
     40        public void onSuccess(SRUExplainResponse response) {
    4141                try {
    4242                        stats.finishedTime = System.currentTimeMillis();
     
    4848
    4949        @Override
    50         public void onError(SRUScanRequest request, SRUClientException error) {
     50        public void onError(SRUExplainRequest request, SRUClientException error) {
    5151                try {
    5252                        stats.finishedTime = System.currentTimeMillis();
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/client/GenericClient.java

    r5901 r5957  
    1313 */
    1414class GenericClient {
     15
    1516        private final SRUThreadedClient sruClient;
    1617        public final int maxConcurrentRequests;
     18
    1719        // queue of operations waiting for execution
    18 
    1920        static class ExecQueue {
    2021
     
    6162                }
    6263        }
     64
     65        public void shutdown() {
     66                sruClient.shutdown();
     67        }
     68
     69        public void shutdownNow() {
     70                sruClient.shutdownNow();
     71        }
    6372}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/client/ThrottledClient.java

    r5901 r5957  
    22
    33import eu.clarin.sru.client.SRUClientException;
     4import eu.clarin.sru.client.SRUExplainRequest;
     5import eu.clarin.sru.client.SRUExplainResponse;
    46import eu.clarin.sru.client.SRUScanRequest;
    57import eu.clarin.sru.client.SRUScanResponse;
     
    2022        }
    2123
     24        public interface ExplainCallback {
     25
     26                void onSuccess(SRUExplainResponse response, Stats stats);
     27
     28                void onError(SRUExplainRequest request, SRUClientException error, Stats stats);
     29        }
     30
    2231        public interface ScanCallback {
    2332
     
    3443        }
    3544
    36         SRUThreadedClient sruClient;
    37         GenericClient scanClient;
    38         GenericClient searchClient;
     45        GenericClient client;
    3946
    40         public ThrottledClient(SRUThreadedClient sruClient, int maxConcurrentScanRequests, int maxConcurrentSearchRequests) {
    41                 this.sruClient = sruClient;
    42                 this.scanClient = new GenericClient(sruClient, maxConcurrentScanRequests);
    43                 this.searchClient = new GenericClient(sruClient, maxConcurrentSearchRequests);
     47        public ThrottledClient(SRUThreadedClient sruClient, int maxConcurrentRequests) {
     48                this.client = new GenericClient(sruClient, maxConcurrentRequests);
     49        }
     50
     51        public void explain(SRUExplainRequest request, ExplainCallback callback) {
     52                client.execute(request.getBaseURI(), new ExplainOperation(request, callback));
    4453        }
    4554
    4655        public void scan(SRUScanRequest request, ScanCallback callback) {
    47                 scanClient.execute(request.getBaseURI(), new ScanOperation(request, callback));
     56                client.execute(request.getBaseURI(), new ScanOperation(request, callback));
    4857        }
    4958
    5059        public void searchRetrieve(SRUSearchRetrieveRequest request, SearchCallback callback) {
    51                 searchClient.execute(request.getBaseURI(), new SearchOperation(request, callback));
     60                client.execute(request.getBaseURI(), new SearchOperation(request, callback));
    5261        }
    5362
    5463        public void shutdown() {
    55                 sruClient.shutdown();
     64                client.shutdown();
    5665        }
    5766
    5867        public void shutdownNow() {
    59                 sruClient.shutdownNow();
     68                client.shutdownNow();
    6069        }
    6170}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/CenterRegistryForTesting.java

    r5893 r5957  
    33import java.util.ArrayList;
    44import java.util.List;
    5 import java.util.logging.Level;
    65import java.util.logging.Logger;
    76
     
    1918    private static final Logger logger = Logger.getLogger(CenterRegistryForTesting.class.getName());
    2019    private boolean hasChildrenLoaded = false;
    21     private List<Institution> centers = new ArrayList<Institution>();
    22     private static final String[] INSTITUTION_URLS = new String[]{
    23                 "http://130.183.206.32/restxml/3",
    24                 "http://130.183.206.32/restxml/5"
    25     };
    26     private static final String[] INSTITUTION_NAMES = new String[]{
    27                 "IDS",
    28                 "MPI"
    29     };
    30     private static final String[][] INSTITUTION_ENDPOINTS = new String[][]{
    31         new String[]{ // MPI endpoints, contact person Olha
    32                         "https://clarin.phonetik.uni-muenchen.de/BASSRU/",
    33                         "http://lux17.mpi.nl/cqltest"
    34         }
    35     };
     20        private List<Institution> centers = new ArrayList<Institution>() {
     21                {
     22                        Institution inst = new Institution("test_IDS", null);
     23                        inst.addEndpoint("https://clarin.ids-mannheim.de/digibibsru-new");
     24                        add(inst);
     25                }
     26        };
    3627
    3728    @Override
    3829    public boolean hasCQLInstitutionsLoaded() {
    39         return hasChildrenLoaded;
     30                return true;
    4031    }
    4132
    4233    @Override
    4334    public void loadCQLInstitutions() {
    44         if (hasChildrenLoaded) {
    45             return;
    46         }
    47         hasChildrenLoaded = true;
    48         loadCQLInstitutionsForTesting();
    49         logger.log(Level.FINE, "Number of Centers: {0}", centers.size());
    5035    }
    5136
    5237    @Override
    5338    public List<Institution> getCQLInstitutions() {
    54         loadCQLInstitutions();
    5539        return centers;
    5640    }
     
    5842    @Override
    5943    public Institution getCQLInstitution(int index) {
    60         loadCQLInstitutions();
    6144        if (index >= centers.size()) {
    6245            return null;
     
    6447        return centers.get(index);
    6548    }
    66 
    67     private void loadCQLInstitutionsForTesting() {
    68         for (int i = 0; i < INSTITUTION_ENDPOINTS.length; i++) {
    69             Institution institution = new Institution(INSTITUTION_NAMES[i], INSTITUTION_URLS[i]);
    70             for (int j = 0; j < INSTITUTION_ENDPOINTS.length; j++) {
    71                                 institution.addEndpoint(INSTITUTION_ENDPOINTS[i][j]);
    72             }
    73                         if (!institution.getEndpoints().isEmpty()) {
    74                                 centers.add(institution);
    75                         }
    76         }
    77     }
    7849}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Corpora.java

    r5954 r5957  
    7878                        @Override
    7979                        public void call(Corpus c) {
    80                                 if (c.getEndpointUrl().equals(endpointUrl)) {
     80                                if (c.getEndpoint().getUrl().equals(endpointUrl)) {
    8181                                        found.add(c);
    8282                                }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Corpus.java

    r5900 r5957  
    1818 */
    1919public class Corpus {
     20
    2021        private static final org.slf4j.Logger log = LoggerFactory.getLogger(Corpus.class);
    2122
     
    2425
    2526        private Institution institution;
    26         private String endpointUrl;
     27        private Endpoint endpoint;
    2728        private String handle;
    2829        private Integer numberOfRecords;
    29         private String displayName;
    3030        private Set<String> languages = new HashSet<String>();
    3131        private String landingPage;
     
    3737        }
    3838
    39         public Corpus(Institution institution, String endpointUrl) {
     39        public Corpus(Institution institution, Endpoint endpoint) {
    4040                this.institution = institution;
    41                 this.endpointUrl = endpointUrl;
     41                this.endpoint = endpoint;
    4242        }
    4343
    4444        public String getId() {
    45                 return endpointUrl + "#" + handle;
     45                return endpoint.getUrl() + "#" + handle;
    4646        }
    4747
     
    6161        }
    6262
    63 
    6463        public String getHandle() {
    6564                return handle;
     
    7877        }
    7978
    80         public String getDisplayName() {
    81                 return displayName;
     79        public Endpoint getEndpoint() {
     80                return endpoint;
    8281        }
    8382
    84         public void setDisplayName(String displayName) {
    85                 this.displayName = displayName;
    86         }
    87 
    88         public String getEndpointUrl() {
    89                 return endpointUrl;
    90         }
    91 
    92         public void setEndpointUrl(String endpointUrl) {
    93                 this.endpointUrl = endpointUrl;
     83        public void setEndpoint(Endpoint endpoint) {
     84                this.endpoint = endpoint;
    9485        }
    9586
     
    146137        public int hashCode() {
    147138                int hash = 3;
    148                 hash = 29 * hash + (this.endpointUrl != null ? this.endpointUrl.hashCode() : 0);
     139                hash = 29 * hash + (this.endpoint != null ? this.endpoint.hashCode() : 0);
    149140                hash = 29 * hash + (this.handle != null ? this.handle.hashCode() : 0);
    150141                return hash;
     
    160151                }
    161152                final Corpus other = (Corpus) obj;
    162                 if ((this.endpointUrl == null) ? (other.endpointUrl != null) : !this.endpointUrl.equals(other.endpointUrl)) {
     153                if ((this.endpoint == null) ? (other.endpoint != null) : !this.endpoint.equals(other.endpoint)) {
    163154                        return false;
    164155                }
     
    171162        @Override
    172163        public String toString() {
    173                 return "Corpus{" + "endpointUrl=" + endpointUrl + ", handle=" + handle + '}';
     164                return "Corpus{" + "endpoint=" + endpoint + ", handle=" + handle + '}';
    174165        }
    175166
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Endpoint.java

    r5937 r5957  
    11package eu.clarin.sru.fcs.aggregator.scan;
    22
    3 import java.util.*;
     3/**
     4 * @author edima
     5 */
     6public class Endpoint {
    47
    5 /**
    6  * Institution. Contains information about institution name and link (url). Can
    7  * have information about its CQL Endpoints.
    8  *
    9  * @author Yana Panchenko
    10  */
    11 public class Institution {
    12 
    13         private String name;
    14         private String link;
    15         private Set<String> endpoints;
     8        private String url;
     9        private FCSProtocolVersion protocol;
    1610
    1711        // for JSON deserialization
    18         public Institution() {
     12        public Endpoint() {
    1913        }
    2014
    21         public Institution(String name, String link) {
    22                 this.name = name;
    23                 this.link = link;
    24                 this.endpoints = new LinkedHashSet<String>();
     15        public Endpoint(String url, FCSProtocolVersion protocol) {
     16                this.url = url;
     17                this.protocol = protocol;
    2518        }
    2619
    27         public String addEndpoint(String endpointUrl) {
    28                 endpoints.add(endpointUrl);
    29                 return endpointUrl;
     20        public String getUrl() {
     21                return url;
    3022        }
    3123
    32         public String getName() {
    33                 return name;
     24        public FCSProtocolVersion getProtocol() {
     25                return protocol;
    3426        }
    3527
    36         public String getLink() {
    37                 return link;
     28        public void setUrl(String url) {
     29                this.url = url;
    3830        }
    3931
    40         public Set<String> getEndpoints() {
    41                 return this.endpoints;
     32        public void setProtocol(FCSProtocolVersion protocol) {
     33                this.protocol = protocol;
    4234        }
    4335
    4436        @Override
    4537        public String toString() {
    46                 if (name != null && name.length() > 0) {
    47                         return name;
    48                 } else {
    49                         return link;
    50                 }
     38                return url;
    5139        }
    5240
     
    5442        public int hashCode() {
    5543                https://primes.utm.edu/lists/small/1000.txt
    56                 return name.hashCode() * 2953;
     44                return url.hashCode() * 1049;
    5745        }
    5846
    5947        @Override
    6048        public boolean equals(Object obj) {
    61                 if (!(obj instanceof Institution)) {
     49                if (!(obj instanceof Endpoint)) {
    6250                        return false;
    6351                }
    64                 Institution i = (Institution) obj;
    65                 return i.name.equals(name);
     52                Endpoint e = (Endpoint) obj;
     53                return e.url.equals(url) && e.protocol.equals(protocol);
    6654        }
    6755}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/Institution.java

    r5900 r5957  
    1313        private String name;
    1414        private String link;
    15         private Set<String> endpoints;
     15        private Set<Endpoint> endpoints;
    1616
    1717        // for JSON deserialization
     
    2222                this.name = name;
    2323                this.link = link;
    24                 this.endpoints = new LinkedHashSet<String>();
     24                this.endpoints = new LinkedHashSet<Endpoint>();
    2525        }
    2626
    2727        public String addEndpoint(String endpointUrl) {
    28                 endpoints.add(endpointUrl);
     28                endpoints.add(new Endpoint(endpointUrl, FCSProtocolVersion.LEGACY));
    2929                return endpointUrl;
    3030        }
     
    3838        }
    3939
    40         public Set<String> getEndpoints() {
     40        public Set<Endpoint> getEndpoints() {
    4141                return this.endpoints;
    4242        }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/ScanCrawlTask.java

    r5893 r5957  
    4545                        log.info("ScanCrawlTask: Initiating crawl");
    4646                        CenterRegistry centerRegistry = new CenterRegistryLive(centerRegistryUrl, filter);
     47                        centerRegistry.getCQLInstitutions().add(0,
     48                                        new Institution("test_IDS", null) {
     49                                                {
     50                                                        addEndpoint("https://clarin.ids-mannheim.de/digibibsru-new");
     51                                                }
     52                                        });
     53//                      CenterRegistry centerRegistry = new CenterRegistryForTesting();
    4754                        ScanCrawler scanCrawler = new ScanCrawler(centerRegistry, sruClient, cacheMaxDepth);
    4855
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/scan/ScanCrawler.java

    r5954 r5957  
    44import eu.clarin.sru.client.SRUClientException;
    55import eu.clarin.sru.client.SRUDiagnostic;
     6import eu.clarin.sru.client.SRUExplainRequest;
     7import eu.clarin.sru.client.SRUExplainResponse;
     8import eu.clarin.sru.client.SRUExtraResponseData;
    69import eu.clarin.sru.client.SRUScanRequest;
    710import eu.clarin.sru.client.SRUScanResponse;
    811import eu.clarin.sru.client.SRUTerm;
     12import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription;
     13import eu.clarin.sru.client.fcs.ClarinFCSEndpointDescription.ResourceInfo;
    914import eu.clarin.sru.fcs.aggregator.client.ThrottledClient;
    1015import eu.clarin.sru.fcs.aggregator.util.SRUCQL;
    1116import eu.clarin.sru.fcs.aggregator.util.Throw;
    1217import java.net.SocketTimeoutException;
     18import java.util.HashSet;
     19import java.util.List;
     20import java.util.Map;
    1321import org.slf4j.LoggerFactory;
    1422import org.w3c.dom.DocumentFragment;
     
    4553                for (Institution institution : centerRegistry.getCQLInstitutions()) {
    4654                        cache.addInstitution(institution);
    47                         Iterable<String> endpoints = institution.getEndpoints();
    48                         for (String endp : endpoints) {
    49                                 ScanTask st = new ScanTask(institution, endp, null, cache, 0);
    50                                 scanForCorpora(st);
     55                        Iterable<Endpoint> endpoints = institution.getEndpoints();
     56                        for (Endpoint endp : endpoints) {
     57                                new ExplainTask(institution, endp, cache).start();
    5158                        }
    5259                }
     
    6067
    6168                log.info("done crawling");
     69
     70                for (Institution institution : centerRegistry.getCQLInstitutions()) {
     71                        Iterable<Endpoint> endpoints = institution.getEndpoints();
     72                        for (Endpoint endp : endpoints) {
     73                                log.info("inst/endpoint type: {} / {}", institution.getName(), endp.getProtocol());
     74                        }
     75                }
     76
    6277                return cache;
    6378        }
    6479
    65         public Statistics getStatistics() {
    66                 return statistics;
    67         }
    68 
    69         private void scanForCorpora(ScanTask st) {
    70                 if (st.depth > maxDepth) {
     80        class ExplainTask implements ThrottledClient.ExplainCallback {
     81
     82                final Institution institution;
     83                final Endpoint endpoint;
     84                final Corpora corpora;
     85
     86                ExplainTask(final Institution institution, final Endpoint endpoint, final Corpora corpora) {
     87                        this.institution = institution;
     88                        this.endpoint = endpoint;
     89                        this.corpora = corpora;
     90                }
     91
     92                void start() {
     93                        SRUExplainRequest explainRequest = null;
     94                        try {
     95                                explainRequest = new SRUExplainRequest(endpoint.getUrl());
     96                                explainRequest.setExtraRequestData(SRUCQL.EXPLAIN_ASK_FOR_RESOURCES_PARAM, "true");
     97                                explainRequest.setParseRecordDataEnabled(true);
     98                        } catch (Throwable ex) {
     99                                log.error("Exception creating explain request for {}: {}", endpoint.getUrl(), ex.getMessage());
     100                                log.error("--> ", ex);
     101                        }
     102                        if (explainRequest == null) {
     103                                return;
     104                        }
     105
     106                        log.info("{} Start explain: {}", latch.get(), endpoint.getUrl());
     107                        latch.increment();
     108                        sruClient.explain(explainRequest, this);
     109                }
     110
     111                @Override
     112                public void onSuccess(SRUExplainResponse response, ThrottledClient.Stats stats) {
     113                        try {
     114                                statistics.addEndpointDatapoint(institution, endpoint.getUrl(), stats.getQueueTime(), stats.getExecutionTime());
     115                                if (response != null && response.hasExtraResponseData()) {
     116                                        for (SRUExtraResponseData data : response.getExtraResponseData()) {
     117                                                if (data instanceof ClarinFCSEndpointDescription) {
     118                                                        endpoint.setProtocol(FCSProtocolVersion.VERSION_1);
     119                                                        ClarinFCSEndpointDescription desc = (ClarinFCSEndpointDescription) data;
     120                                                        addCorpora(corpora, institution, endpoint, desc.getResources(), null);
     121                                                }
     122                                        }
     123                                }
     124
     125                                if (response != null && response.hasDiagnostics()) {
     126                                        for (SRUDiagnostic d : response.getDiagnostics()) {
     127                                                SRUExplainRequest request = response.getRequest();
     128                                                Diagnostic diag = new Diagnostic(request.getBaseURI().toString(), null,
     129                                                                d.getURI(), d.getMessage(), d.getDetails());
     130                                                statistics.addEndpointDiagnostic(institution, endpoint.getUrl(), diag);
     131                                                log.info("Diagnostic: {} {}: {} {} {}", diag.getReqEndpointUrl(), diag.getReqContext(),
     132                                                                diag.getDgnUri(), diag.getDgnMessage(), diag.getDgnDiagnostic());
     133                                        }
     134                                }
     135
     136                                log.info("{} Finished explain, endpoint version is {}: {}", latch.get(), endpoint.getProtocol(), endpoint.getUrl());
     137                        } catch (Exception xc) {
     138                                log.error("{} Exception in explain callback {}", latch.get(), endpoint.getUrl());
     139                                log.error("--> ", xc);
     140                        } finally {
     141                                if (endpoint.getProtocol().equals(FCSProtocolVersion.LEGACY)) {
     142                                        new ScanTask(institution, endpoint, null, corpora, 0).start();
     143                                }
     144
     145                                latch.decrement();
     146                        }
     147                }
     148
     149                @Override
     150                public void onError(SRUExplainRequest request, SRUClientException error, ThrottledClient.Stats stats) {
     151                        try {
     152                                log.error("{} Error while explaining {}: {}", latch.get(), endpoint.getUrl(), error.getMessage());
     153                                statistics.addEndpointDatapoint(institution, endpoint.getUrl(), stats.getQueueTime(), stats.getExecutionTime());
     154                                statistics.addErrorDatapoint(institution, endpoint.getUrl(), error);
     155                                if (Throw.isCausedBy(error, SocketTimeoutException.class)) {
     156                                        return;
     157                                }
     158                                log.error("--> " + request.getBaseURI() + " --> ", error);
     159                        } finally {
     160                                latch.decrement();
     161                        }
     162                }
     163        }
     164
     165        private static void addCorpora(Corpora corpora, Institution institution, Endpoint endpoint,
     166                        List<ResourceInfo> resources, Corpus parentCorpus) {
     167                if (resources == null) {
    71168                        return;
    72169                }
    73 
    74                 SRUScanRequest scanRequest = null;
    75                 try {
    76                         scanRequest = new SRUScanRequest(st.endpointUrl);
    77                         scanRequest.setScanClause(SRUCQL.SCAN_RESOURCE_PARAMETER
    78                                         + "=" + normalizeHandle(st.parentCorpus));
    79                         scanRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER,
    80                                         SRUCQL.SCAN_RESOURCE_INFO_PARAMETER_DEFAULT_VALUE);
    81                 } catch (Throwable ex) {
    82                         log.error("Exception creating scan request for {}: {}", st.endpointUrl, ex.getMessage());
    83                         log.error("--> ", ex);
    84                 }
    85                 if (scanRequest == null) {
    86                         return;
    87                 }
    88 
    89                 log.info("{} Start scan: {}#{}", latch.get(), st.endpointUrl, normalizeHandle(st.parentCorpus));
    90                 latch.increment();
    91                 sruClient.scan(scanRequest, st);
     170                for (ResourceInfo ri : resources) {
     171                        Corpus c = new Corpus(institution, endpoint);
     172                        c.setHandle(ri.getPid());
     173                        c.setTitle(getBestValueFrom(ri.getTitle()));
     174                        c.setDescription(getBestValueFrom(ri.getTitle()));
     175                        c.setLanguages(new HashSet<String>(ri.getLanguages()));
     176                        c.setLandingPage(ri.getLandingPageURI());
     177
     178                        if (corpora.addCorpus(c, parentCorpus)) {
     179                                addCorpora(corpora, institution, endpoint, ri.getSubResources(), c);
     180                        }
     181                }
     182        }
     183
     184        private static String getBestValueFrom(Map<String, String> map) {
     185                String ret = map.get("en");
     186                if (ret == null || ret.trim().isEmpty()) {
     187                        ret = map.get(null);
     188                }
     189                if (ret == null || ret.trim().isEmpty()) {
     190                        ret = map.get("de");
     191                }
     192                if (ret == null || ret.trim().isEmpty()) {
     193                        ret = map.size() > 0
     194                                        ? map.values().iterator().next()
     195                                        : null;
     196                }
     197                return ret;
    92198        }
    93199
     
    95201
    96202                final Institution institution;
    97                 final String endpointUrl;
     203                final Endpoint endpoint;
    98204                final Corpus parentCorpus;
    99205                final Corpora corpora;
    100206                final int depth;
    101207
    102                 ScanTask(final Institution institution, final String endpointUrl,
     208                ScanTask(final Institution institution, final Endpoint endpoint,
    103209                                final Corpus parentCorpus, final Corpora corpora, final int depth) {
    104210                        this.institution = institution;
    105                         this.endpointUrl = endpointUrl;
     211                        this.endpoint = endpoint;
    106212                        this.parentCorpus = parentCorpus;
    107213                        this.corpora = corpora;
     
    109215                }
    110216
     217                private void start() {
     218                        if (depth > maxDepth) {
     219                                return;
     220                        }
     221
     222                        SRUScanRequest scanRequest = null;
     223                        try {
     224                                scanRequest = new SRUScanRequest(endpoint.getUrl());
     225                                scanRequest.setScanClause(SRUCQL.SCAN_RESOURCE_PARAMETER
     226                                                + "=" + normalizeHandle(parentCorpus));
     227                                scanRequest.setExtraRequestData(SRUCQL.SCAN_RESOURCE_INFO_PARAMETER,
     228                                                SRUCQL.SCAN_RESOURCE_INFO_PARAMETER_DEFAULT_VALUE);
     229                        } catch (Throwable ex) {
     230                                log.error("Exception creating scan request for {}: {}", endpoint.getUrl(), ex.getMessage());
     231                                log.error("--> ", ex);
     232                        }
     233                        if (scanRequest == null) {
     234                                return;
     235                        }
     236
     237                        log.info("{} Start scan: {}#{}", latch.get(), endpoint.getUrl(), normalizeHandle(parentCorpus));
     238                        latch.increment();
     239                        sruClient.scan(scanRequest, this);
     240                }
     241
    111242                @Override
    112243                public void onSuccess(SRUScanResponse response, ThrottledClient.Stats stats) {
    113244                        try {
    114                                 statistics.addEndpointDatapoint(institution, endpointUrl, stats.getQueueTime(), stats.getExecutionTime());
     245                                statistics.addEndpointDatapoint(institution, endpoint.getUrl(), stats.getQueueTime(), stats.getExecutionTime());
    115246                                if (response != null && response.hasTerms()) {
    116247                                        for (SRUTerm term : response.getTerms()) {
    117248                                                if (term == null) {
    118                                                         log.warn("null term for scan at endpoint {}", endpointUrl);
     249                                                        log.warn("null term for scan at endpoint {}", endpoint.getUrl());
    119250                                                } else {
    120                                                         Corpus c = createCorpus(institution, endpointUrl, term);
     251                                                        Corpus c = createCorpus(institution, endpoint, term);
    121252                                                        if (corpora.addCorpus(c, parentCorpus)) {
    122                                                                 ScanTask st = new ScanTask(institution, endpointUrl, c, corpora, depth + 1);
    123                                                                 scanForCorpora(st);
     253                                                                new ScanTask(institution, endpoint, c, corpora, depth + 1).start();
    124254                                                        }
    125255                                                }
    126256                                        }
    127257                                } else if (parentCorpus == null) {
    128                                         Corpus c = createCorpus(institution, endpointUrl, null);
     258                                        Corpus c = createCorpus(institution, endpoint, null);
    129259                                        if (corpora.addCorpus(c, parentCorpus)) {
    130                                                 ScanTask st = new ScanTask(institution, endpointUrl, c, corpora, depth + 1);
    131                                                 scanForCorpora(st);
     260                                                new ScanTask(institution, endpoint, c, corpora, depth + 1).start();
    132261                                        }
    133262                                }
     
    140269                                                Diagnostic diag = new Diagnostic(request.getBaseURI().toString(), handle,
    141270                                                                d.getURI(), d.getMessage(), d.getDetails());
    142                                                 statistics.addEndpointDiagnostic(institution, endpointUrl, diag);
     271                                                statistics.addEndpointDiagnostic(institution, endpoint.getUrl(), diag);
    143272                                                log.info("Diagnostic: {} {}: {} {} {}", diag.getReqEndpointUrl(), diag.getReqContext(),
    144273                                                                diag.getDgnUri(), diag.getDgnMessage(), diag.getDgnDiagnostic());
     
    146275                                }
    147276
    148                                 log.info("{} Finished scan: {}#{}", latch.get(), endpointUrl, normalizeHandle(parentCorpus));
     277                                log.info("{} Finished scan: {}#{}", latch.get(), endpoint.getUrl(), normalizeHandle(parentCorpus));
    149278                        } catch (Exception xc) {
    150                                 log.error("{} Exception in callback {}#{}", latch.get(), endpointUrl, normalizeHandle(parentCorpus));
     279                                log.error("{} Exception in scan callback {}#{}", latch.get(), endpoint.getUrl(), normalizeHandle(parentCorpus));
    151280                                log.error("--> ", xc);
    152281                        } finally {
     
    158287                public void onError(SRUScanRequest request, SRUClientException error, ThrottledClient.Stats stats) {
    159288                        try {
    160                                 log.error("{} Error while scanning {}#{}: {}", latch.get(), endpointUrl, normalizeHandle(parentCorpus), error.getMessage());
    161                                 statistics.addEndpointDatapoint(institution, endpointUrl, stats.getQueueTime(), stats.getExecutionTime());
    162                                 statistics.addErrorDatapoint(institution, endpointUrl, error);
     289                                log.error("{} Error while scanning {}#{}: {}", latch.get(), endpoint.getUrl(), normalizeHandle(parentCorpus), error.getMessage());
     290                                statistics.addEndpointDatapoint(institution, endpoint.getUrl(), stats.getQueueTime(), stats.getExecutionTime());
     291                                statistics.addErrorDatapoint(institution, endpoint.getUrl(), error);
    163292                                if (Throw.isCausedBy(error, SocketTimeoutException.class)) {
    164293                                        return;
     
    171300        }
    172301
     302        public Statistics getStatistics() {
     303                return statistics;
     304        }
     305
    173306        private static String normalizeHandle(Corpus corpus) {
    174307                if (corpus == null) {
     
    182315        }
    183316
    184         private static Corpus createCorpus(Institution institution, String endpointUrl, SRUTerm term) {
    185                 Corpus c = new Corpus(institution, endpointUrl);
    186                 c.setDisplayName(term.getDisplayTerm());
     317        private static Corpus createCorpus(Institution institution, Endpoint endpoint, SRUTerm term) {
     318                Corpus c = new Corpus(institution, endpoint);
     319                c.setTitle(term.getDisplayTerm());
    187320                String handle = term.getValue();
    188321                if (handle == null) {
    189                         log.error("null handle for corpus: {} : {}", endpointUrl, term.getDisplayTerm());
     322                        log.error("null handle for corpus: {} : {}", endpoint, term.getDisplayTerm());
    190323                        handle = "";
    191324                }
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/search/Exports.java

    r5897 r5957  
    286286            tc.createMatchesLayer("FCS", resultsProcessed.get(0).getSearchString());
    287287            for (Result result : resultsProcessed) {
    288                 MatchedCorpus mCorpus = tc.getMatchesLayer().addCorpus(result.getCorpus().getDisplayName(), result.getCorpus().getHandle());
     288                                MatchedCorpus mCorpus = tc.getMatchesLayer().addCorpus(result.getCorpus().getTitle(), result.getCorpus().getHandle());
    289289                for (Kwic kwic : result.getKwics()) {
    290290                    List<Token> tokens = new ArrayList<Token>();
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/search/Request.java

    r5900 r5957  
    3838                return searchString;
    3939        }
    40 
    41         public boolean hasCorpusHandle() {
    42                 return corpus != null && corpus.getHandle() != null;
    43         }
    4440}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/search/Search.java

    r5931 r5957  
    99import eu.clarin.sru.fcs.aggregator.client.ThrottledClient;
    1010import eu.clarin.sru.fcs.aggregator.scan.Corpus;
     11import eu.clarin.sru.fcs.aggregator.scan.FCSProtocolVersion;
    1112import eu.clarin.sru.fcs.aggregator.scan.Statistics;
    1213import eu.clarin.sru.fcs.aggregator.util.SRUCQL;
     
    3536
    3637        private final Long id;
     38        private final long createdAt = System.currentTimeMillis();
    3739        private final String searchLanguage;
    3840        private final List<Request> requests = Collections.synchronizedList(new ArrayList<Request>());
     
    5658                log.info("Executing search in '{}' query='{}' maxRecords='{}'", corpus, searchString, maxRecords);
    5759
    58                 SRUSearchRetrieveRequest searchRequest = new SRUSearchRetrieveRequest(corpus.getEndpointUrl());
     60                SRUSearchRetrieveRequest searchRequest = new SRUSearchRetrieveRequest(corpus.getEndpoint().getUrl());
    5961                searchRequest.setVersion(version);
    6062                searchRequest.setMaximumRecords(maxRecords);
    61                 searchRequest.setRecordSchema(ClarinFCSRecordData.RECORD_SCHEMA);
     63//              searchRequest.setRecordSchema(
     64//                              corpus.getEndpoint().getProtocol().equals(FCSProtocolVersion.LEGACY)
     65//                                              ? ClarinFCSRecordData.LEGACY_RECORD_SCHEMA
     66//                                              : ClarinFCSRecordData.RECORD_SCHEMA);
    6267                searchRequest.setQuery("\"" + searchString + "\"");
    6368                searchRequest.setStartRecord(startRecord);
    64                 if (request.hasCorpusHandle()) {
     69                if (corpus.getHandle() != null) {
    6570                        searchRequest.setExtraRequestData(SRUCQL.SEARCH_CORPUS_HANDLE_PARAMETER, corpus.getHandle());
    6671                }
     
    7176                                @Override
    7277                                public void onSuccess(SRUSearchRetrieveResponse response, ThrottledClient.Stats stats) {
    73                                         statistics.addEndpointDatapoint(corpus.getInstitution(), corpus.getEndpointUrl(), stats.getQueueTime(), stats.getExecutionTime());
     78                                        statistics.addEndpointDatapoint(corpus.getInstitution(), corpus.getEndpoint().getUrl(), stats.getQueueTime(), stats.getExecutionTime());
    7479                                        results.add(new Result(request, response, null));
    7580                                        requests.remove(request);
     
    7883                                @Override
    7984                                public void onError(SRUSearchRetrieveRequest srureq, SRUClientException xc, ThrottledClient.Stats stats) {
    80                                         statistics.addEndpointDatapoint(corpus.getInstitution(), corpus.getEndpointUrl(), stats.getQueueTime(), stats.getExecutionTime());
    81                                         statistics.addErrorDatapoint(corpus.getInstitution(), corpus.getEndpointUrl(), xc);
     85                                        statistics.addEndpointDatapoint(corpus.getInstitution(), corpus.getEndpoint().getUrl(), stats.getQueueTime(), stats.getExecutionTime());
     86                                        statistics.addErrorDatapoint(corpus.getInstitution(), corpus.getEndpoint().getUrl(), xc);
    8287                                        results.add(new Result(request, null, xc));
    8388                                        requests.remove(request);
     
    8590                        });
    8691                } catch (Throwable xc) {
    87                         log.error("SearchRetrieve error for " + corpus.getEndpointUrl(), xc);
     92                        log.error("SearchRetrieve error for " + corpus.getEndpoint().getUrl(), xc);
    8893                }
    8994                return request;
     
    204209                // nothing to do
    205210        }
     211
     212        public long getCreatedAt() {
     213                return createdAt;
     214        }
    206215}
  • SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/util/SRUCQL.java

    r5720 r5957  
    99
    1010        public static final String VERSION = "version";
     11
     12        public static final String EXPLAIN_ASK_FOR_RESOURCES_PARAM = "x-fcs-endpoint-description";
    1113
    1214        public static final String SEARCH_RETRIEVE = "searchRetrieve";
  • SRUAggregator/trunk/src/main/resources/assets/index.html

    r5954 r5957  
    22<html>
    33<head>
    4         <title>Aggregator2</title>
     4        <title>Aggregator - Federated Content Search</title>
    55        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    66        <meta name="viewport" content="width=device-width, initial-scale=1.0">
     7
    78        <link href="lib/bootstrap.min.css" rel="stylesheet">
    89        <link href="lib/font-awesome.min.css" rel="stylesheet">
    910        <link href="CLARIN.css" rel="stylesheet">
    1011        <link href="base.css" rel="stylesheet">
    11 </head>
    12 <body>
    13         <noscript>
    14                 <div>Federated Content Search Aggregator requires JavaScript to be enabled!</div>
    15         </noscript>
     12
     13        <!--[if lt IE 9]>
     14                <script src="http://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-shim.js"></script>
     15                <script src="http://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-sham.js"></script>
     16        <![endif]-->   
    1617
    1718        <style>
     
    2223                        height:100%;
    2324                }
    24                 #container {
     25                #main-container {
    2526                        min-height:100%;
    2627                        position:relative;
     
    3637                }
    3738        </style>
     39</head>
    3840
    39         <div id="container">
    40                 <div id="body">
    41                         <div id="reactMain">
    42                 </div>
    43                 <div id="footer">
    44                         <div class="container">
    45                                 <div id="CLARIN_footer_left">
    46                                                 <a title="about" id="aboutlink" href="about">
    47                                                 <span class="glyphicon glyphicon-info-sign"></span>
    48                                                 <span>VERSION 2.0.0.α14</span>
    49                                         </a>
    50                                 </div>
    51                                 <div id="CLARIN_footer_middle">
    52                                         <a title="CLARIN ERIC" href="https://www.clarin.eu/">
    53                                         <img src="img/clarindLogo.png" alt="CLARIN ERIC logo" style="height:80px"/>
    54                                         </a>
    55                                 </div>
    56                                 <div id="CLARIN_footer_right">
    57                                         <a title="contact" href="mailto:fcs@clarin.eu">
    58                                                 <span class="glyphicon glyphicon-envelope"></span>
    59                                                 <span> CONTACT</span>
    60                                         </a>
    61                                 </div>
    62                         </div>
    63                 </div>
     41<body>
     42        <noscript>
     43                <div>Federated Content Search Aggregator requires JavaScript to be enabled!</div>
     44        </noscript>
     45        <div id="main-container">
     46                <div id="body"></div>
     47                <div id="footer"></div>
    6448        </div>
    6549
    66         <!--[if lt IE 9]>
    67                 <script src="http://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-shim.js"></script>
    68                 <script src="http://cdnjs.cloudflare.com/ajax/libs/es5-shim/3.4.0/es5-sham.js"></script>
    69         <![endif]-->   
    7050        <script src="lib/jquery.min.js"></script>
    7151        <script src="lib/react-with-addons.js"></script>
  • SRUAggregator/trunk/src/main/resources/assets/js/corpora.js

    r5954 r5957  
    9696                var querytokens = query.split(" ").filter(function(x){ return x.length > 0; });
    9797                this.props.corpora.recurse(function(corpus){
    98                         var title = corpus.title ? corpus.title : corpus.displayName;
     98                        var title = corpus.title;
    9999                        querytokens.forEach(function(qtoken){
    100100                                if (title && title.toLowerCase().indexOf(qtoken) >= 0) {
     
    217217                var expansive = corpus.expanded ? {overflow:'hidden'}
    218218                        : {whiteSpace:'nowrap', overflow:'hidden', textOverflow: 'ellipsis'};
    219                 var title = corpus.title || corpus.displayName;
    220                 return  React.createElement("div", {className: corpusContainerClass, key: corpus.displayName},
     219                return  React.createElement("div", {className: corpusContainerClass, key: corpus.title},
    221220                                        React.createElement("div", {className: "row corpus", onClick: this.toggleExpansion.bind(this, corpus)},
    222221                                                React.createElement("div", {className: "col-sm-1 vcenter"},
     
    228227                                                        React.createElement("div", {style: indent},
    229228                                                                React.createElement("h3", {style: expansive},
    230                                                                         title,
     229                                                                        corpus.title,
    231230                                                                         corpus.landingPage ?
    232231                                                                                React.createElement("a", {href: corpus.landingPage, onClick: this.stop},
  • SRUAggregator/trunk/src/main/resources/assets/js/corpora.jsx

    r5954 r5957  
    9696                var querytokens = query.split(" ").filter(function(x){ return x.length > 0; });
    9797                this.props.corpora.recurse(function(corpus){
    98                         var title = corpus.title ? corpus.title : corpus.displayName;
     98                        var title = corpus.title;
    9999                        querytokens.forEach(function(qtoken){
    100100                                if (title && title.toLowerCase().indexOf(qtoken) >= 0) {
     
    217217                var expansive = corpus.expanded ? {overflow:'hidden'}
    218218                        : {whiteSpace:'nowrap', overflow:'hidden', textOverflow: 'ellipsis'};
    219                 var title = corpus.title || corpus.displayName;
    220                 return  <div className={corpusContainerClass} key={corpus.displayName}>
     219                return  <div className={corpusContainerClass} key={corpus.title}>
    221220                                        <div className="row corpus" onClick={this.toggleExpansion.bind(this, corpus)}>
    222221                                                <div className="col-sm-1 vcenter">
     
    228227                                                        <div style={indent}>
    229228                                                                <h3 style={expansive}>
    230                                                                         {title}
     229                                                                        {corpus.title}
    231230                                                                        { corpus.landingPage ?
    232231                                                                                <a href={corpus.landingPage} onClick={this.stop}>
  • SRUAggregator/trunk/src/main/resources/assets/js/main.js

    r5954 r5957  
    5454                        };
    5555                }
     56                // console.log("ajax", ajaxObject);
    5657                jQuery.ajax(ajaxObject);
    5758        },
     
    269270});
    270271
    271 React.render(React.createElement(Main, null), document.getElementById('reactMain') );
     272var Footer = React.createClass({displayName: 'Footer',
     273        render: function() {
     274                return  (
     275                        React.createElement("div", {className: "container"},
     276                                React.createElement("div", {id: "CLARIN_footer_left"},
     277                                                React.createElement("a", {title: "about", id: "aboutlink", href: "about"},
     278                                                React.createElement("span", {className: "glyphicon glyphicon-info-sign"}),
     279                                                React.createElement("span", null, "VERSION 2.0.0.α15")
     280                                        )
     281                                ),
     282                                React.createElement("div", {id: "CLARIN_footer_middle"},
     283                                        React.createElement("a", {title: "CLARIN ERIC", href: "https://www.clarin.eu/"},
     284                                        React.createElement("img", {src: "img/clarindLogo.png", alt: "CLARIN ERIC logo", style: {height:80}})
     285                                        )
     286                                ),
     287                                React.createElement("div", {id: "CLARIN_footer_right"},
     288                                        React.createElement("a", {title: "contact", href: "mailto:fcs@clarin.eu"},
     289                                                React.createElement("span", {className: "glyphicon glyphicon-envelope"}),
     290                                                React.createElement("span", null, " CONTACT")
     291                                        )
     292                                )
     293                        )
     294                );
     295        }
     296});
     297
     298React.render(React.createElement(Main, null),  document.getElementById('body'));
     299React.render(React.createElement(Footer, null), document.getElementById('footer') );
    272300
    273301})();
  • SRUAggregator/trunk/src/main/resources/assets/js/main.jsx

    r5954 r5957  
    5454                        };
    5555                }
     56                // console.log("ajax", ajaxObject);
    5657                jQuery.ajax(ajaxObject);
    5758        },
     
    269270});
    270271
    271 React.render(<Main />, document.getElementById('reactMain') );
     272var Footer = React.createClass({
     273        render: function() {
     274                return  (
     275                        <div className="container">
     276                                <div id="CLARIN_footer_left">
     277                                                <a title="about" id="aboutlink" href="about">
     278                                                <span className="glyphicon glyphicon-info-sign"></span>
     279                                                <span>VERSION 2.0.0.α15</span>
     280                                        </a>
     281                                </div>
     282                                <div id="CLARIN_footer_middle">
     283                                        <a title="CLARIN ERIC" href="https://www.clarin.eu/">
     284                                        <img src="img/clarindLogo.png" alt="CLARIN ERIC logo" style={{height:80}}/>
     285                                        </a>
     286                                </div>
     287                                <div id="CLARIN_footer_right">
     288                                        <a title="contact" href="mailto:fcs@clarin.eu">
     289                                                <span className="glyphicon glyphicon-envelope"></span>
     290                                                <span> CONTACT</span>
     291                                        </a>
     292                                </div>
     293                        </div>
     294                );
     295        }
     296});
     297
     298React.render(<Main />,  document.getElementById('body'));
     299React.render(<Footer />, document.getElementById('footer') );
    272300
    273301})();
  • SRUAggregator/trunk/src/main/resources/assets/js/search.js

    r5954 r5957  
    5252                        return r;
    5353                }
    54                 var t1 = x.title ? x.title : x.displayName;
    55                 var t2 = y.title ? y.title : y.displayName;
    56                 return t1.toLowerCase().localeCompare(t2.toLowerCase());
     54                return x.title.toLowerCase().localeCompare(y.title.toLowerCase());
    5755        };
    5856
     
    177175                        corpora: new Corpora([], this.updateCorpora),
    178176                        languageMap: {},
     177                        query: "",
    179178                        language: this.anyLanguage,
    180179                        languageFilter: 'byMeta',
     
    214213        },
    215214
    216         search: function(query) {
    217                 // console.log(query);
     215        search: function() {
     216                var query = this.state.query;
    218217                if (!query) {
    219218                        this.setState({ hits: this.nohits, searchId: null });
     
    253252                                        // console.log("new search in: " + this.timeout+ "ms");
    254253                                } else {
    255                                         // console.log("search ended");
     254                                        console.log("search ended; hits:", json);
    256255                                }
    257256                                this.setState({hits:json});
    258                                 // console.log("hits:", json);
    259257                        }.bind(this),
    260258                });
     
    316314        },
    317315
     316        handleChange: function(event) {
     317        this.setState({query: event.target.value});
     318        },
     319
     320        handleKey: function(event) {
     321        if (event.keyCode==13) {
     322                this.search();
     323        }
     324        },
     325
    318326        renderAggregator: function() {
    319327                var layer = layerMap[this.state.searchLayerId];
     
    327335                                                        ),
    328336
    329                                                         React.createElement(SearchBox, {search: this.search, placeholder: layer.searchPlaceholder}),
     337                                                        React.createElement("input", {className: "form-control input-lg search", name: "query", type: "text",
     338                                                                value: this.state.query, placeholder: this.props.placeholder,
     339                                                                tabIndex: "1", onChange: this.handleChange, onKeyDown: this.handleKey}),
    330340                                                        React.createElement("div", {className: "input-group-btn"},
    331341                                                                React.createElement("button", {className: "btn btn-default input-lg", type: "button", onClick: this.search},
     
    496506        }
    497507});
    498 /////////////////////////////////
    499 
    500 var SearchBox = React.createClass({displayName: 'SearchBox',
    501         propTypes: {
    502                 search: PT.func.isRequired,
    503                 placeholder: PT.string.isRequired,
    504         },
    505 
    506         getInitialState: function () {
    507                 return {
    508                         query: "",
    509                 };
    510         },
    511 
    512         handleChange: function(event) {
    513         this.setState({query: event.target.value});
    514         },
    515 
    516         handleKey: function(event) {
    517         if (event.keyCode==13) {
    518                 this.search();
    519         }
    520         },
    521 
    522         search: function() {
    523                 this.props.search(this.state.query);
    524         },
    525 
    526         render: function() {
    527                 return  React.createElement("input", {className: "form-control input-lg search",
    528                                         name: "query",
    529                                         type: "text",
    530                                         value: this.state.query,
    531                                         placeholder: this.props.placeholder,
    532                                         tabIndex: "1",
    533                                         onChange: this.handleChange,
    534                                         onKeyDown: this.handleKey})  ;
    535         }
    536 });
    537508
    538509/////////////////////////////////
     
    584555                var inline = {display:"inline-block"};
    585556                return  React.createElement("div", {style: inline},
    586                                         React.createElement("span", {className: "corpusName"}, " ", corpus.title ? corpus.title : corpus.displayName),
     557                                        React.createElement("span", {className: "corpusName"}, " ", corpus.title),
    587558                                        React.createElement("span", {className: "institutionName"}, " — ", corpus.institution.name)
    588559                                );
     
    592563                var inline = {display:"inline-block"};
    593564                return  React.createElement("div", null,
    594                                         React.createElement(InfoPopover, {placement: "left",
    595                                                         title: corpus.title ? corpus.title : corpus.displayName},
     565                                        React.createElement(InfoPopover, {placement: "left", title: corpus.title},
    596566                                                React.createElement("dl", {className: "dl-horizontal"},
    597567                                                        React.createElement("dt", null, "Institution"),
     
    625595
    626596                return corpusHit.diagnostics.map(function(d) {
    627                         return  React.createElement("div", {className: "alert alert-danger", role: "alert"},
     597                        return  React.createElement("div", {className: "alert alert-danger", role: "alert", key: d.dgnUri},
    628598                                                d.dgnMessage, ": ", d.dgnDiagnostic
    629599                                        );
     
    653623                        return false;
    654624                }
    655                 return  React.createElement(Panel, {key: corpusHit.corpus.displayName,
     625                return  React.createElement(Panel, {key: corpusHit.corpus.title,
    656626                                                title: this.renderPanelTitle(corpusHit.corpus),
    657627                                                info: this.renderPanelInfo(corpusHit.corpus)},
  • SRUAggregator/trunk/src/main/resources/assets/js/search.jsx

    r5954 r5957  
    5252                        return r;
    5353                }
    54                 var t1 = x.title ? x.title : x.displayName;
    55                 var t2 = y.title ? y.title : y.displayName;
    56                 return t1.toLowerCase().localeCompare(t2.toLowerCase());
     54                return x.title.toLowerCase().localeCompare(y.title.toLowerCase());
    5755        };
    5856
     
    177175                        corpora: new Corpora([], this.updateCorpora),
    178176                        languageMap: {},
     177                        query: "",
    179178                        language: this.anyLanguage,
    180179                        languageFilter: 'byMeta',
     
    214213        },
    215214
    216         search: function(query) {
    217                 // console.log(query);
     215        search: function() {
     216                var query = this.state.query;
    218217                if (!query) {
    219218                        this.setState({ hits: this.nohits, searchId: null });
     
    253252                                        // console.log("new search in: " + this.timeout+ "ms");
    254253                                } else {
    255                                         // console.log("search ended");
     254                                        console.log("search ended; hits:", json);
    256255                                }
    257256                                this.setState({hits:json});
    258                                 // console.log("hits:", json);
    259257                        }.bind(this),
    260258                });
     
    316314        },
    317315
     316        handleChange: function(event) {
     317        this.setState({query: event.target.value});
     318        },
     319
     320        handleKey: function(event) {
     321        if (event.keyCode==13) {
     322                this.search();
     323        }
     324        },
     325
    318326        renderAggregator: function() {
    319327                var layer = layerMap[this.state.searchLayerId];
     
    327335                                                        </span>
    328336
    329                                                         <SearchBox search={this.search} placeholder={layer.searchPlaceholder} />
     337                                                        <input className="form-control input-lg search" name="query" type="text"
     338                                                                value={this.state.query} placeholder={this.props.placeholder}
     339                                                                tabIndex="1" onChange={this.handleChange} onKeyDown={this.handleKey} />
    330340                                                        <div className="input-group-btn">
    331341                                                                <button className="btn btn-default input-lg" type="button" onClick={this.search}>
     
    496506        }
    497507});
    498 /////////////////////////////////
    499 
    500 var SearchBox = React.createClass({
    501         propTypes: {
    502                 search: PT.func.isRequired,
    503                 placeholder: PT.string.isRequired,
    504         },
    505 
    506         getInitialState: function () {
    507                 return {
    508                         query: "",
    509                 };
    510         },
    511 
    512         handleChange: function(event) {
    513         this.setState({query: event.target.value});
    514         },
    515 
    516         handleKey: function(event) {
    517         if (event.keyCode==13) {
    518                 this.search();
    519         }
    520         },
    521 
    522         search: function() {
    523                 this.props.search(this.state.query);
    524         },
    525 
    526         render: function() {
    527                 return  <input className="form-control input-lg search"
    528                                         name="query"
    529                                         type="text"
    530                                         value={this.state.query}
    531                                         placeholder={this.props.placeholder}
    532                                         tabIndex="1"
    533                                         onChange={this.handleChange}
    534                                         onKeyDown={this.handleKey} />  ;
    535         }
    536 });
    537508
    538509/////////////////////////////////
     
    584555                var inline = {display:"inline-block"};
    585556                return  <div style={inline}>
    586                                         <span className="corpusName"> {corpus.title ? corpus.title : corpus.displayName}</span>
     557                                        <span className="corpusName"> {corpus.title}</span>
    587558                                        <span className="institutionName"> — {corpus.institution.name}</span>
    588559                                </div>;
     
    592563                var inline = {display:"inline-block"};
    593564                return  <div>
    594                                         <InfoPopover placement="left"
    595                                                         title={corpus.title ? corpus.title : corpus.displayName}>
     565                                        <InfoPopover placement="left" title={corpus.title}>
    596566                                                <dl className="dl-horizontal">
    597567                                                        <dt>Institution</dt>
     
    625595
    626596                return corpusHit.diagnostics.map(function(d) {
    627                         return  <div className="alert alert-danger" role="alert">
     597                        return  <div className="alert alert-danger" role="alert" key={d.dgnUri}>
    628598                                                {d.dgnMessage}{": "}{d.dgnDiagnostic}
    629599                                        </div>;
     
    653623                        return false;
    654624                }
    655                 return  <Panel key={corpusHit.corpus.displayName}
     625                return  <Panel key={corpusHit.corpus.title}
    656626                                                title={this.renderPanelTitle(corpusHit.corpus)}
    657627                                                info={this.renderPanelInfo(corpusHit.corpus)}>
  • SRUAggregator/trunk/src/test/java/eu/clarin/sru/fcs/aggregator/app/CQLEnumerationTest.java

    r5893 r5957  
    33import eu.clarin.sru.fcs.aggregator.scan.CenterRegistry;
    44import eu.clarin.sru.fcs.aggregator.scan.CenterRegistryLive;
     5import eu.clarin.sru.fcs.aggregator.scan.Endpoint;
    56import eu.clarin.sru.fcs.aggregator.scan.Institution;
    67import javax.naming.NamingException;
     
    2425                        for (Institution institution : centerRegistry.getCQLInstitutions()) {
    2526                                System.out.println(institution.getName() + ": ");
    26                                 for (String e : institution.getEndpoints()) {
     27                                for (Endpoint e : institution.getEndpoints()) {
    2728                                        System.out.println("\t -> " + e);
    2829                                }
  • SRUAggregator/trunk/src/test/java/eu/clarin/sru/fcs/aggregator/app/ScanCrawlerTest.java

    r5901 r5957  
    3030                                new ClarinFCSClientBuilder()
    3131                                .addDefaultDataViewParsers()
    32                                 .buildThreadedClient(), 2, 2);
     32                                .buildThreadedClient(), 2);
    3333
    3434                try {
     
    5353                        Assert.assertTrue("Description problem", tueRootCorpus.getDescription().contains(tueDescSubstring));
    5454                        String tueNameSubstring = "TuebaDDC";
    55                         Assert.assertTrue("Name problem", tueRootCorpus.getDisplayName().contains(tueNameSubstring));
     55                        Assert.assertTrue("Name problem", tueRootCorpus.getTitle().contains(tueNameSubstring));
    5656                        String tuePageSubstring = "sfs.uni-tuebingen.de";
    5757                        Assert.assertTrue("Landing page problem", tueRootCorpus.getLandingPage().contains(tuePageSubstring));
Note: See TracChangeset for help on using the changeset viewer.