Changeset 6123 for SRUAggregator
- Timestamp:
- 04/01/15 13:04:47 (9 years ago)
- Location:
- SRUAggregator/trunk
- Files:
-
- 9 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
SRUAggregator/trunk/pom.xml
r6111 r6123 8 8 <groupId>eu.clarin.sru.fcs</groupId> 9 9 <artifactId>Aggregator2</artifactId> 10 <version>2.0.0-beta-3 0</version>10 <version>2.0.0-beta-31</version> 11 11 <name>FCS Aggregator</name> 12 12 -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/Aggregator.java
r6093 r6123 34 34 import java.util.concurrent.ScheduledExecutorService; 35 35 import java.util.concurrent.atomic.AtomicReference; 36 import org.eclipse.jetty.server.session.SessionHandler; 36 37 import org.slf4j.LoggerFactory; 37 38 … … 48 49 * If invoked with 'x-aggregation-context' and 'query' parameter, the aggregator 49 50 * will pre-select provided resources and fill in the query field. This 50 * mechanism is currently used by VLO. Example: POST 51 * http://weblicht.sfs.uni-tuebingen.de/Aggregator HTTP/1.1 operation = 52 * searchRetrieve & version = 1.2 & query = bellen & x-aggregation-context = 51 * mechanism is currently used by VLO. 52 * 53 * Example: POST 54 * http://weblicht.sfs.uni-tuebingen.de/Aggregator HTTP/1.1 55 * query = bellen & x-aggregation-context = 53 56 * {"http://fedora.clarin-d.uni-saarland.de/sru/":["hdl:11858/00-246C-0000-0008-5F2A-0"]} 54 57 * 55 * 56 * Additionally, if run with the a URL query string parameter 'mode', the 57 * special behavior of the aggregator is triggered: 58 * 59 * /?mode=testing corresponds to the mode where the CQL endpoints are taken not 60 * from Clarin center repository, but from a hard-coded endpoints list; this 61 * functionality is useful for testing the development instances of endpoints, 62 * before they are moved to production. Was done to meet the request from MPI. 63 * 64 * /?mode=search corresponds to the mode where the aggregator page is requested 65 * with the already known query and (optionally) resources to search in, and if 66 * the immediate search is desired. In this case the aggregator search results 67 * page is displayed and search results of the provided query start to fill it 68 * in immediately (i.e. users don't need to click 'search' in the aggregator 69 * page). Was done to meet the request from CLARIN ERIC (Martin Wynne contacted 70 * us). 71 * 72 * /?mode=live corresponds to the mode where the information about corpora are 73 * taken not from the scan cache (crawled in advance), but loaded live, starting 74 * from the request to center registry and then performing scan operation 75 * requests on each CQL endpoint listed there. It takes time to get the 76 * corresponding responses from the endpoints, therefore the Aggregator page 77 * loads very slow in this mode. But this mode is useful for testing of the 78 * newly added or changed corpora without waiting for the next crawl. 79 * 80 * 81 * Adds Application initialization and clean up: only one SRU threaded client is 82 * used in the application, it has to be shut down when the application stops. 83 * One Languages object instance is used within the application. 58 * If the Aggregator web page has the URL query string parameter 'mode' 59 * set to the string 'search', and the 'query' parameter is set, 60 * then the aggregator search results for this query are immediately displayed 61 * (i.e. users don't need to click 'search' in the aggregator page). 62 * This feature has been requested initially by Martin Wynne from CLARIN ERIC 84 63 * 85 64 * @author Yana Panchenko 86 65 * @author edima 87 66 * 88 * TODO: add the modes described above (except live)67 * TODO: improve help page text 89 68 * 90 69 * TODO: update comments everywhere … … 103 82 * 104 83 * TODO: tri-state for parent collections; search + message implications 105 *106 * TODO: improve help page text107 84 * 108 85 */ … … 161 138 } 162 139 163 environment.getApplicationContext().setErrorHandler(new ErrorPageHandler()); 140 environment.getApplicationContext().setSessionHandler(new SessionHandler()); 141 environment.getApplicationContext().setErrorHandler(new ErrorHandler()); 164 142 environment.jersey().setUrlPattern("/rest/*"); 165 143 environment.jersey().register(new RestService()); -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/app/ErrorHandler.java
r6044 r6123 1 1 package eu.clarin.sru.fcs.aggregator.app; 2 2 3 import java.util.ArrayList; 4 import java.util.List; 3 import com.fasterxml.jackson.databind.ObjectMapper; 4 import java.io.IOException; 5 import javax.servlet.RequestDispatcher; 6 import javax.servlet.ServletException; 5 7 import javax.servlet.http.HttpServletRequest; 6 import javax.ws.rs.ext.Provider; 7 import org.eclipse.jetty.servlet.ErrorPageErrorHandler; 8 import javax.servlet.http.HttpServletResponse; 9 import org.eclipse.jetty.http.HttpMethod; 10 import org.eclipse.jetty.server.Request; 11 import org.slf4j.LoggerFactory; 8 12 9 13 /** … … 11 15 * @author edima 12 16 */ 13 @Provider 14 public class ErrorPageHandler extends ErrorPageErrorHandler { 17 public class ErrorHandler extends org.eclipse.jetty.server.handler.ErrorHandler { 15 18 16 List<String> staticRoutes;19 private static final org.slf4j.Logger log = LoggerFactory.getLogger(Aggregator.class); 17 20 18 public ErrorPageHandler() { 19 staticRoutes = new ArrayList<String>(); 20 staticRoutes.add("/rest"); 21 staticRoutes.add("/admin"); 22 staticRoutes.add("/lib"); 23 staticRoutes.add("/js"); 24 staticRoutes.add("/fonts"); 25 staticRoutes.add("/img"); 21 private final String redirectRoute = "/index.html"; 22 23 @Override 24 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException { 25 // On 404 page we need to show index.html and let JS router do the work, otherwise show error page 26 if (response.getStatus() == HttpServletResponse.SC_NOT_FOUND) { 27 forward(redirectRoute, baseRequest, response); 28 } else if (request.getMethod().equals("POST") 29 && response.getStatus() == HttpServletResponse.SC_METHOD_NOT_ALLOWED 30 && request.getParameterValues("x-aggregation-context") != null) { 31 32 // this request must come from VLO 33 String[] queryValues = request.getParameterValues("query"); 34 if (queryValues != null && queryValues.length > 0) { 35 baseRequest.getSession().setAttribute("query", queryValues[0]); 36 } 37 38 String[] contextValues = request.getParameterValues("x-aggregation-context"); 39 if (contextValues != null && contextValues.length > 0) { 40 baseRequest.getSession().setAttribute("x-aggregation-context", contextValues[0]); 41 } 42 43 baseRequest.setMethod(HttpMethod.GET, HttpMethod.GET.asString()); 44 45 forward(redirectRoute, baseRequest, response); 46 } else { 47 super.handle(target, baseRequest, request, response); 48 } 26 49 } 27 50 28 static boolean prefix(String url, String prefix) { 29 return url.equals(prefix) || url.startsWith(prefix + "/") || url.startsWith(prefix + "?"); 30 } 31 32 @Override 33 public String getErrorPage(HttpServletRequest request) { 34 String url = request.getPathInfo(); 35 for (String pre : staticRoutes) { 36 if (prefix(url, pre)) { 37 return null; 51 void forward(String target, Request request, HttpServletResponse response) throws IOException { 52 RequestDispatcher dispatcher = request.getRequestDispatcher(target); 53 if (dispatcher != null) { 54 try { 55 response.reset(); 56 dispatcher.forward(request, response); 57 } catch (ServletException e) { 58 super.handle(target, request, request, response); 38 59 } 60 } else { 61 log.error("Can not find internal redirect route '" + target + "' while handling error. Will show system error page"); 62 super.handle(target, request, request, response); 39 63 } 40 return "/index.html";41 64 } 42 65 } -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/rest/RestService.java
r6092 r6123 81 81 @GET 82 82 @Path("init") 83 public Response getInit( ) throws IOException {83 public Response getInit(@Context HttpServletRequest request) throws IOException { 84 84 log.info("get initial data"); 85 85 final Corpora corpora = Aggregator.getInstance().getCorpora(); 86 final Object contextString = request.getSession().getAttribute("x-aggregation-context"); 87 final Object query = request.getSession().getAttribute("query"); 88 final Object mode = request.getSession().getAttribute("mode"); 86 89 Object j = new HashMap<String, Object>() { 87 90 { 91 if (query != null) { 92 put("query", query); 93 } 94 if (contextString instanceof String) { 95 Object context = new ObjectMapper().readValue((String) contextString, Object.class); 96 put("x-aggregation-context", context); // preselected corpora 97 } 88 98 put("corpora", corpora.getCorpora()); 89 99 put("languages", LanguagesISO693.getInstance().getLanguageMap(corpora.getLanguages())); -
SRUAggregator/trunk/src/main/java/eu/clarin/sru/fcs/aggregator/search/Exports.java
r6081 r6123 168 168 return null; 169 169 } else { 170 WLData data;171 MetaData md = new MetaData();172 170 String lang = LanguagesISO693.getInstance().code_1ForCode_3(searchLanguage); 173 171 if (filterLanguage != null) { … … 176 174 TextCorpusStored tc = new TextCorpusStored(lang); 177 175 tc.createTextLayer().addText(text); 178 data = new WLData(md, tc);176 WLData data = new WLData(new MetaData(), tc); 179 177 ByteArrayOutputStream os = new ByteArrayOutputStream(); 180 178 try { -
SRUAggregator/trunk/src/main/resources/assets/index.html
r6081 r6123 46 46 <div id="main-container"> 47 47 <div id="body"></div> 48 <!-- <div> 49 <form id="contentSearchForm" method="post" name="fcsForm" target="_blank" action="http://localhost:4019/Aggregator-testing/"> 50 <fieldset style="border:0px;"> 51 <input type="hidden" name="query" id="query" value=""> 52 <input type="hidden" name="x-aggregation-context" value="{"http://cqlservlet.mpi.nl/": ["tla.mpi.nl:collections:childes"]}"> 53 <input type="hidden" name="operation" value="searchRetrieve"> 54 <input type="hidden" name="version" value="1.2"> 55 </fieldset> 56 </form> 57 <a href="#" onclick="document.fcsForm.submit();">Plain text search via Federated Content Search</a> 58 </div> --> 48 59 <div id="footer"></div> 49 60 </div> -
SRUAggregator/trunk/src/main/resources/assets/js/main.js
r6111 r6123 3 3 "use strict"; 4 4 5 var VERSION = window.MyAggregator.VERSION = "VERSION 2.0.0-beta-3 0";5 var VERSION = window.MyAggregator.VERSION = "VERSION 2.0.0-beta-31"; 6 6 var URLROOT = window.MyAggregator.URLROOT = "/Aggregator-testing"; 7 7 … … 13 13 var Main = React.createClass({displayName: 'Main', 14 14 componentWillMount: function() { 15 routeFromLocation.bind(this) ;15 routeFromLocation.bind(this)(); 16 16 }, 17 17 … … 111 111 }, 112 112 113 toAggregator: function(doPushHistory ) { this.gotoPage(doPushHistory, ''); },113 toAggregator: function(doPushHistory, query) { this.gotoPage(doPushHistory, ''); }, 114 114 toHelp: function(doPushHistory) { this.gotoPage(doPushHistory, 'help'); }, 115 115 toAbout: function(doPushHistory) { this.gotoPage(doPushHistory, 'about'); }, … … 557 557 window.onpopstate = routeFromLocation.bind(main); 558 558 559 routeFromLocation.bind(main)();559 // routeFromLocation.bind(main)(); 560 560 561 561 })(); 562 563 564 565 566 567 568 -
SRUAggregator/trunk/src/main/resources/assets/js/main.jsx
r6111 r6123 3 3 "use strict"; 4 4 5 var VERSION = window.MyAggregator.VERSION = "VERSION 2.0.0-beta-3 0";5 var VERSION = window.MyAggregator.VERSION = "VERSION 2.0.0-beta-31"; 6 6 var URLROOT = window.MyAggregator.URLROOT = "/Aggregator-testing"; 7 7 … … 13 13 var Main = React.createClass({ 14 14 componentWillMount: function() { 15 routeFromLocation.bind(this) ;15 routeFromLocation.bind(this)(); 16 16 }, 17 17 … … 557 557 window.onpopstate = routeFromLocation.bind(main); 558 558 559 routeFromLocation.bind(main)();560 561 559 })(); 562 563 564 565 566 567 568 -
SRUAggregator/trunk/src/main/resources/assets/js/search.js
r6111 r6123 44 44 sampa: layers[1], 45 45 }; 46 47 function getQueryVariable(variable) { 48 var query = window.location.search.substring(1); 49 var vars = query.split('&'); 50 for (var i = 0; i < vars.length; i++) { 51 var pair = vars[i].split('='); 52 if (decodeURIComponent(pair[0]) == variable) { 53 return decodeURIComponent(pair[1]); 54 } 55 } 56 return null; 57 } 46 58 47 59 function Corpora(corpora, updateFn) { … … 139 151 }; 140 152 153 Corpora.prototype.setAggregationContext = function(endpoints2handles) { 154 console.log('setAggregationContext', endpoints2handles, this.corpora); 155 156 var recurseSelect = function(select, corpus) { 157 corpus.selected = false; 158 this.recurseCorpora(corpus.subCorpora, function(c) { c.selected = corpus.selected; }); 159 }; 160 161 this.corpora.forEach(recurseSelect.bind(this, false)); 162 163 var corporaToSelect = []; 164 _.pairs(endpoints2handles).forEach(function(endp){ 165 var endpoint = endp[0]; 166 var handles = endp[1]; 167 handles.forEach(function(handle){ 168 this.recurse(function(corpus){ 169 if (corpus.handle === handle) { 170 corporaToSelect.push(corpus); 171 } 172 }.bind(this)); 173 }.bind(this)); 174 }.bind(this)); 175 176 corporaToSelect.forEach(recurseSelect.bind(this, true)); 177 }; 178 141 179 Corpora.prototype.getSelectedIds = function() { 142 180 var ids = []; … … 189 227 languageMap: {}, 190 228 weblichtLanguages: [], 191 query: "",229 query: getQueryVariable('query') || '', 192 230 language: this.anyLanguage, 193 231 languageFilter: 'byMeta', … … 208 246 success: function(json, textStatus, jqXHR) { 209 247 if (this.isMounted()) { 248 var corpora = new Corpora(json.corpora, this.updateCorpora); 210 249 this.setState({ 211 corpora : new Corpora(json.corpora, this.updateCorpora),250 corpora : corpora, 212 251 languageMap: json.languages, 213 252 weblichtLanguages: json.weblichtLanguages, 253 query: this.state.query || json.query || '', 214 254 }); 255 256 if (json['x-aggregation-context']) { 257 console.log("x-aggregation-context: ", json["x-aggregation-context"]); 258 corpora.setAggregationContext(json["x-aggregation-context"]); 259 corpora.update(); 260 } 261 262 if (getQueryVariable('mode') === 'search' || 263 json.mode === 'search') { 264 this.search(); 265 } 215 266 } 216 267 }.bind(this), … … 433 484 if (this.props.embedded) { 434 485 var query = this.state.query; 435 var newurl = query ? (window.MyAggregator.URLROOT + "?search=" + query) : "#"; 486 var newurl = !query ? "#" : 487 (window.MyAggregator.URLROOT + "?" + encodeQueryData({query:query, mode:'search'})); 436 488 return ( 437 489 React.createElement("a", {className: "btn btn-default input-lg", type: "button", target: "_blank", href: newurl}, -
SRUAggregator/trunk/src/main/resources/assets/js/search.jsx
r6111 r6123 44 44 sampa: layers[1], 45 45 }; 46 47 function getQueryVariable(variable) { 48 var query = window.location.search.substring(1); 49 var vars = query.split('&'); 50 for (var i = 0; i < vars.length; i++) { 51 var pair = vars[i].split('='); 52 if (decodeURIComponent(pair[0]) == variable) { 53 return decodeURIComponent(pair[1]); 54 } 55 } 56 return null; 57 } 46 58 47 59 function Corpora(corpora, updateFn) { … … 139 151 }; 140 152 153 Corpora.prototype.setAggregationContext = function(endpoints2handles) { 154 console.log('setAggregationContext', endpoints2handles, this.corpora); 155 156 var recurseSelect = function(select, corpus) { 157 corpus.selected = false; 158 this.recurseCorpora(corpus.subCorpora, function(c) { c.selected = corpus.selected; }); 159 }; 160 161 this.corpora.forEach(recurseSelect.bind(this, false)); 162 163 var corporaToSelect = []; 164 _.pairs(endpoints2handles).forEach(function(endp){ 165 var endpoint = endp[0]; 166 var handles = endp[1]; 167 handles.forEach(function(handle){ 168 this.recurse(function(corpus){ 169 if (corpus.handle === handle) { 170 corporaToSelect.push(corpus); 171 } 172 }.bind(this)); 173 }.bind(this)); 174 }.bind(this)); 175 176 corporaToSelect.forEach(recurseSelect.bind(this, true)); 177 }; 178 141 179 Corpora.prototype.getSelectedIds = function() { 142 180 var ids = []; … … 189 227 languageMap: {}, 190 228 weblichtLanguages: [], 191 query: "",229 query: getQueryVariable('query') || '', 192 230 language: this.anyLanguage, 193 231 languageFilter: 'byMeta', … … 208 246 success: function(json, textStatus, jqXHR) { 209 247 if (this.isMounted()) { 248 var corpora = new Corpora(json.corpora, this.updateCorpora); 210 249 this.setState({ 211 corpora : new Corpora(json.corpora, this.updateCorpora),250 corpora : corpora, 212 251 languageMap: json.languages, 213 252 weblichtLanguages: json.weblichtLanguages, 253 query: this.state.query || json.query || '', 214 254 }); 255 256 if (json['x-aggregation-context']) { 257 console.log("x-aggregation-context: ", json["x-aggregation-context"]); 258 corpora.setAggregationContext(json["x-aggregation-context"]); 259 corpora.update(); 260 } 261 262 if (getQueryVariable('mode') === 'search' || 263 json.mode === 'search') { 264 this.search(); 265 } 215 266 } 216 267 }.bind(this), … … 433 484 if (this.props.embedded) { 434 485 var query = this.state.query; 435 var newurl = query ? (window.MyAggregator.URLROOT + "?search=" + query) : "#"; 486 var newurl = !query ? "#" : 487 (window.MyAggregator.URLROOT + "?" + encodeQueryData({query:query, mode:'search'})); 436 488 return ( 437 489 <a className="btn btn-default input-lg" type="button" target="_blank" href={newurl}>
Note: See TracChangeset
for help on using the changeset viewer.