diff --git a/CHANGES.txt b/CHANGES.txt index 25dc916ac8a..0a2bc05f13a 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -118,6 +118,8 @@ Changes in runtime behavior through multiple threads. Large commits also might be faster (klaas, SOLR-65) 9. Lazy field loading can be enabled via a solrconfig directive. This will be faster when not all stored fields are needed from a document (klaas, SOLR-52) +10. Made admin JSPs return XML and transform them with new XSL stylesheets + (Otis Gospodnetic, SOLR-58) Optimizations 1. getDocListAndSet can now generate both a DocList and a DocSet from a diff --git a/src/webapp/resources/admin/analysis.jsp b/src/webapp/resources/admin/analysis.jsp index 03cece46d90..bdf0f66e089 100644 --- a/src/webapp/resources/admin/analysis.jsp +++ b/src/webapp/resources/admin/analysis.jsp @@ -1,20 +1,4 @@ -<%@ page contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> -<%-- - Licensed to the Apache Software Foundation (ASF) under one or more - contributor license agreements. See the NOTICE file distributed with - this work for additional information regarding copyright ownership. - The ASF licenses this file to You under the Apache License, Version 2.0 - (the "License"); you may not use this file except in compliance with - the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. ---%> +<%@ page contentType="text/xml; charset=utf-8" pageEncoding="UTF-8" language="java" %> <%@ page import="org.apache.lucene.analysis.Analyzer, org.apache.lucene.analysis.Token, org.apache.lucene.analysis.TokenStream, @@ -30,129 +14,86 @@ <%@ page import="java.io.StringReader"%> <%@ page import="java.util.*"%> -<%-- $Id$ --%> -<%-- $Source: /cvs/main/searching/org.apache.solrolarServer/resources/admin/analysis.jsp,v $ --%> -<%-- $Name: $ --%> + -<%@include file="header.jsp" %> +<%@include file="_info.jsp" %> <% String name = request.getParameter("name"); - if (name==null || name.length()==0) name=""; + if (name == null || name.length() == 0) name = ""; String val = request.getParameter("val"); - if (val==null || val.length()==0) val=""; + if (val == null || val.length() == 0) val = ""; String qval = request.getParameter("qval"); - if (qval==null || qval.length()==0) qval=""; + if (qval == null || qval.length() == 0) qval = ""; String verboseS = request.getParameter("verbose"); - boolean verbose = verboseS!=null && verboseS.equalsIgnoreCase("on"); + boolean verbose = verboseS != null && verboseS.equalsIgnoreCase("on"); String qverboseS = request.getParameter("qverbose"); - boolean qverbose = qverboseS!=null && qverboseS.equalsIgnoreCase("on"); + boolean qverbose = qverboseS != null && qverboseS.equalsIgnoreCase("on"); String highlightS = request.getParameter("highlight"); - boolean highlight = highlightS!=null && highlightS.equalsIgnoreCase("on"); + boolean highlight = highlightS != null && highlightS.equalsIgnoreCase("on"); %> -
- -

Field Analysis

- -
- - - - - - - - - - - - - - - - - - - - -
- Field name - - -
- Field value (Index) -
- verbose output - > -
- highlight matches - > -
- -
- Field value (Query) -
- verbose output - > -
- -
- - -
-
- + +<%@include file="heading.jsp" %> + <% - SchemaField field=null; + SchemaField field = null; - if (name!="") { + if (name != "") { try { field = schema.getField(name); } catch (Exception e) { - out.println("Unknown Field " + name + ""); + out.println("Unknown Field " + name + ""); } } - if (field!=null) { + if (field != null) { + out.println("
"); + out.println(" "); + XML.escapeCharData(name, out); + out.println(""); + out.print(" "); + XML.escapeCharData(val, out); + out.println(" "); + out.print(" "); + XML.escapeCharData(qval, out); + out.println(" "); + out.println("
"); + HashSet matches = null; - if (qval!="" && highlight) { + if (qval != "" && highlight) { Reader reader = new StringReader(qval); Analyzer analyzer = field.getType().getQueryAnalyzer(); - TokenStream tstream = analyzer.tokenStream(field.getName(),reader); + TokenStream tstream = analyzer.tokenStream(field.getName(), reader); List tokens = getTokens(tstream); matches = new HashSet(); - for (Token t : tokens) { matches.add( new Tok(t,0)); } + for (Token t : tokens) { matches.add( new Tok(t, 0)); } } - if (val!="") { - out.println("

Index Analyzer

"); - doAnalyzer(out, field, val, false, verbose,matches); + out.println(" "); + if (val != "") { + out.println(""); + doAnalyzer(out, field, val, false, verbose, matches); + out.println(""); } - if (qval!="") { - out.println("

Query Analyzer

"); - doAnalyzer(out, field, qval, true, qverbose,null); + if (qval != "") { + out.println(""); + doAnalyzer(out, field, qval, true, qverbose, null); + out.println(""); } + out.println("
"); } - %> - - - - - +
+
<%! private static void doAnalyzer(JspWriter out, SchemaField field, String val, boolean queryAnalyser, boolean verbose, Set match) throws Exception { Reader reader = new StringReader(val); FieldType ft = field.getType(); - Analyzer analyzer = queryAnalyser ? - ft.getQueryAnalyzer() : ft.getAnalyzer(); + Analyzer analyzer = queryAnalyser ? ft.getQueryAnalyzer() : ft.getAnalyzer(); if (analyzer instanceof TokenizerChain) { TokenizerChain tchain = (TokenizerChain)analyzer; TokenizerFactory tfac = tchain.getTokenizerFactory(); @@ -161,12 +102,14 @@ TokenStream tstream = tfac.create(reader); List tokens = getTokens(tstream); tstream = tfac.create(reader); + // write tokenizer factories if (verbose) { writeHeader(out, tfac.getClass(), tfac.getArgs()); } writeTokens(out, tokens, ft, verbose, match); + // write filter factories for (TokenFilterFactory filtfac : filtfacs) { if (verbose) { writeHeader(out, filtfac.getClass(), filtfac.getArgs()); @@ -183,7 +126,6 @@ writeTokens(out, tokens, ft, verbose, match); } - } else { TokenStream tstream = analyzer.tokenStream(field.getName(),reader); List tokens = getTokens(tstream); @@ -199,7 +141,7 @@ List tokens = new ArrayList(); while (true) { Token t = tstream.next(); - if (t==null) break; + if (t == null) break; tokens.add(t); } return tokens; @@ -210,8 +152,8 @@ Token token; int pos; Tok(Token token, int pos) { - this.token=token; - this.pos=pos; + this.token = token; + this.pos = pos; } public boolean equals(Object o) { @@ -221,7 +163,7 @@ return token.termText().hashCode(); } public String toString() { - return token.termText(); + return token.termText() + " at position " + pos; } } @@ -229,81 +171,38 @@ public String toStr(Object o); } - private static void printRow(JspWriter out, String header, List[] arrLst, ToStr converter, boolean multival, boolean verbose, Set match) throws IOException { - // find the maximum number of terms for any position - int maxSz=1; - if (multival) { - for (List lst : arrLst) { - maxSz = Math.max(lst.size(), maxSz); - } - } - - - for (int idx=0; idx"); - if (idx==0 && verbose) { - if (header != null) { - out.print(""); - XML.escapeCharData(header,out); - out.println(""); - } - } - - for (List lst : arrLst) { - if (lst.size() <= idx) continue; - if (match!=null && match.contains(lst.get(idx))) { - out.print(" 1) { - out.print("rowspan=\""+maxSz+'"'); - } - - out.print('>'); - - XML.escapeCharData(converter.toStr(lst.get(idx)), out); - out.print(""); - } - - out.println(""); - } - - } - - - static void writeHeader(JspWriter out, Class clazz, Map args) throws IOException { - out.print("

"); - out.print(clazz.getName()); - XML.escapeCharData(" "+args,out); - out.println("

"); + out.println(" "); + out.println(" "); + for (Iterator iter = args.keySet().iterator(); iter.hasNext(); ) { + String key = iter.next(); + String value = args.get(key); + out.println(" " + value + ""); + } + out.println(" "); } - - // readable, raw, pos, type, start/end static void writeTokens(JspWriter out, List tokens, final FieldType ft, boolean verbose, Set match) throws IOException { // Use a map to tell what tokens are in what positions // because some tokenizers/filters may do funky stuff with // very large increments, or negative increments. - HashMap> map = new HashMap>(); - boolean needRaw=false; - int pos=0; + HashMap> map = new HashMap>(); + boolean needRaw = false; + int pos = 0; for (Token t : tokens) { if (!t.termText().equals(ft.indexedToReadable(t.termText()))) { - needRaw=true; + needRaw = true; } pos += t.getPositionIncrement(); List lst = map.get(pos); - if (lst==null) { + if (lst == null) { lst = new ArrayList(1); - map.put(pos,lst); + map.put(pos, lst); } - Tok tok = new Tok(t,pos); + Tok tok = new Tok(t, pos); lst.add(tok); } @@ -330,70 +229,21 @@ ); - out.println(""); - - if (verbose) { - printRow(out,"term position", arr, new ToStr() { - public String toStr(Object o) { - return Integer.toString(((Tok)o).pos); - } - } - ,false - ,verbose - ,null); - } - - - printRow(out,"term text", arr, new ToStr() { - public String toStr(Object o) { - return ft.indexedToReadable( ((Tok)o).token.termText() ); - } - } - ,true - ,verbose - ,match - ); - - if (needRaw) { - printRow(out,"raw text", arr, new ToStr() { - public String toStr(Object o) { - // todo: output in hex or something? - // check if it's all ascii or not? - return ((Tok)o).token.termText(); - } - } - ,true - ,verbose - ,match - ); - } - - if (verbose) { - printRow(out,"term type", arr, new ToStr() { - public String toStr(Object o) { - return ((Tok)o).token.type(); - } - } - ,true - ,verbose, - null - ); - } - - if (verbose) { - printRow(out,"source start,end", arr, new ToStr() { - public String toStr(Object o) { - Token t = ((Tok)o).token; - return Integer.toString(t.startOffset()) + ',' + t.endOffset() ; - } - } - ,true - ,verbose - ,null - ); - } - - out.println("
"); + out.println(" "); + for (int i = 0; i < arr.length; i++) { + for (Tok tok : arr[i]) { + out.print(" "); + out.print(tok.token.termText()); + out.println("
"); + } + } + out.println(" "); + out.println("
"); } %> diff --git a/src/webapp/resources/admin/analysis.xsl b/src/webapp/resources/admin/analysis.xsl new file mode 100644 index 00000000000..ae301aad802 --- /dev/null +++ b/src/webapp/resources/admin/analysis.xsl @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + SOLR Info + + + + SOLR + +

Solr Admin ()

+
+

Field Analysis

+ + Return to Admin Page +
+ + +
+ + + + +
+ + + + + + + + + + + + + + + + + +
+ Field name + + +
+ Field value (Index) +
+ verbose output +
+ highlight matches +
+ +
+ Field value (Query) +
+ verbose output +
+ +
+ + +
+
+
+ + +

Index Analyzer

+ +
+ +
+
+ + +
{ + + =, + + }
+
+ + +
+ + + + + + + + + + + + + + + + + +
texttypepositionstartend
+
+
+ + +

Query Analyzer

+ +
+ +
+
+ + +
{ + + =, + + }
+
+ + +
+ + + + + + + + + + + + + + + + + +
texttypepositionstartend
+
+
+ +
diff --git a/src/webapp/resources/admin/heading.jsp b/src/webapp/resources/admin/heading.jsp new file mode 100644 index 00000000000..38b4be82c5c --- /dev/null +++ b/src/webapp/resources/admin/heading.jsp @@ -0,0 +1,23 @@ +<%-- + Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed with + this work for additional information regarding copyright ownership. + The ASF licenses this file to You under the Apache License, Version 2.0 + (the "License"); you may not use this file except in compliance with + the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--%> + + <%= collectionName %> + <%= hostname %> + <%= port %> + <%= cwd %> + <%= solrHome %> + diff --git a/src/webapp/resources/admin/logging.jsp b/src/webapp/resources/admin/logging.jsp index d891e30c7c2..c8057d220c8 100644 --- a/src/webapp/resources/admin/logging.jsp +++ b/src/webapp/resources/admin/logging.jsp @@ -1,4 +1,4 @@ -<%@ page contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> +<%@ page contentType="text/xml; charset=utf-8" pageEncoding="UTF-8" language="java" %> <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -24,12 +24,11 @@ <%@ page import="java.util.logging.Level"%> <%@ page import="java.util.logging.LogManager"%> <%@ page import="java.util.logging.Logger"%> -<%@include file="header.jsp" %> + + + <% - - LogManager mgr = LogManager.getLogManager(); Logger log = SolrCore.log; - Logger parent = log.getParent(); while(parent != null) { log = parent; @@ -38,39 +37,12 @@ Level lvl = log.getLevel(); %> -
-

Solr Logging

- - - - - - - - - -
-

Log Level:

-
-<% if (lvl!=null) {%> - <%= lvl.toString() %>
+ + +<% if (lvl != null) {%> + <%= lvl.toString() %> <% } else { %> - null
+ null <% } %> -
- Set Level - - [ALL] - [CONFIG] - [FINE] - [FINER] - [FINEST] - [INFO] - [OFF] - [SEVERE] - [WARNING] -
-

- Return to Admin Page - - + + diff --git a/src/webapp/resources/admin/logging.xsl b/src/webapp/resources/admin/logging.xsl new file mode 100644 index 00000000000..3678ea5b83e --- /dev/null +++ b/src/webapp/resources/admin/logging.xsl @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + Solr Admin: Logging + + + + SOLR + + +

Solr Admin ()

+ + + +
+ + + + + +
+

Solr Logging

+ + + + + + + + + +
+

Log Level:

+
+ +
+ Set Level + + [ALL] + [CONFIG] + [FINE] + [FINER] + [FINEST] + [INFO] + [OFF] + [SEVERE] + [WARNING] +
+ +
+
diff --git a/src/webapp/resources/admin/meta.xsl b/src/webapp/resources/admin/meta.xsl new file mode 100644 index 00000000000..a1c608537f8 --- /dev/null +++ b/src/webapp/resources/admin/meta.xsl @@ -0,0 +1,32 @@ + + + + + + + : + cwd= SolrHome= + + + diff --git a/src/webapp/resources/admin/ping.jsp b/src/webapp/resources/admin/ping.jsp index 4b1dfa1b63b..37126faf262 100644 --- a/src/webapp/resources/admin/ping.jsp +++ b/src/webapp/resources/admin/ping.jsp @@ -1,4 +1,4 @@ -<%@ page contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> +<%@ page contentType="text/xml; charset=utf-8" pageEncoding="UTF-8" language="java" %> <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -17,10 +17,16 @@ --%> <%@ page import="org.apache.solr.core.SolrConfig, org.apache.solr.core.SolrCore, + org.apache.solr.util.XML, org.apache.solr.core.SolrException"%> <%@ page import="org.apache.solr.request.LocalSolrQueryRequest"%> <%@ page import="org.apache.solr.request.SolrQueryResponse"%> <%@ page import="java.util.StringTokenizer"%> + + + + + <% SolrCore core = SolrCore.getSolrCore(); @@ -40,12 +46,31 @@ SolrQueryResponse resp = new SolrQueryResponse(); try { core.execute(req,resp); - if (resp.getException() != null) { - response.sendError(500, SolrException.toStr(resp.getException())); + if (resp.getException() == null) { +// No need for explicit status in the body, when the standard HTTP +// response codes already transmit success/failure message +// out.println("200"); + } + else if (resp.getException() != null) { +// No need for explicit status in the body, when the standard HTTP +// response codes already transmit success/failure message +// out.println("500"); + out.println(""); + XML.escapeCharData(SolrException.toStr(resp.getException()), out); + out.println(""); + response.sendError(500); } } catch (Throwable t) { - response.sendError(500, SolrException.toStr(t)); +// No need for explicit status in the body, when the standard HTTP +// response codes already transmit success/failure message +// out.println("500"); + out.println(""); + XML.escapeCharData(SolrException.toStr(t), out); + out.println(""); + response.sendError(500); } finally { req.close(); } %> + + diff --git a/src/webapp/resources/admin/ping.xsl b/src/webapp/resources/admin/ping.xsl new file mode 100644 index 00000000000..364577bc69c --- /dev/null +++ b/src/webapp/resources/admin/ping.xsl @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + Solr Admin: Ping + + + + SOLR + + +

Solr Admin ()

+ + + +
+ + + + + + + + + +
+

Ping

+
+ +
+
+
diff --git a/src/webapp/resources/admin/threaddump.jsp b/src/webapp/resources/admin/threaddump.jsp index d53cdaaeeaa..1cb962dc0de 100644 --- a/src/webapp/resources/admin/threaddump.jsp +++ b/src/webapp/resources/admin/threaddump.jsp @@ -1,4 +1,4 @@ -<%@ page contentType="text/html; charset=utf-8" pageEncoding="UTF-8"%> +<%@ page contentType="text/xml; charset=utf-8" pageEncoding="UTF-8" language="java" %> <%-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with @@ -18,101 +18,87 @@ <%@ page import="java.lang.management.ManagementFactory, java.lang.management.ThreadMXBean, java.lang.management.ThreadInfo, - java.io.IOException"%> -<%@include file="header.jsp" %> + java.io.IOException, + org.apache.solr.util.XML"%> + + + <%! static ThreadMXBean tmbean = ManagementFactory.getThreadMXBean(); %> -
-

Thread Dump

- - - - - - - - - - - - - -
-<% - out.print(System.getProperty("java.vm.name") + - " " + System.getProperty("java.vm.version") + "
"); -%> -
+ + + + <%=System.getProperty("java.vm.version")%> + <%=System.getProperty("java.vm.name")%> + + + <%=tmbean.getThreadCount()%> + <%=tmbean.getPeakThreadCount()%> + <%=tmbean.getDaemonThreadCount()%> + <% long[] tids; ThreadInfo[] tinfos; - - out.print("Thread Count: current=" + tmbean.getThreadCount() + - " deamon=" + tmbean.getDaemonThreadCount() + - " peak=" + tmbean.getPeakThreadCount()); -%> -
-<% tids = tmbean.findMonitorDeadlockedThreads(); - if (tids == null) { - out.print("No deadlock found."); - } - else { - out.print("Deadlock found :-"); + if (tids != null) { + out.println(" "); tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); for (ThreadInfo ti : tinfos) { printThreadInfo(ti, out); } + out.println(" "); } %> -
<% - out.print("Full Thread Dump:
"); tids = tmbean.getAllThreadIds(); tinfos = tmbean.getThreadInfo(tids, Integer.MAX_VALUE); + out.println(" "); for (ThreadInfo ti : tinfos) { printThreadInfo(ti, out); } + out.println(" "); %> -
-

- Return to Admin Page - - + + <%! - static String INDENT = "     "; - static void printThreadInfo(ThreadInfo ti, JspWriter out) throws IOException { long tid = ti.getThreadId(); - StringBuilder sb = new StringBuilder("\"" + ti.getThreadName() + "\"" + - " Id=" + tid + - " in " + ti.getThreadState()); + out.println(" "); + out.println(" " + tid + ""); + out.print(" "); + XML.escapeCharData(ti.getThreadName(), out); + out.println(""); + out.println(" " + ti.getThreadState() + ""); if (ti.getLockName() != null) { - sb.append(" on lock=" + ti.getLockName()); + out.println(" " + ti.getLockName() + ""); } if (ti.isSuspended()) { - sb.append(" (suspended)"); + out.println(" "); } if (ti.isInNative()) { - sb.append(" (running in native)"); + out.println(" "); } if (tmbean.isThreadCpuTimeSupported()) { - sb.append(" total cpu time=" - +formatNanos(tmbean.getThreadCpuTime(tid))); - sb.append(" user time=" - +formatNanos(tmbean.getThreadUserTime(tid))); + out.println(" " + formatNanos(tmbean.getThreadCpuTime(tid)) + ""); + out.println(" " + formatNanos(tmbean.getThreadUserTime(tid)) + ""); } - out.print(sb.toString()+"
"); + if (ti.getLockOwnerName() != null) { - out.print(INDENT + " owned by " + ti.getLockOwnerName() + - " Id=" + ti.getLockOwnerId()+"
"); + out.println(" "); + out.println(" " + ti.getLockOwnerName() + ""); + out.println(" " + ti.getLockOwnerId() + ""); + out.println(" "); } + out.println(" "); for (StackTraceElement ste : ti.getStackTrace()) { - out.print(INDENT + "at " + ste.toString()+"
"); + out.print(" "); + XML.escapeCharData("at " + ste.toString(), out); + out.println(" "); } - out.print("
"); + out.println("
"); + out.println("
"); } static String formatNanos(long ns) { diff --git a/src/webapp/resources/admin/threaddump.xsl b/src/webapp/resources/admin/threaddump.xsl new file mode 100644 index 00000000000..999b05d009b --- /dev/null +++ b/src/webapp/resources/admin/threaddump.xsl @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + SOLR Info + + + + SOLR + +

Solr Admin ()

+

Thread Dump

+ + + +
+ + + + + + + + + + + + + Thread Count: + current=, + peak=, + daemon= + + + + +
Full Thread Dump:
+ + + + + '' + Id=, + + on lock=, + total cpu time= + user time= + + + + +
+ + + + + +
+
+ + +
+ +