All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.solr.client.solrj.util.ClientUtils Maven / Gradle / Ivy

/*
 * 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.client.solrj.util;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.SolrInputField;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.util.ContentStream;
import org.apache.solr.common.util.ContentStreamBase;
import org.apache.solr.common.util.XML;

/**
 * @since solr 1.3
 */
public class ClientUtils {
  // Standard Content types
  public static final String TEXT_XML = "application/xml; charset=UTF-8";
  public static final String TEXT_JSON = "application/json; charset=UTF-8";

  /** Take a string and make it an iterable ContentStream */
  public static Collection toContentStreams(
      final String str, final String contentType) {
    if (str == null) return null;

    ArrayList streams = new ArrayList<>(1);
    ContentStreamBase ccc = new ContentStreamBase.StringStream(str);
    ccc.setContentType(contentType);
    streams.add(ccc);
    return streams;
  }

  // ------------------------------------------------------------------------
  // ------------------------------------------------------------------------

  @SuppressWarnings({"unchecked"})
  public static void writeXML(SolrInputDocument doc, Writer writer) throws IOException {
    writer.write("");

    for (SolrInputField field : doc) {
      String name = field.getName();

      for (Object v : field) {
        String update = null;

        if (v instanceof SolrInputDocument) {
          writeVal(writer, name, v, null);
        } else if (v instanceof Map) {
          // currently only supports a single value
          for (Entry entry : ((Map) v).entrySet()) {
            update = entry.getKey().toString();
            v = entry.getValue();
            if (v instanceof Collection) {
              Collection values = (Collection) v;
              for (Object value : values) {
                writeVal(writer, name, value, update);
              }
            } else {
              writeVal(writer, name, v, update);
            }
          }
        } else {
          writeVal(writer, name, v, update);
        }
      }
    }

    if (doc.hasChildDocuments()) {
      for (SolrInputDocument childDocument : doc.getChildDocuments()) {
        writeXML(childDocument, writer);
      }
    }

    writer.write("");
  }

  private static void writeVal(Writer writer, String name, Object v, String update)
      throws IOException {
    if (v instanceof Date) {
      v = ((Date) v).toInstant().toString();
    } else if (v instanceof byte[]) {
      byte[] bytes = (byte[]) v;
      v = Base64.getEncoder().encodeToString(bytes);
    } else if (v instanceof ByteBuffer) {
      ByteBuffer bytes = (ByteBuffer) v;
      v =
          new String(
              Base64.getEncoder()
                  .encode(
                      ByteBuffer.wrap(
                          bytes.array(),
                          bytes.arrayOffset() + bytes.position(),
                          bytes.limit() - bytes.position()))
                  .array(),
              StandardCharsets.ISO_8859_1);
    }

    XML.Writable valWriter = null;
    if (v instanceof SolrInputDocument) {
      final SolrInputDocument solrDoc = (SolrInputDocument) v;
      valWriter = (writer1) -> writeXML(solrDoc, writer1);
    } else if (v != null) {
      final Object val = v;
      valWriter = (writer1) -> XML.escapeCharData(val.toString(), writer1);
    }

    if (update == null) {
      if (v != null) {
        XML.writeXML(writer, "field", valWriter, "name", name);
      }
    } else {
      if (v == null) {
        XML.writeXML(
            writer, "field", (XML.Writable) null, "name", name, "update", update, "null", true);
      } else {
        XML.writeXML(writer, "field", valWriter, "name", name, "update", update);
      }
    }
  }

  public static String toXML(SolrInputDocument doc) {
    StringWriter str = new StringWriter();
    try {
      writeXML(doc, str);
    } catch (Exception ex) {
    }
    return str.toString();
  }

  // ---------------------------------------------------------------------------------------

  /**
   * See: Lucene query
   * parser syntax for more information on Escaping Special Characters
   */
  // NOTE: its broken to link to any lucene-queryparser.jar docs, not in classpath!!!!!
  public static String escapeQueryChars(String s) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < s.length(); i++) {
      char c = s.charAt(i);
      // These characters are part of the query syntax and must be escaped
      if (c == '\\'
          || c == '+'
          || c == '-'
          || c == '!'
          || c == '('
          || c == ')'
          || c == ':'
          || c == '^'
          || c == '['
          || c == ']'
          || c == '\"'
          || c == '{'
          || c == '}'
          || c == '~'
          || c == '*'
          || c == '?'
          || c == '|'
          || c == '&'
          || c == ';'
          || c == '/'
          || Character.isWhitespace(c)) {
        sb.append('\\');
      }
      sb.append(c);
    }
    return sb.toString();
  }

  /**
   * Returns the value encoded properly so it can be appended after a
   *
   * 
name=
* * local-param. */ public static String encodeLocalParamVal(String val) { int len = val.length(); int i = 0; if (len > 0 && val.charAt(0) != '$') { for (; i < len; i++) { char ch = val.charAt(i); if (Character.isWhitespace(ch) || ch == '}') break; } } if (i >= len) return val; // We need to enclose in quotes... but now we need to escape StringBuilder sb = new StringBuilder(val.length() + 4); sb.append('\''); for (i = 0; i < len; i++) { char ch = val.charAt(i); if (ch == '\'') { sb.append('\\'); } sb.append(ch); } sb.append('\''); return sb.toString(); } /** * Constructs a slices map from a collection of slices and handles disambiguation if multiple * collections are being queried simultaneously */ public static void addSlices( Map target, String collectionName, Collection slices, boolean multiCollection) { for (Slice slice : slices) { String key = slice.getName(); if (multiCollection) key = collectionName + "_" + key; target.put(key, slice); } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy