/** * Generate the unique caching key. This key must be unique inside the space of this component. */ public Serializable getKey() { try { Request request = ObjectModelHelper.getRequest(objectModel); String key = request.getScheme() + request.getServerName() + request.getServerPort() + request.getSitemapURI() + request.getQueryString(); DSpaceObject dso = HandleUtil.obtainHandle(objectModel); if (dso != null) { key += "-" + dso.getHandle(); } return HashUtil.hash(key); } catch (SQLException sqle) { // Ignore all errors and just return that the component is not cachable. return "0"; } }
public void doAdvancedSearch(AppleResponse res, AppleRequest req) { // Get all parameteres from the HTML form as Map Map<String, String[]> parameterMap = new TreeMap<String, String[]>(createParametersMap(req.getCocoonRequest())); Map<String, Object> bizData = new HashMap<String, Object>(); boolean abovemaxnumberofhits = false; StringBuilder messageBuffer = new StringBuilder(); messageBuffer.append( "<c:messages xmlns:i18n=\"http://apache.org/cocoon/i18n/2.1\" xmlns:c=\"http://xmlns.computas.com/cocoon\">\n"); // Boolean that can be set to false if we don't want the actual search to be performed. // Typically when the search string is empty. boolean doSearch = true; // Temporary to override the sparql query upopn freetext search boolean freetext = false; String searchStringOverriden = null; boolean doBigSearchAnyway = (parameterMap.get("dobigsearchanyway") != null); parameterMap.remove("dobigsearchanyway"); // Create an XML structure of the search criterias. This could probably be nore generic. StringBuilder xmlSearchParametersBuffer = new StringBuilder(); xmlSearchParametersBuffer.append( "<c:searchparams xmlns:c=\"http://xmlns.computas.com/cocoon\">\n"); if (req.getCocoonRequest().getParameter("searchstring") == null) { xmlSearchParametersBuffer.append("\t<c:searchstring></c:searchstring>\n"); } else { String searchstring = req.getCocoonRequest().getParameter("searchstring"); searchstring = searchstring.replace("&", "&"); searchstring = searchstring.replace("<", "<"); searchstring = searchstring.replace(">", ">"); xmlSearchParametersBuffer.append("\t<c:searchstring>" + searchstring + "</c:searchstring>\n"); } xmlSearchParametersBuffer.append( "\t<c:operator>" + req.getCocoonRequest().getParameter("booleanoperator") + "</c:operator>\n"); xmlSearchParametersBuffer.append( "\t<c:deepsearch>" + req.getCocoonRequest().getParameter("deepsearch") + "</c:deepsearch>\n"); xmlSearchParametersBuffer.append( "\t<c:sortby>" + req.getCocoonRequest().getParameter("sort") + "</c:sortby>\n"); xmlSearchParametersBuffer.append( "\t<c:exactmatch>" + req.getCocoonRequest().getParameter("exactmatch") + "</c:exactmatch>\n"); xmlSearchParametersBuffer.append("</c:searchparams>\n"); if ("resource".equalsIgnoreCase(mode)) { parameterMap.put( "prefix", new String[] { "dct: <http://purl.org/dc/terms/>", "rdfs: <http://www.w3.org/2000/01/rdf-schema#>", "skos: <http://www.w3.org/2004/02/skos/core#>" }); parameterMap.put( "interface-language", new String[] {req.getSitemapParameter("interface-language")}); parameterMap.put( "dct:identifier", new String[] { getProperty("sublima.base.url") + "resource/" + req.getSitemapParameter("name") }); parameterMap.put("dct:subject/skos:prefLabel", new String[] {""}); } if (parameterMap.get("searchstring") != null) { if (req.getCocoonRequest().getParameter("searchstring").trim().equalsIgnoreCase("")) { doSearch = false; } else { // When true, we override the searchstring later in the code freetext = true; searchStringOverriden = freeTextSearchString( req.getCocoonRequest().getParameter("searchstring"), req.getCocoonRequest().getParameter("booleanoperator"), (req.getCocoonRequest().getParameter("exactmatch") != null), false); parameterMap.put("searchstring", new String[] {searchStringOverriden}); parameterMap.remove("booleanoperator"); parameterMap.remove("sort"); parameterMap.remove("sortorder"); parameterMap.remove("exactmatch"); } } // sending the result String sparqlQuery = null; String countNumberOfHitsQuery = null; String moreThanZeroHitsQuery = null; // Check for magic prefixes if (parameterMap.get("prefix") != null) { // Calls the Form2SPARQL service with the parameterMap which returns // a SPARQL as String Form2SparqlService form2SparqlService = new Form2SparqlService(parameterMap.get("prefix"), parameterMap.get("freetext-field")); parameterMap.remove("prefix"); // The prefixes are magic variables parameterMap.remove("freetext-field"); // The freetext-fields are magic variables too parameterMap.remove("res-view"); // As is this boolean truncate = Boolean.valueOf(SettingsService.getProperty("sublima.advancedsearch.truncate")); // Test if some of the free text fields in the advanced search form exists, if so we build a // proper search string if (req.getCocoonRequest().getParameter("dct:title") != null && !"".equals(req.getCocoonRequest().getParameter("dct:title"))) { parameterMap.remove("dct:title"); form2SparqlService.setTruncate(truncate); searchStringOverriden = freeTextSearchString( req.getCocoonRequest().getParameter("dct:title"), "AND", true, true); parameterMap.put("dct:title", new String[] {searchStringOverriden}); } if (req.getCocoonRequest().getParameter("dct:subject/sub:literals") != null && !"".equals(req.getCocoonRequest().getParameter("dct:subject/sub:literals"))) { parameterMap.remove("dct:subject/sub:literals"); form2SparqlService.setTruncate(truncate); searchStringOverriden = freeTextSearchString( req.getCocoonRequest().getParameter("dct:subject/sub:literals"), "AND", true, true); parameterMap.put("dct:subject/sub:literals", new String[] {searchStringOverriden}); } if (req.getCocoonRequest().getParameter("dct:description") != null && !"".equals(req.getCocoonRequest().getParameter("dct:description"))) { parameterMap.remove("dct:description"); form2SparqlService.setTruncate(truncate); searchStringOverriden = freeTextSearchString( req.getCocoonRequest().getParameter("dct:description"), "AND", true, true); parameterMap.put("dct:description", new String[] {searchStringOverriden}); } if (req.getCocoonRequest().getParameter("dct:publisher/foaf:name") != null && !"".equals(req.getCocoonRequest().getParameter("dct:publisher/foaf:name"))) { parameterMap.remove("dct:publisher/foaf:name"); form2SparqlService.setTruncate(truncate); searchStringOverriden = freeTextSearchString( req.getCocoonRequest().getParameter("dct:publisher/foaf:name"), "AND", true, true); parameterMap.put("dct:publisher/foaf:name", new String[] {searchStringOverriden}); } // Keep a copy of the original parameterMap so that we can reuse it later Map<String, String[]> parameterMapBackup = new TreeMap<String, String[]>(parameterMap); sparqlQuery = form2SparqlService.convertForm2Sparql(parameterMap); countNumberOfHitsQuery = form2SparqlService.convertForm2SparqlCount( parameterMap, Integer.valueOf(SettingsService.getProperty("sublima.search.maxhitsbeforestop"))); // OKE-562 If the search returns 0 hits, do a deep search if such is enabled. boolean zeroHitsStrategyEnables = Boolean.valueOf(getProperty("sulima.deepsearch.when.zero.hits")); if (freetext && zeroHitsStrategyEnables) { moreThanZeroHitsQuery = form2SparqlService.convertForm2SparqlMoreThanZeroHits(parameterMap); String moreThanZeroHitsResult = (String) sparqlDispatcher.query(moreThanZeroHitsQuery); if (moreThanZeroHitsResult == null || !moreThanZeroHitsResult.contains("<uri>")) { form2SparqlService.setDeepsearch(true); form2SparqlService.nullN3List(); sparqlQuery = form2SparqlService.convertForm2Sparql(parameterMapBackup); countNumberOfHitsQuery = form2SparqlService.convertForm2SparqlCount( parameterMapBackup, Integer.valueOf(SettingsService.getProperty("sublima.search.maxhitsbeforestop"))); messageBuffer.append( "<c:message><i18n:text key=\"search.zerohits\">Ingen treff i ressursenes metadata, utførte derfor et dypere søk som også inkluderte søk i ressursenes eksterne innhold.</i18n:text></c:message>"); } } } else { res.sendStatus(400); } // logger.trace("doAdvancedSearch: SPARQL query sent to dispatcher:\n" + sparqlQuery); Object queryResult; if (doBigSearchAnyway) { // This will do the search despite it being large, thus populating the cache queryResult = sparqlDispatcher.query(sparqlQuery); } else if (doSearch) { if (adminService.isAboveMaxNumberOfHits(countNumberOfHitsQuery)) { // We are above the threshold, lets see if we have it cached CachingService cache = new CachingService(); MemcachedClient memcached = cache.connect(); String cacheString = sparqlQuery.replaceAll("\\s+", " ") + SettingsService.getProperty("sublima.base.url"); String cacheKey = String.valueOf( cacheString.hashCode()); // We could parse the query first to get a better key // logger.trace("SPARQLdispatcher hashing for use as key.\n" + cacheString + "\n"); if (cache.ask(memcached, cacheKey)) { logger.debug("SearchController found the query in the cache."); queryResult = sparqlDispatcher.query(sparqlQuery); // Cache will be used in here. abovemaxnumberofhits = false; } else { Request r = req.getCocoonRequest(); String uri = r.getScheme() + "://" + r.getServerName(); if (r.getServerPort() != 80) { uri = uri + ":" + r.getServerPort(); } uri = uri + r.getRequestURI() + "?dobigsearchanyway=true&" + r.getQueryString(); heavylogger.info(uri); queryResult = "<empty/>"; abovemaxnumberofhits = true; } } else { // We are below the threshold, do the search. Cache will be checked queryResult = sparqlDispatcher.query(sparqlQuery); abovemaxnumberofhits = false; } } else { queryResult = "<empty/>"; } Object navigationResults = "<empty></empty>"; if (searchStringOverriden != null && searchStringOverriden.length() > 0) { // Now get the matching topics String sparqlTopicsQuery = null; if (!searchStringOverriden.isEmpty() && !"''".equals(searchStringOverriden)) { sparqlTopicsQuery = "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n" + "PREFIX skos: <http://www.w3.org/2004/02/skos/core#> \n" + "PREFIX owl: <http://www.w3.org/2002/07/owl#> \n" + "PREFIX wdr: <http://www.w3.org/2007/05/powder#>\n" + "PREFIX sub: <http://xmlns.computas.com/sublima#>\n" + "DESCRIBE ?subject WHERE {\n" + " ?subject sub:literals ?lit .\n" + " ?lit <bif:contains> \"\"\"" + searchStringOverriden + "\"\"\" . \n" + " ?subject a skos:Concept .\n" + " ?subject wdr:describedBy <http://sublima.computas.com/status/godkjent_av_administrator> . \n" + "\n}\n"; // logger.trace("doAdvanced: SPARQL query to get topics sent to dispatcher:\n" + // sparqlTopicsQuery); navigationResults = sparqlDispatcher.query(sparqlTopicsQuery); } else { navigationResults = "<empty/>"; } } bizData.put("result-list", queryResult); bizData.put("navigation", navigationResults); bizData.put("mode", mode); bizData.put("searchparams", xmlSearchParametersBuffer.toString()); StringBuilder params = adminService.getMostOfTheRequestXML(req); params.append("\n </request>\n"); messageBuffer.append("</c:messages>"); bizData.put("request", params.toString()); bizData.put("loggedin", loggedIn); bizData.put("messages", messageBuffer.toString()); bizData.put("abovemaxnumberofhits", abovemaxnumberofhits); bizData.put("comment", "<empty/>"); System.gc(); res.sendPage(format + "/sparql-result", bizData); }
/** Insure that the context path is added to the page meta. */ public void addPageMeta(PageMeta pageMeta) throws SAXException, WingException, UIException, SQLException, IOException, AuthorizeException { // FIXME: I don't think these should be set here, but there needed and I'm // not sure where else it could go. Perhaps the linkResolver? Request request = ObjectModelHelper.getRequest(objectModel); pageMeta.addMetadata("contextPath").addContent(contextPath); pageMeta.addMetadata("request", "queryString").addContent(request.getQueryString()); pageMeta.addMetadata("request", "scheme").addContent(request.getScheme()); pageMeta.addMetadata("request", "serverPort").addContent(request.getServerPort()); pageMeta.addMetadata("request", "serverName").addContent(request.getServerName()); pageMeta.addMetadata("request", "URI").addContent(request.getSitemapURI()); String dspaceVersion = Util.getSourceVersion(); if (dspaceVersion != null) { pageMeta.addMetadata("dspace", "version").addContent(dspaceVersion); } String analyticsKey = ConfigurationManager.getProperty("xmlui.google.analytics.key"); if (analyticsKey != null && analyticsKey.length() > 0) { analyticsKey = analyticsKey.trim(); pageMeta.addMetadata("google", "analytics").addContent(analyticsKey); } // add metadata for OpenSearch auto-discovery links if enabled if (ConfigurationManager.getBooleanProperty("websvc.opensearch.autolink")) { pageMeta .addMetadata("opensearch", "shortName") .addContent(ConfigurationManager.getProperty("websvc.opensearch.shortname")); pageMeta .addMetadata("opensearch", "context") .addContent(ConfigurationManager.getProperty("websvc.opensearch.svccontext")); } // Add metadata for quick searches: pageMeta.addMetadata("search", "simpleURL").addContent(contextPath + "/search"); pageMeta.addMetadata("search", "advancedURL").addContent(contextPath + "/advanced-search"); pageMeta.addMetadata("search", "queryField").addContent("query"); pageMeta.addMetadata("page", "contactURL").addContent(contextPath + "/contact"); pageMeta.addMetadata("page", "feedbackURL").addContent(contextPath + "/feedback"); // Add the locale meta data including language dependant labels Locale[] locales = I18nUtil.getSupportedLocales(); for (int i = 0; i < locales.length; i++) { pageMeta.addMetadata("page", "supportedLocale").addContent(locales[i].toString()); // now add the appropriate labels pageMeta .addMetadata("supportedLocale", locales[i].toString()) .addContent(locales[i].getDisplayName(locales[i])); } pageMeta.addMetadata("page", "currentLocale").addContent(context.getCurrentLocale().toString()); DSpaceObject dso = HandleUtil.obtainHandle(objectModel); if (dso != null) { if (dso instanceof Item) { pageMeta.addMetadata("focus", "object").addContent("hdl:" + dso.getHandle()); this.getObjectManager().manageObject(dso); dso = ((Item) dso).getOwningCollection(); } if (dso instanceof Collection || dso instanceof Community) { pageMeta.addMetadata("focus", "container").addContent("hdl:" + dso.getHandle()); this.getObjectManager().manageObject(dso); } } }