Skip to content

Commit

Permalink
Optionally render the response header when using the Solr html writer
Browse files Browse the repository at this point in the history
With params rendered as html input fields for conveniently modifying
params values and refreshing results.
  • Loading branch information
luccioman committed Jul 23, 2018
1 parent 313204a commit bf4f320
Show file tree
Hide file tree
Showing 5 changed files with 175 additions and 9 deletions.
2 changes: 1 addition & 1 deletion htroot/ConfigSearchPage_p.html
Expand Up @@ -268,7 +268,7 @@ <h4 class="linktitle">
<td style="width:15px;"></td>
<td><span title="Last known modification date">#[content_showDate_date]#</span></td>
<td><span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span>42 kbyte</td>
<td><span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a id="metadataLink" href="solr/select?q=*:*&defType=edismax&start=0&rows=3&core=collection1&wt=html" target="LayouTest">Metadata</a></td>
<td><span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a id="metadataLink" href="solr/select?q=*:*&defType=edismax&start=0&rows=1&core=collection1&wt=html&omitHeader=true" target="LayouTest">Metadata</a></td>
<td><span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a id="parserLink" href="ViewFile.html" target="LayouTest">Parser</a></td>
<td><span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a id="citationLink" href="api/citation.html?url=yacy.net" target="LayouTest">Citation</a></td>
<td><span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a id="picturesLink" href="yacysearch.html" target="LayouTest">Pictures</a></td>
Expand Down
4 changes: 2 additions & 2 deletions htroot/IndexControlURLs_p.html
Expand Up @@ -63,7 +63,7 @@
#%env/templates/header.template%#
#%env/templates/submenuIndexControl.template%#
<div id="api">
<a href="solr/select?defType=edismax&start=0&rows=3&core=collection1&wt=html&q=id:%22#[urlhash]#%22">
<a href="solr/select?defType=edismax&start=0&rows=3&core=collection1&wt=html&omitHeader=true&q=id:%22#[urlhash]#%22">
<img src="env/grafics/api.png" width="60" height="40" alt="API" /></a>
<span>These document details can be retrieved as <a href="http://www.w3.org/TR/xhtml-rdfa-primer/" target="_blank">XHTML+RDFa</a>
document containg <a href="http://www.w3.org/RDF/" target="_blank">RDF</a> annotations in <a href="http://dublincore.org/" target="_blank">Dublin Core</a> vocabulary.
Expand Down Expand Up @@ -181,7 +181,7 @@ <h2>URL Database Administration</h2>

#(genUrlProfile)#
::No entry found for URL-hash #[urlhash]#
::<iframe src="solr/select?defType=edismax&start=0&rows=3&core=collection1&wt=html&q=id:%22#[urlhash]#%22" width="100%" height="420" frameborder="0" scrolling="no"></iframe>
::<iframe src="solr/select?defType=edismax&start=0&rows=3&core=collection1&wt=html&omitHeader=true&q=id:%22#[urlhash]#%22" width="100%" height="420" frameborder="0" scrolling="no"></iframe>
<br />
<p>
<form action="ViewFile.html" method="get" accept-charset="UTF-8">
Expand Down
2 changes: 1 addition & 1 deletion htroot/ViewFile.html
Expand Up @@ -104,7 +104,7 @@ <h2>View URL Content</h2>
<fieldset><legend>URL Metadata</legend>
<dl>
<dt>URL:</dt><dd><a href="#[url]#">#[url]#</a></dd>
<dt>Hash:</dt><dd>#(inurldb)##[hash]#::<a href="solr/select?defType=edismax&start=0&rows=3&core=collection1&wt=html&q=id:%22#[hash]#%22">#[hash]#</a> (click this for full metadata)#(/inurldb)#</dd>
<dt>Hash:</dt><dd>#(inurldb)##[hash]#::<a href="solr/select?defType=edismax&start=0&rows=3&core=collection1&wt=html&omitHeader=true&q=id:%22#[hash]#%22">#[hash]#</a> (click this for full metadata)#(/inurldb)#</dd>
<dt>In Metadata:</dt><dd>#(inurldb)#no::yes#(/inurldb)#</dd>
<dt>In Cache:</dt><dd>#(incache)#no::yes#(/incache)#</dd>
<dt>First Seen:</dt><dd>#[firstSeen]#</dd>
Expand Down
2 changes: 1 addition & 1 deletion htroot/yacysearchitem.html
Expand Up @@ -41,7 +41,7 @@ <h4 class="linktitle">
#(showDate)#::<span title="Last known modification date">#[date]#</span>#(/showDate)#
#(showEvent)#::on #[date]##(/showEvent)#
#(showSize)#::<span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span>#[sizename]##(/showSize)#
#(showMetadata)#::<span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a href="solr/select?q=id:%22#[urlhash]#%22&defType=edismax&start=0&rows=1&core=collection1&wt=html" target="_blank">Metadata</a>#(/showMetadata)#
#(showMetadata)#::<span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a href="solr/select?q=id:%22#[urlhash]#%22&defType=edismax&start=0&rows=1&core=collection1&wt=html&omitHeader=true" target="_blank">Metadata</a>#(/showMetadata)#
#(showParser)#::<span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a href="ViewFile.html?urlHash=#[urlhash]#&amp;words=#[words]#" target="_blank">Parser</a>#(/showParser)#
#(showCitation)#::<span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a href="api/citation.html?hash=#[urlhash]#&filter=true" target="_blank">Citations</a>#(/showCitation)#
#(showPictures)#::<span role="separator" aria-orientation="vertical">&nbsp;|&nbsp;</span><a href="yacysearch.html?contentdom=image#(authSearch)#::&auth#(/authSearch)#&url=#[link]#&query=#[former]#+inurl:#[link]#" target="_blank">Pictures</a>#(/showPictures)#
Expand Down
Expand Up @@ -24,6 +24,7 @@
import java.io.Writer;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
Expand All @@ -39,6 +40,7 @@
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.XML;
Expand All @@ -58,6 +60,7 @@

import net.yacy.cora.federate.solr.SolrType;
import net.yacy.cora.lod.vocabulary.DublinCore;
import net.yacy.document.parser.html.CharacterCoding;
import net.yacy.search.schema.CollectionSchema;
import net.yacy.search.schema.WebgraphSchema;

Expand Down Expand Up @@ -127,6 +130,157 @@ private void writeApiLink(final Writer writer, final NamedList<Object> paramsLis
writer.write("<div id=\"api\"><a href=\"" + xmlquery + "\"><img src=\"../env/grafics/api.png\" width=\"60\" height=\"40\" alt=\"API\" /></a>\n");
writer.write("<span>This search result can also be retrieved as XML. Click the API icon to see this page as XML.</span></div>\n");
}

/**
* Optionally (omitHeader request param must not be true) append to the writer an HTML representation of the response header.
* @param writer the output writer. Must not be null.
* @param request the initial Solr request. Must not be null.
* @param responseHeader the eventual Solr response header.
* @throws IOException when an error occurred while appending content to the writer
*/
private void writeResponseHeader(final Writer writer, final SolrQueryRequest request, final NamedList<Object> responseHeader)
throws IOException {
if (responseHeader != null && request.getParams() == null || !request.getParams().getBool(CommonParams.OMIT_HEADER, false)) {
writer.write(
"<form name=\"responseHeaders\" method=\"get\" action=\"select\" enctype=\"multipart/form-data\" accept-charset=\"UTF-8\" class=\"form-horizontal\">\n");
writer.write("<fieldset>\n");
writer.write("<h1>Response header</h1>\n");
writeNamedList(writer, responseHeader, 0);
writer.write("<div class=\"col-sm-offset-2\">");
writer.write("<input class=\"btn btn-primary\" type=\"submit\">");
writer.write("</div>");
writer.write("</fieldset>\n");
writer.write("</form>\n");
}
}

/**
* Append to the writer an HTML representation of the given values.
* @param writer the output writer. Must not be null.
* @param list the values to write. Must not be null.
* @param nestingLevel the nesting level of the list.
* @throws IOException when an error occurred while appending content to the writer
*/
private void writeNamedList(final Writer writer, final NamedList<?> list, final int nestingLevel)
throws IOException {
if (list != null && list.size() > 0) {
writer.write("<dl>\n");
for (final Map.Entry<String, ?> entry : list) {
final String key = entry.getKey();
final Object value = entry.getValue();
writer.write("<dt>");
writer.write(key);
writer.write("</dt>\n<dd>");
if (value instanceof NamedList<?>) {
if (nestingLevel < 5) { // prevent any infite recursive loop
if("params".equals(key) && nestingLevel == 0) {
writeEditableNamedList(writer, (NamedList<?>) value, nestingLevel + 1);
} else {
writeNamedList(writer, (NamedList<?>) value, nestingLevel + 1);
}
}
} else if (value instanceof Iterable<?>) {
writeIterable(writer, key, (Iterable<?>) value);
} else if (value instanceof Object[]) {
writeIterable(writer, key, Arrays.asList((Object[]) value));
} else {
writer.write(CharacterCoding.unicode2html(String.valueOf(value), true));
}
writer.write("</dd>\n");
}
writer.write("</dl>\n");
}
}

/**
* Append to the writer a representation of the given values as HTML form input fields grouped in a fieldset.
* @param writer the output writer. Must not be null.
* @param list the values to write. Must not be null.
* @param nestingLevel the nesting level of the list.
* @throws IOException when an error occurred while appending content to the writer
*/
private void writeEditableNamedList(final Writer writer, final NamedList<?> list, final int nestingLevel)
throws IOException {
if (list != null && list.size() > 0) {
writer.write("<fieldset>\n");
for (final Map.Entry<String, ?> entry : list) {
final String key = entry.getKey();
final Object value = entry.getValue();

if (value instanceof NamedList<?>) {
if (nestingLevel < 5) { // prevent any infite recursive loop
writeEditableNamedList(writer, (NamedList<?>) value, nestingLevel + 1);
}
} else if (value instanceof Iterable<?>) {
writeEditableIterable(writer, key, (Iterable<?>) value);
} else if (value instanceof Object[]) {
writeEditableIterable(writer, key, Arrays.asList((Object[]) value));
} else {
writeEditableValue(writer, key, key, key, value);
}
}
writer.write("</fieldset>\n");
}
}

/**
* Append to the writer a representation of the given value as an HTML form input field.
* @param writer the output writer. Must not be null.
* @param inputLabel the html label to render. Must not be null.
* @param inputId the id attribute of the html input field to render. Must not be null.
* @param inputName the name of the html input field to render. Must not be null.
* @param value the value to write. Must not be null.
* @throws IOException when an error occurred while appending content to the writer
*/
private void writeEditableValue(final Writer writer, final String inputLabel, final String inputId, final String inputName, final Object value) throws IOException {
writer.write("<div class=\"form-group\">\n");
writer.write("<label for=\"" + inputId + "\" class=\"col-sm-2 control-label\">");
writer.write(inputLabel);
writer.write("</label>\n");
writer.write("<div class=\"col-sm-10\">\n");
writer.write("<input type=\"text\" class=\"form-control\" id=\"" + inputId + "\" name=\"" + inputName + "\" value=\"");
writer.write(CharacterCoding.unicode2html(String.valueOf(value), true));
writer.write("\"/>\n");
writer.write("</div></div>\n");
}

/**
* Append to the writer an HTML representation of the given values.
* @param writer the output writer. Must not be null.
* @param key the key of the values. Must not be null.
* @param values the values to write. Must not be null.
* @throws IOException when an error occurred while appending content to the writer
*/
private void writeIterable(final Writer writer, final String key, final Iterable<?> values) throws IOException {
int count = 0;
for (final Object value : values) {
writer.write("<dt>");
writer.write(key);
writer.write("_");
writer.write(Integer.toString(count));
writer.write("</dt>\n<dd>");
writer.write(CharacterCoding.unicode2html(String.valueOf(value), true));
count++;
writer.write("</dd>\n");
}
}

/**
* Append to the writer a representation of the given values as HTML form input fields.
* @param writer the output writer. Must not be null.
* @param key the key of the values. Must not be null.
* @param values the values to write. Must not be null.
* @throws IOException when an error occurred while appending content to the writer
*/
private void writeEditableIterable(final Writer writer, final String key, final Iterable<?> values)
throws IOException {
int count = 0;
for (final Object value : values) {
writeEditableValue(writer, key + "_" + Integer.toString(count), key + "_" + Integer.toString(count), key,
value);
count++;
}
}

@Override
public void write(final Writer writer, final SolrQueryRequest request, final SolrQueryResponse rsp) throws IOException {
Expand All @@ -150,7 +304,7 @@ public void write(final Writer writer, final SolrQueryRequest request, final Sol
*/
final SolrDocumentList docList = ((SolrDocumentList)responseObj);

writeSolrDocumentList(writer, request, coreName, paramsList, docList);
writeSolrDocumentList(writer, request, rsp.getResponseHeader(), coreName, paramsList, docList);
} else if(responseObj instanceof ResultContext){
/* Regular response object */
final DocList documents = ((ResultContext)responseObj).getDocList();
Expand All @@ -169,6 +323,8 @@ public void write(final Writer writer, final SolrQueryRequest request, final Sol
String title = doc.get(CollectionSchema.title.getSolrFieldName()); // title is multivalued, after translation fieldname could be in tdoc. "title_0" ..., so get it from doc
writeTitle(writer, coreName, sz, title);

writeResponseHeader(writer, request, rsp.getResponseHeader());

writeApiLink(writer, paramsList, coreName);

writeDoc(writer, tdoc, coreName, rsp.getReturnFields());
Expand All @@ -182,18 +338,24 @@ public void write(final Writer writer, final SolrQueryRequest request, final Sol
}
} else {
writer.write("<title>No Document Found</title>\n</head><body>\n");

writeResponseHeader(writer, request, rsp.getResponseHeader());

writer.write("<div class='alert alert-info'>No documents found</div>\n");
}

} else {
writer.write("<title>Unable to process Solr response</title>\n</head><body>\n");

writeResponseHeader(writer, request, rsp.getResponseHeader());

writer.write("<div class='alert alert-info'>Unknown Solr response format</div>\n");
}


writer.write("</body></html>\n");
}

@Override
public void write(final Writer writer, final SolrQueryRequest request, final String coreName, final QueryResponse rsp) throws IOException {
writeHtmlHead(writer);
Expand All @@ -203,8 +365,9 @@ public void write(final Writer writer, final SolrQueryRequest request, final Str
paramsList.remove("wt");

final SolrDocumentList docsList = rsp.getResults();
final NamedList<Object> responseHeader = rsp.getHeader();

writeSolrDocumentList(writer, request, coreName, paramsList, docsList);
writeSolrDocumentList(writer, request, responseHeader, coreName, paramsList, docsList);

writer.write("</body></html>\n");
}
Expand All @@ -213,12 +376,13 @@ public void write(final Writer writer, final SolrQueryRequest request, final Str
* Append to the writer HTML reprensentation of the given documents list.
* @param writer the output writer
* @param request the initial Solr request
* @param responseHeader the eventual Solr response header
* @param coreName the requested Solr core
* @param paramsList the original request parameters
* @param docList the result Solr documents list
* @throws IOException
*/
private void writeSolrDocumentList(final Writer writer, final SolrQueryRequest request, final String coreName,
private void writeSolrDocumentList(final Writer writer, final SolrQueryRequest request, final NamedList<Object> responseHeader, final String coreName,
final NamedList<Object> paramsList, final SolrDocumentList docList) throws IOException {
final int sz = docList.size();
if (sz > 0) {
Expand All @@ -230,6 +394,8 @@ private void writeSolrDocumentList(final Writer writer, final SolrQueryRequest r
final Object titleValue = doc.getFirstValue(CollectionSchema.title.getSolrFieldName());
final String firstDocTitle = formatValue(titleValue);
writeTitle(writer, coreName, sz, firstDocTitle);

writeResponseHeader(writer, request, responseHeader);

writeApiLink(writer, paramsList, coreName);

Expand Down

0 comments on commit bf4f320

Please sign in to comment.