From bd4e7a8c03c891abac0e05ffe3e92f78eeb25282 Mon Sep 17 00:00:00 2001 From: Yonik Seeley Date: Sat, 11 Aug 2007 03:32:02 +0000 Subject: [PATCH] SOLR-196: php response writers git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@564829 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 5 + example/solr/conf/solrconfig.xml | 2 + .../solr/request/JSONResponseWriter.java | 254 +++++------------- .../solr/request/PythonResponseWriter.java | 96 +++++++ .../solr/request/RubyResponseWriter.java | 43 +++ 5 files changed, 217 insertions(+), 183 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d6a72cfbd37..a280ac52d7b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -117,6 +117,11 @@ New Features computed for ranges of size facet.date.gap (a DateMath expression) between facet.date.start and facet.date.end. (hossman) +22. SOLR-196: A PHP serialized "phps" response writer that returns a + serialized array that can be used with the PHP function unserialize, + and a PHP response writer "php" that may be used by eval. + (Nick Jenkin, Paul Borgermans, Pieter Berkel via yonik) + Changes in runtime behavior Optimizations diff --git a/example/solr/conf/solrconfig.xml b/example/solr/conf/solrconfig.xml index f615fcefd46..242feea8327 100755 --- a/example/solr/conf/solrconfig.xml +++ b/example/solr/conf/solrconfig.xml @@ -495,6 +495,8 @@ + + --> diff --git a/src/java/org/apache/solr/request/JSONResponseWriter.java b/src/java/org/apache/solr/request/JSONResponseWriter.java index b99734844cd..f4797da7fba 100644 --- a/src/java/org/apache/solr/request/JSONResponseWriter.java +++ b/src/java/org/apache/solr/request/JSONResponseWriter.java @@ -96,7 +96,7 @@ class JSONWriter extends TextResponseWriter { */ protected void writeNamedListAsMapMangled(String name, NamedList val) throws IOException { int sz = val.size(); - writer.write('{'); + writeMapOpener(sz); incLevel(); // In JSON objects (maps) we can't have null keys or duplicates... @@ -121,7 +121,7 @@ class JSONWriter extends TextResponseWriter { first=false; repeats.put(key,0); } else { - writer.write(','); + writeMapSeparator(); Integer repeatCount = repeats.get(key); if (repeatCount==null) { @@ -145,7 +145,7 @@ class JSONWriter extends TextResponseWriter { } decLevel(); - writer.write('}'); + writeMapCloser(); } /** Represents a NamedList directly as a JSON Object (essentially a Map) @@ -154,12 +154,12 @@ class JSONWriter extends TextResponseWriter { */ protected void writeNamedListAsMapWithDups(String name, NamedList val) throws IOException { int sz = val.size(); - writer.write('{'); + writeMapOpener(sz); incLevel(); for (int i=0; i ["a",1,"b",2,null,3] protected void writeNamedListAsFlat(String name, NamedList val) throws IOException { int sz = val.size(); - writer.write('['); + writeArrayOpener(sz); incLevel(); for (int i=0; i fields; MultiValueField(SchemaField sfield, Fieldable firstVal) { @@ -303,7 +303,7 @@ class JSONWriter extends TextResponseWriter { } public void writeDoc(String name, Collection fields, Set returnFields, Map pseudoFields) throws IOException { - writer.write('{'); + writeMapOpener(-1); // no trivial way to determine map size incLevel(); HashMap multi = new HashMap(); @@ -332,7 +332,7 @@ class JSONWriter extends TextResponseWriter { if (first) { first=false; } else { - writer.write(','); + writeMapSeparator(); } indent(); writeKey(fname,true); @@ -344,7 +344,7 @@ class JSONWriter extends TextResponseWriter { if (first) { first=false; } else { - writer.write(','); + writeMapSeparator(); } indent(); @@ -357,7 +357,7 @@ class JSONWriter extends TextResponseWriter { indentArrElems = (mvf.sfield.getType() instanceof TextField); } - writer.write('['); + writeArrayOpener(-1); // no trivial way to determine array size boolean firstArrElem=true; incLevel(); @@ -365,12 +365,12 @@ class JSONWriter extends TextResponseWriter { if (firstArrElem) { firstArrElem=false; } else { - writer.write(','); + writeArraySeparator(); } if (indentArrElems) indent(); mvf.sfield.write(this, null, ff); } - writer.write(']'); + writeArrayCloser(); decLevel(); } @@ -379,7 +379,7 @@ class JSONWriter extends TextResponseWriter { } decLevel(); - writer.write('}'); + writeMapCloser(); } // reusable map to store the "score" pseudo-field. @@ -406,23 +406,23 @@ class JSONWriter extends TextResponseWriter { int sz=ids.size(); - writer.write('{'); + writeMapOpener(includeScore ? 4 : 3); incLevel(); writeKey("numFound",false); writeInt(null,ids.matches()); - writer.write(','); + writeMapSeparator(); writeKey("start",false); writeInt(null,ids.offset()); if (includeScore) { - writer.write(','); + writeMapSeparator(); writeKey("maxScore",false); writeFloat(null,ids.maxScore()); } - writer.write(','); + writeMapSeparator(); // indent(); writeKey("docs",false); - writer.write('['); + writeArrayOpener(sz); incLevel(); boolean first=true; @@ -436,13 +436,13 @@ class JSONWriter extends TextResponseWriter { if (first) { first=false; } else { - writer.write(','); + writeArraySeparator(); } indent(); writeDoc(null, doc, fields, (includeScore ? iterator.score() : 0.0f), includeScore); } decLevel(); - writer.write(']'); + writeArrayCloser(); if (otherFields !=null) { writeMap(null, otherFields, true, false); @@ -450,11 +450,39 @@ class JSONWriter extends TextResponseWriter { decLevel(); indent(); - writer.write('}'); + writeMapCloser(); } + // + // Data structure tokens + // NOTE: a positive size paramater indicates the number of elements + // contained in an array or map, a negative value indicates + // that the size could not be reliably determined. + // + + public void writeMapOpener(int size) throws IOException, IllegalArgumentException { + writer.write('{'); + } + + public void writeMapSeparator() throws IOException { + writer.write(','); + } + public void writeMapCloser() throws IOException { + writer.write('}'); + } + + public void writeArrayOpener(int size) throws IOException, IllegalArgumentException { + writer.write('['); + } + + public void writeArraySeparator() throws IOException { + writer.write(','); + } + public void writeArrayCloser() throws IOException { + writer.write(']'); + } public void writeStr(String name, String val, boolean needsEscaping) throws IOException { // it might be more efficient to use a stringbuilder or write substrings @@ -508,7 +536,7 @@ class JSONWriter extends TextResponseWriter { public void writeMap(String name, Map val, boolean excludeOuter, boolean isFirstVal) throws IOException { if (!excludeOuter) { - writer.write('{'); + writeMapOpener(val.size()); incLevel(); isFirstVal=true; } @@ -523,7 +551,7 @@ class JSONWriter extends TextResponseWriter { if (isFirstVal) { isFirstVal=false; } else { - writer.write(','); + writeMapSeparator(); } if (doIndent) indent(); @@ -533,7 +561,7 @@ class JSONWriter extends TextResponseWriter { if (!excludeOuter) { decLevel(); - writer.write('}'); + writeMapCloser(); } } @@ -542,19 +570,19 @@ class JSONWriter extends TextResponseWriter { } public void writeArray(String name, Iterator val) throws IOException { - writer.write('['); + writeArrayOpener(-1); // no trivial way to determine array size incLevel(); boolean first=true; while( val.hasNext() ) { if( !first ) indent(); writeVal(null, val.next()); if( val.hasNext() ) { - writer.write(','); + writeArraySeparator(); } first=false; } decLevel(); - writer.write(']'); + writeArrayCloser(); } // @@ -657,143 +685,3 @@ class JSONWriter extends TextResponseWriter { } } - -class PythonWriter extends JSONWriter { - public PythonWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp) { - super(writer, req, rsp); - } - - @Override - public void writeNull(String name) throws IOException { - writer.write("None"); - } - - @Override - public void writeBool(String name, boolean val) throws IOException { - writer.write(val ? "True" : "False"); - } - - @Override - public void writeBool(String name, String val) throws IOException { - writeBool(name,val.charAt(0)=='t'); - } - - /* optionally use a unicode python string if necessary */ - @Override - public void writeStr(String name, String val, boolean needsEscaping) throws IOException { - if (!needsEscaping) { - writer.write('\''); - writer.write(val); - writer.write('\''); - return; - } - - // use python unicode strings... - // python doesn't tolerate newlines in strings in it's eval(), so we must escape them. - - StringBuilder sb = new StringBuilder(val.length()); - boolean needUnicode=false; - - for (int i=0; i127) { - unicodeEscape(sb, ch); - needUnicode=true; - } else { - sb.append(ch); - } - } - } - - writer.write( needUnicode ? "u'" : "'"); - writer.append(sb); - writer.write('\''); - } - - /* - old version that always used unicode - public void writeStr(String name, String val, boolean needsEscaping) throws IOException { - // use python unicode strings... - // python doesn't tolerate newlines in strings in it's eval(), so we must escape them. - writer.write("u'"); - // it might be more efficient to use a stringbuilder or write substrings - // if writing chars to the stream is slow. - if (needsEscaping) { - for (int i=0; i127) { - unicodeChar(ch); - } else { - writer.write(ch); - } - } - } - } else { - writer.write(val); - } - writer.write('\''); - } - */ - -} - - -class RubyWriter extends JSONWriter { - public RubyWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp) { - super(writer, req, rsp); - } - - @Override - public void writeNull(String name) throws IOException { - writer.write("nil"); - } - - @Override - protected void writeKey(String fname, boolean needsEscaping) throws IOException { - writeStr(null, fname, needsEscaping); - writer.write("=>"); - } - - @Override - public void writeStr(String name, String val, boolean needsEscaping) throws IOException { - // Ruby doesn't do unicode escapes... so let the servlet container write raw UTF-8 - // bytes into the string. - // - // Use single quoted strings for safety since no evaluation is done within them. - // Also, there are very few escapes recognized in a single quoted string, so - // only escape the backslash and single quote. - writer.write('\''); - // it might be more efficient to use a stringbuilder or write substrings - // if writing chars to the stream is slow. - if (needsEscaping) { - for (int i=0; i127) { + unicodeEscape(sb, ch); + needUnicode=true; + } else { + sb.append(ch); + } + } + } + + writer.write( needUnicode ? "u'" : "'"); + writer.append(sb); + writer.write('\''); + } + + /* + old version that always used unicode + public void writeStr(String name, String val, boolean needsEscaping) throws IOException { + // use python unicode strings... + // python doesn't tolerate newlines in strings in it's eval(), so we must escape them. + writer.write("u'"); + // it might be more efficient to use a stringbuilder or write substrings + // if writing chars to the stream is slow. + if (needsEscaping) { + for (int i=0; i127) { + unicodeChar(ch); + } else { + writer.write(ch); + } + } + } + } else { + writer.write(val); + } + writer.write('\''); + } + */ + +} diff --git a/src/java/org/apache/solr/request/RubyResponseWriter.java b/src/java/org/apache/solr/request/RubyResponseWriter.java index 00f143226e0..8864c49da55 100644 --- a/src/java/org/apache/solr/request/RubyResponseWriter.java +++ b/src/java/org/apache/solr/request/RubyResponseWriter.java @@ -37,3 +37,46 @@ public class RubyResponseWriter implements QueryResponseWriter { return CONTENT_TYPE_TEXT_UTF8; } } + +class RubyWriter extends JSONWriter { + public RubyWriter(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp) { + super(writer, req, rsp); + } + + @Override + public void writeNull(String name) throws IOException { + writer.write("nil"); + } + + @Override + protected void writeKey(String fname, boolean needsEscaping) throws IOException { + writeStr(null, fname, needsEscaping); + writer.write("=>"); + } + + @Override + public void writeStr(String name, String val, boolean needsEscaping) throws IOException { + // Ruby doesn't do unicode escapes... so let the servlet container write raw UTF-8 + // bytes into the string. + // + // Use single quoted strings for safety since no evaluation is done within them. + // Also, there are very few escapes recognized in a single quoted string, so + // only escape the backslash and single quote. + writer.write('\''); + // it might be more efficient to use a stringbuilder or write substrings + // if writing chars to the stream is slow. + if (needsEscaping) { + for (int i=0; i