From 5df553c152c2002c56ef0d8f06ee516005786b83 Mon Sep 17 00:00:00 2001 From: Michael Peter Christen Date: Mon, 10 Sep 2012 14:30:44 +0200 Subject: [PATCH] - added a json writer for solr (yes there was one using xslt but this one writes the same way as yacysearch.json) - using the new json solr result to change the ajax search in IndexControlURLs to the new solr search --- htroot/IndexControlURLs_p.html | 3 +- htroot/solr/select.java | 2 + source/de/anomic/server/serverObjects.java | 2 +- .../federated/solr/JsonResponseWriter.java | 293 ++++++++++++++++++ .../solr/OpensearchResponseWriter.java | 187 ++--------- 5 files changed, 320 insertions(+), 167 deletions(-) create mode 100644 source/net/yacy/cora/services/federated/solr/JsonResponseWriter.java diff --git a/htroot/IndexControlURLs_p.html b/htroot/IndexControlURLs_p.html index 500431e28..77abc40a3 100644 --- a/htroot/IndexControlURLs_p.html +++ b/htroot/IndexControlURLs_p.html @@ -21,7 +21,8 @@ function search(query) { else if (window.ActiveXObject) { // IE self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP"); } - self.xmlHttpReq.open('GET', "yacysearch.json?verify=false&resource=local&maximumRecords=100&nav=none&query=" + query + "+inurl:" + query, true); + self.xmlHttpReq.open('GET', "/solr/select?q=sku:\"" + query + "\" OR host_s:\"" + query + "\" OR host_dnc_s:\"" + query + "\" OR host_organization_s:\"" + query + "\" OR host_organizationdnc_s:\"" + query + "\" OR host_subdomain_s:\"" + query + "\"&start=0&rows=100&wt=json", true); + //self.xmlHttpReq.open('GET', "yacysearch.json?verify=false&resource=local&maximumRecords=100&nav=none&query=" + query + "+inurl:" + query, true); self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); self.xmlHttpReq.onreadystatechange = function() { if (self.xmlHttpReq.readyState == 4) { diff --git a/htroot/solr/select.java b/htroot/solr/select.java index 6f554b839..0bd9562ad 100644 --- a/htroot/solr/select.java +++ b/htroot/solr/select.java @@ -32,6 +32,7 @@ import net.yacy.cora.protocol.HeaderFramework; import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.services.federated.solr.EmbeddedSolrConnector; import net.yacy.cora.services.federated.solr.EnhancedXMLResponseWriter; +import net.yacy.cora.services.federated.solr.JsonResponseWriter; import net.yacy.cora.services.federated.solr.OpensearchResponseWriter; import net.yacy.cora.services.federated.solr.SolrServlet; import net.yacy.kelondro.logging.Log; @@ -75,6 +76,7 @@ public class select { RESPONSE_WRITER.put("xslt", xsltWriter); // try i.e. http://localhost:8090/solr/select?q=*:*&start=0&rows=10&wt=xslt&tr=json.xsl RESPONSE_WRITER.put("exml", new EnhancedXMLResponseWriter()); RESPONSE_WRITER.put("rss", new OpensearchResponseWriter()); //try http://localhost:8090/solr/select?wt=rss&q=olympia&hl=true&hl.fl=text_t,h1,h2 + RESPONSE_WRITER.put("json", new JsonResponseWriter()); //try http://localhost:8090/solr/select?wt=json&q=olympia&hl=true&hl.fl=text_t,h1,h2 } /** diff --git a/source/de/anomic/server/serverObjects.java b/source/de/anomic/server/serverObjects.java index 165cb7b15..3033e1155 100644 --- a/source/de/anomic/server/serverObjects.java +++ b/source/de/anomic/server/serverObjects.java @@ -223,7 +223,7 @@ public class serverObjects extends HashMap implements Cloneable return put(key, toJSON(value.toString())); } - private static String toJSON(String value) { + public static String toJSON(String value) { // value = value.replaceAll("\\", "\\\\"); value = patternDoublequote.matcher(value).replaceAll("'"); value = patternSlash.matcher(value).replaceAll("\\/"); diff --git a/source/net/yacy/cora/services/federated/solr/JsonResponseWriter.java b/source/net/yacy/cora/services/federated/solr/JsonResponseWriter.java new file mode 100644 index 000000000..966a37501 --- /dev/null +++ b/source/net/yacy/cora/services/federated/solr/JsonResponseWriter.java @@ -0,0 +1,293 @@ +/** + * JsonResponseWriter + * Copyright 2012 by Michael Peter Christen + * First released 10.09.2012 at http://yacy.net + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program in the file lgpl21.txt + * If not, see . + */ + +package net.yacy.cora.services.federated.solr; + +import java.io.IOException; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import net.yacy.cora.protocol.HeaderFramework; +import net.yacy.cora.services.federated.solr.OpensearchResponseWriter.ResHead; +import net.yacy.search.index.YaCySchema; + +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Fieldable; +import org.apache.solr.common.util.NamedList; +import org.apache.solr.common.util.SimpleOrderedMap; +import org.apache.solr.request.SolrQueryRequest; +import org.apache.solr.response.QueryResponseWriter; +import org.apache.solr.response.SolrQueryResponse; +import org.apache.solr.search.DocIterator; +import org.apache.solr.search.DocSlice; +import org.apache.solr.search.SolrIndexSearcher; + +import de.anomic.server.serverObjects; + +/** + * write the opensearch result in YaCys special way to include as much as in opensearch is included. + * This will also include YaCy facets. + */ +public class JsonResponseWriter implements QueryResponseWriter { + + private String title; + + public JsonResponseWriter() { + super(); + } + + public void setTitle(String searchPageTitle) { + this.title = searchPageTitle; + } + + @Override + public String getContentType(final SolrQueryRequest request, final SolrQueryResponse response) { + return "application/json; charset=UTF-8"; + } + + @Override + public void init(@SuppressWarnings("rawtypes") NamedList n) { + } + + @Override + public void write(final Writer writer, final SolrQueryRequest request, final SolrQueryResponse rsp) throws IOException { + assert rsp.getValues().get("responseHeader") != null; + assert rsp.getValues().get("response") != null; + + @SuppressWarnings("unchecked") + SimpleOrderedMap responseHeader = (SimpleOrderedMap) rsp.getResponseHeader(); + DocSlice response = (DocSlice) rsp.getValues().get("response"); + @SuppressWarnings("unchecked") + SimpleOrderedMap highlighting = (SimpleOrderedMap) rsp.getValues().get("highlighting"); + Map> snippets = OpensearchResponseWriter.highlighting(highlighting); + + // parse response header + ResHead resHead = new ResHead(); + NamedList val0 = (NamedList) responseHeader.get("params"); + resHead.rows = Integer.parseInt((String) val0.get("rows")); + resHead.offset = response.offset(); // equal to 'start' + resHead.numFound = response.matches(); + + // write header + writer.write(("{\"channels\": [{\n").toCharArray()); + solitaireTag(writer, "totalResults", Integer.toString(resHead.numFound)); + solitaireTag(writer, "startIndex", Integer.toString(resHead.offset)); + solitaireTag(writer, "itemsPerPage", Integer.toString(resHead.rows)); + solitaireTag(writer, "title", this.title); + solitaireTag(writer, "description", "Search Result"); + writer.write("\"items\": [\n".toCharArray()); + + // parse body + final int responseCount = response.size(); + SolrIndexSearcher searcher = request.getSearcher(); + DocIterator iterator = response.iterator(); + String urlhash = null; + for (int i = 0; i < responseCount; i++) { + writer.write("{\n".toCharArray()); + int id = iterator.nextDoc(); + Document doc = searcher.doc(id, OpensearchResponseWriter.SOLR_FIELDS); + List fields = doc.getFields(); + int fieldc = fields.size(); + List texts = new ArrayList(); + String description = ""; + for (int j = 0; j < fieldc; j++) { + Fieldable value = fields.get(j); + String fieldName = value.name(); + if (YaCySchema.title.name().equals(fieldName)) { + solitaireTag(writer, "title", value.stringValue()); + texts.add(value.stringValue()); + continue; + } + if (YaCySchema.sku.name().equals(fieldName)) { + urlhash = value.stringValue(); + solitaireTag(writer, "link", value.stringValue()); + continue; + } + if (YaCySchema.description.name().equals(fieldName)) { + description = value.stringValue(); + texts.add(description); + continue; + } + if (YaCySchema.id.name().equals(fieldName)) { + urlhash = value.stringValue(); + solitaireTag(writer, "guid", urlhash); + continue; + } + if (YaCySchema.last_modified.name().equals(fieldName)) { + Date d = new Date(Long.parseLong(value.stringValue())); + solitaireTag(writer, "pubDate", HeaderFramework.formatRFC1123(d)); + texts.add(value.stringValue()); + continue; + } + if (YaCySchema.size_i.equals(fieldName)) { + urlhash = value.stringValue(); + int size = value.stringValue() != null && value.stringValue().length() > 0 ? Integer.parseInt(value.stringValue()) : -1; + int sizekb = size / 1024; + int sizemb = sizekb / 1024; + solitaireTag(writer, "size", value.stringValue()); + solitaireTag(writer, "sizename", sizemb > 0 ? (Integer.toString(sizemb) + " mbyte") : sizekb > 0 ? (Integer.toString(sizekb) + " kbyte") : (Integer.toString(size) + " byte")); + continue; + } + if (YaCySchema.text_t.name().equals(fieldName)) { + texts.add(value.stringValue()); + continue; + } + if (YaCySchema.h1_txt.name().equals(fieldName) || YaCySchema.h2_txt.name().equals(fieldName) || + YaCySchema.h3_txt.name().equals(fieldName) || YaCySchema.h4_txt.name().equals(fieldName) || + YaCySchema.h5_txt.name().equals(fieldName) || YaCySchema.h6_txt.name().equals(fieldName)) { + // because these are multi-valued fields, there can be several of each + texts.add(value.stringValue()); + continue; + } + } + // compute snippet from texts + List snippet = urlhash == null ? null : snippets.get(urlhash); + writer.write("\"description\":\""); writer.write(serverObjects.toJSON(snippet == null || snippet.size() == 0 ? description : snippet.get(0))); writer.write("\"\n}\n"); + if (i < responseCount - 1) { + writer.write(",\n".toCharArray()); + } + } + writer.write("]}]}\n".toCharArray()); + } + + public static void solitaireTag(final Writer writer, final String tagname, String value) throws IOException { + if (value == null || value.length() == 0) return; + writer.write('"'); writer.write(tagname); writer.write("\":\""); writer.write(serverObjects.toJSON(value)); writer.write("\","); writer.write('\n'); + } + +} + +/** +{ + "channels": [{ + "title": "YaCy P2P-Search for uni-mainz", + "description": "Search for uni-mainz", + "link": "http://localhost:8090/yacysearch.html?query=uni-mainz&resource=local&contentdom=text&verify=-UNRESOLVED_PATTERN-", + "image": { + "url": "http://localhost:8090/env/grafics/yacy.gif", + "title": "Search for uni-mainz", + "link": "http://localhost:8090/yacysearch.html?query=uni-mainz&resource=local&contentdom=text&verify=-UNRESOLVED_PATTERN-" + }, + "totalResults": "1986", + "startIndex": "0", + "itemsPerPage": "10", + "searchTerms": "uni-mainz", + + "items": [ + + { + "title": "From dark matter to school experiments: Physicists meet in Mainz", + "link": "http://www.phmi.uni-mainz.de/5305.php", + "code": "", + "description": "", + "pubDate": "Mon, 10 Sep 2012 10:25:36 +0000", + "size": "15927", + "sizename": "15 kbyte", + "guid": "7NYsT4NwCWgB", + "faviconCode": "d6ce1c0b", + "host": "www.phmi.uni-mainz.de", + "path": "/5305.php", + "file": "/5305.php", + "urlhash": "7NYsT4NwCWgB", + "ranking": "6983282" + } + , +.. +} +], +"navigation": [ +{ + "facetname": "filetypes", + "displayname": "Filetype", + "type": "String", + "min": "0", + "max": "0", + "mean": "0", + "elements": [ + {"name": "php", "count": "8", "modifier": "filetype%3Aphp", "url": "/yacysearch.json?query=uni-mainz+filetype%3Aphp&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "html", "count": "1", "modifier": "filetype%3Ahtml", "url": "/yacysearch.json?query=uni-mainz+filetype%3Ahtml&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"} + ] +}, +{ + "facetname": "protocols", + "displayname": "Protocol", + "type": "String", + "min": "0", + "max": "0", + "mean": "0", + "elements": [ + {"name": "http", "count": "13", "modifier": "%2Fhttp", "url": "/yacysearch.json?query=uni-mainz+%2Fhttp&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "https", "count": "1", "modifier": "%2Fhttps", "url": "/yacysearch.json?query=uni-mainz+%2Fhttps&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"} + ] +}, +{ + "facetname": "domains", + "displayname": "Domains", + "type": "String", + "min": "0", + "max": "0", + "mean": "0", + "elements": [ + {"name": "www.geo.uni-frankfurt.de", "count": "1", "modifier": "site%3Awww.geo.uni-frankfurt.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.geo.uni-frankfurt.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.info.jogustine.uni-mainz.de", "count": "1", "modifier": "site%3Awww.info.jogustine.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.info.jogustine.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.fb09.uni-mainz.de", "count": "1", "modifier": "site%3Awww.fb09.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.fb09.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.studgen.uni-mainz.de", "count": "1", "modifier": "site%3Awww.studgen.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.studgen.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "twitter.com", "count": "1", "modifier": "site%3Atwitter.com", "url": "/yacysearch.json?query=uni-mainz+site%3Atwitter.com&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.theaterwissenschaft.uni-mainz.de", "count": "1", "modifier": "site%3Awww.theaterwissenschaft.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.theaterwissenschaft.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.uni-mainz.de", "count": "1", "modifier": "site%3Awww.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.fb06.uni-mainz.de", "count": "1", "modifier": "site%3Awww.fb06.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.fb06.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.familienservice.uni-mainz.de", "count": "1", "modifier": "site%3Awww.familienservice.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.familienservice.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.zdv.uni-mainz.de", "count": "1", "modifier": "site%3Awww.zdv.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.zdv.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "zope.verwaltung.uni-mainz.de", "count": "1", "modifier": "site%3Azope.verwaltung.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Azope.verwaltung.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.geo.uni-mainz.de", "count": "1", "modifier": "site%3Awww.geo.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.geo.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.bio.uni-mainz.de", "count": "1", "modifier": "site%3Awww.bio.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.bio.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "www.phmi.uni-mainz.de", "count": "1", "modifier": "site%3Awww.phmi.uni-mainz.de", "url": "/yacysearch.json?query=uni-mainz+site%3Awww.phmi.uni-mainz.de&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"} + ] +}, +{ + "facetname": "topics", + "displayname": "Topics", + "type": "String", + "min": "0", + "max": "0", + "mean": "0", + "elements": [ + {"name": "des", "count": "3", "modifier": "des", "url": "/yacysearch.json?query=uni-mainz+des&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "auf", "count": "2", "modifier": "auf", "url": "/yacysearch.json?query=uni-mainz+auf&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "willkommen", "count": "2", "modifier": "willkommen", "url": "/yacysearch.json?query=uni-mainz+willkommen&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "biologie", "count": "1", "modifier": "biologie", "url": "/yacysearch.json?query=uni-mainz+biologie&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "johannes", "count": "1", "modifier": "johannes", "url": "/yacysearch.json?query=uni-mainz+johannes&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "weiterleitung", "count": "1", "modifier": "weiterleitung", "url": "/yacysearch.json?query=uni-mainz+weiterleitung&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "archiv", "count": "1", "modifier": "archiv", "url": "/yacysearch.json?query=uni-mainz+archiv&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "entdecken", "count": "1", "modifier": "entdecken", "url": "/yacysearch.json?query=uni-mainz+entdecken&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "gutenberg", "count": "1", "modifier": "gutenberg", "url": "/yacysearch.json?query=uni-mainz+gutenberg&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "heimverzeichnis", "count": "1", "modifier": "heimverzeichnis", "url": "/yacysearch.json?query=uni-mainz+heimverzeichnis&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "school", "count": "1", "modifier": "school", "url": "/yacysearch.json?query=uni-mainz+school&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"}, + {"name": "vernetzung", "count": "1", "modifier": "vernetzung", "url": "/yacysearch.json?query=uni-mainz+vernetzung&maximumRecords=10&resource=local&verify=iffresh&nav=hosts,authors,namespace,topics,filetype,protocol&urlmaskfilter=.*&prefermaskfilter=&cat=href&constraint=&contentdom=text&former=uni-mainz&startRecord=0"} + ] +} +], +"totalResults": "1986" +}] +} +*/ \ No newline at end of file diff --git a/source/net/yacy/cora/services/federated/solr/OpensearchResponseWriter.java b/source/net/yacy/cora/services/federated/solr/OpensearchResponseWriter.java index de0c52714..dda1cde93 100644 --- a/source/net/yacy/cora/services/federated/solr/OpensearchResponseWriter.java +++ b/source/net/yacy/cora/services/federated/solr/OpensearchResponseWriter.java @@ -49,20 +49,6 @@ import org.apache.solr.search.SolrIndexSearcher; public class OpensearchResponseWriter implements QueryResponseWriter { - private static final char lb = '\n'; - private static final char[] XML_START = ( - "\n" + - "\n" + - "\n").toCharArray(); - private static final char[] XML_STOP = "\n".toCharArray(); - // define a list of simple YaCySchema -> RSS Token matchings private static final Map field2tag = new HashMap(); @@ -71,7 +57,7 @@ public class OpensearchResponseWriter implements QueryResponseWriter { YaCySchema.id, YaCySchema.title, YaCySchema.description, YaCySchema.text_t, YaCySchema.h1_txt, YaCySchema.h2_txt, YaCySchema.h3_txt, YaCySchema.h4_txt, YaCySchema.h5_txt, YaCySchema.h6_txt, }; - private static final Set SOLR_FIELDS = new HashSet(); + static final Set SOLR_FIELDS = new HashSet(); static { field2tag.put(YaCySchema.sku.name(), RSSMessage.Token.link.name()); field2tag.put(YaCySchema.publisher_t.name(), DublinCore.Publisher.getURIref()); @@ -82,7 +68,7 @@ public class OpensearchResponseWriter implements QueryResponseWriter { private String title; - private static class ResHead { + public static class ResHead { public int offset, rows, numFound; //public int status, QTime; //public String df, q, wt; @@ -132,7 +118,17 @@ public class OpensearchResponseWriter implements QueryResponseWriter { //resHead.maxScore = response.maxScore(); // write header - writer.write(XML_START); + writer.write(( + "\n" + + "\n" + + "\n").toCharArray()); openTag(writer, "channel"); solitaireTag(writer, "opensearch:totalResults", Integer.toString(resHead.numFound)); solitaireTag(writer, "opensearch:startIndex", Integer.toString(resHead.offset)); @@ -204,12 +200,15 @@ public class OpensearchResponseWriter implements QueryResponseWriter { } // compute snippet from texts List snippet = urlhash == null ? null : snippets.get(urlhash); - solitaireTagNocheck(writer, RSSMessage.Token.description.name(), snippet == null || snippet.size() == 0 ? description : snippet.get(0)); + String tagname = RSSMessage.Token.description.name(); + writer.write("<"); writer.write(tagname); writer.write('>'); + XML.escapeCharData(snippet == null || snippet.size() == 0 ? description : snippet.get(0), writer); + writer.write("\n"); closeTag(writer, "item"); } closeTag(writer, "channel"); - writer.write(XML_STOP); + writer.write("\n".toCharArray()); } @SuppressWarnings("unchecked") @@ -237,22 +236,18 @@ public class OpensearchResponseWriter implements QueryResponseWriter { } public static void openTag(final Writer writer, final String tag) throws IOException { - writer.write('<'); writer.write(tag); writer.write('>'); writer.write(lb); + writer.write('<'); writer.write(tag); writer.write(">\n"); } public static void closeTag(final Writer writer, final String tag) throws IOException { - writer.write("'); writer.write(lb); + writer.write("\n"); } public static void solitaireTag(final Writer writer, final String tagname, String value) throws IOException { if (value == null || value.length() == 0) return; - solitaireTagNocheck(writer, tagname, value); - } - - public static void solitaireTagNocheck(final Writer writer, final String tagname, String value) throws IOException { writer.write("<"); writer.write(tagname); writer.write('>'); XML.escapeCharData(value, writer); - writer.write("'); writer.write(lb); + writer.write("\n"); } public static void solitaireTag(final Writer writer, final String tagname, String value, String attr) throws IOException { @@ -262,145 +257,7 @@ public class OpensearchResponseWriter implements QueryResponseWriter { writer.write(attr); writer.write('>'); writer.write(value); - writer.write("'); writer.write(lb); + writer.write("\n"); } } - -/* - - - #[promoteSearchPageGreeting]# - Search for #[rss_query]# - #[searchBaseURL]#?query=#[rss_queryenc]#&resource=#[resource]#&contentdom=#[contentdom]#&verify=#[verify]# - - #[rssYacyImageURL]# - Search for #[rss_query]# - #[searchBaseURL]#?query=#[rss_queryenc]#&resource=#[resource]#&contentdom=#[contentdom]#&verify=#[verify]# - - #[num-results_totalcount]# - #[num-results_offset]# - #[num-results_itemsPerPage]# - - - - - - -#[title-xml]# -#[link]# -#[description-xml]# -#[date822]# - - - -#[size]# -#[sizename]# -#[host]# -#[path]# -#[file]# -#[urlhash]# -#(loc)#::#[lat]##[lon]##(/loc)# -:: -#(item)#:: -#[name]# -#[source-xml]# - - -#[urlhash]# -#[sourcedom]# - - - - - - - - - - -#(nav-domains)#:: - -#{element}# - -#{/element}# - -#(/nav-domains)# - -#(nav-namespace)#:: - -#{element}# - -#{/element}# - -#(/nav-namespace)# - -#(nav-authors)#:: - -#{element}# - -#{/element}# - -#(/nav-authors)# - -#(nav-filetype)#:: - -#{element}# - -#{/element}# - -#(/nav-filetype)# - -#(nav-protocol)#:: - -#{element}# - -#{/element}# - -#(/nav-protocol)# - -#(nav-topics)#:: - -#{element}# - -#{/element}# - -#(/nav-topics)# - -#{nav-vocabulary}# - -#{element}# - -#{/element}# - -#{/nav-vocabulary}# - - - -#[num-results_totalcount]# - - */ \ No newline at end of file