/* * 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. */ package org.apache.solr.response; import java.io.Writer; import java.io.IOException; import org.apache.solr.common.util.NamedList; import org.apache.solr.request.SolrQueryRequest; public class PythonResponseWriter implements QueryResponseWriter { static String CONTENT_TYPE_PYTHON_ASCII="text/x-python;charset=US-ASCII"; @Override public void init(NamedList n) { /* NOOP */ } @Override public void write(Writer writer, SolrQueryRequest req, SolrQueryResponse rsp) throws IOException { PythonWriter w = new PythonWriter(writer, req, rsp); try { w.writeResponse(); } finally { w.close(); } } @Override public String getContentType(SolrQueryRequest request, SolrQueryResponse response) { return CONTENT_TYPE_TEXT_ASCII; } } class PythonWriter extends NaNFloatWriter { @Override protected String getNaN() { return "float('NaN')"; } @Override protected String getInf() { return "float('Inf')"; } 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 its eval(), so we must escape them. StringBuilder sb = new StringBuilder(val.length()); boolean needUnicode=false; for (int i=0; i<val.length(); i++) { char ch = val.charAt(i); switch(ch) { case '\'': case '\\': sb.append('\\'); sb.append(ch); break; case '\r': sb.append("\\r"); break; case '\n': sb.append("\\n"); break; case '\t': sb.append("\\t"); break; default: // we don't strictly have to escape these chars, but it will probably increase // portability to stick to visible ascii if (ch<' ' || ch>127) { unicodeEscape(sb, ch); needUnicode=true; } else { sb.append(ch); } } } if (needUnicode) { writer.write('u'); } writer.write('\''); 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 its 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; i<val.length(); i++) { char ch = val.charAt(i); switch(ch) { case '\'': case '\\': writer.write('\\'); writer.write(ch); break; case '\r': writer.write("\\r"); break; case '\n': writer.write("\\n"); break; default: // we don't strictly have to escape these chars, but it will probably increase // portability to stick to visible ascii if (ch<' ' || ch>127) { unicodeChar(ch); } else { writer.write(ch); } } } } else { writer.write(val); } writer.write('\''); } */ }