| /* |
| * 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.request.schema; |
| |
| import java.io.IOException; |
| import java.util.Collection; |
| import java.util.Collections; |
| import java.util.Iterator; |
| import java.util.LinkedList; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.apache.solr.client.solrj.SolrClient; |
| import org.apache.solr.client.solrj.response.schema.SchemaResponse; |
| import org.apache.solr.common.params.SolrParams; |
| import org.apache.solr.common.util.ContentStream; |
| import org.apache.solr.common.util.ContentStreamBase; |
| import org.apache.solr.common.util.NamedList; |
| import org.noggit.CharArr; |
| import org.noggit.JSONWriter; |
| |
| /** |
| * <p>This class offers access to the operations exposed by the Solr Schema API.</p> |
| * <p>Most of the operations of this class offer a very abstract interface avoiding |
| * in this manner eventual changes due to Solr Schema API updates. On the other |
| * hand, the creation of request parameters for creating new fields or field types |
| * can be tedious because it is not strongly typed (the user has to build on his own |
| * a {@link NamedList} argument containing the field/field type properties).</p> |
| * <p>The class does not currently offer explicit support for the Schema API operations exposed |
| * through Managed Resources, but such operations can be built with little effort manually |
| * based on this class within the client applications.</p> |
| * <p>This class is experimental and it is subject to change.</p> |
| * |
| * @see <a href="https://lucene.apache.org/solr/guide/schema-api.html">Solr Schema API</a> |
| * @see <a href="https://lucene.apache.org/solr/guide/managed-resources.html">Solr managed resources</a> |
| * @since solr 5.3 |
| */ |
| public class SchemaRequest extends AbstractSchemaRequest<SchemaResponse> { |
| |
| /** |
| * Default constructor. |
| * It can be used to retrieve the entire schema. |
| * |
| * @see #process(SolrClient) |
| */ |
| public SchemaRequest() { |
| this(null); |
| } |
| |
| public SchemaRequest(SolrParams q) { |
| super(METHOD.GET, "/schema", q); |
| } |
| |
| private static NamedList<Object> createAddFieldTypeNamedList(FieldTypeDefinition fieldTypeDefinition) { |
| final NamedList<Object> addFieldTypeNamedList = new NamedList<>(); |
| addFieldTypeNamedList.addAll(fieldTypeDefinition.getAttributes()); |
| AnalyzerDefinition analyzerDefinition = fieldTypeDefinition.getAnalyzer(); |
| if (analyzerDefinition != null) { |
| NamedList<Object> analyzerNamedList = createAnalyzerNamedList(analyzerDefinition); |
| addFieldTypeNamedList.add("analyzer", analyzerNamedList); |
| } |
| AnalyzerDefinition indexAnalyzerDefinition = fieldTypeDefinition.getIndexAnalyzer(); |
| if (indexAnalyzerDefinition != null) { |
| NamedList<Object> indexAnalyzerNamedList = createAnalyzerNamedList(indexAnalyzerDefinition); |
| addFieldTypeNamedList.add("indexAnalyzer", indexAnalyzerNamedList); |
| } |
| AnalyzerDefinition queryAnalyzerDefinition = fieldTypeDefinition.getQueryAnalyzer(); |
| if (queryAnalyzerDefinition != null) { |
| NamedList<Object> queryAnalyzerNamedList = createAnalyzerNamedList(queryAnalyzerDefinition); |
| addFieldTypeNamedList.add("queryAnalyzer", queryAnalyzerNamedList); |
| } |
| AnalyzerDefinition multiTermAnalyzerDefinition = fieldTypeDefinition.getMultiTermAnalyzer(); |
| if (multiTermAnalyzerDefinition != null) { |
| NamedList<Object> multiTermAnalyzerNamedList = createAnalyzerNamedList(multiTermAnalyzerDefinition); |
| addFieldTypeNamedList.add("multiTermAnalyzer", multiTermAnalyzerNamedList); |
| } |
| Map<String, Object> similarityAttributes = fieldTypeDefinition.getSimilarity(); |
| if (similarityAttributes != null && !similarityAttributes.isEmpty()) { |
| addFieldTypeNamedList.add("similarity", new NamedList<>(similarityAttributes)); |
| } |
| |
| return addFieldTypeNamedList; |
| } |
| |
| private static NamedList<Object> createAnalyzerNamedList(AnalyzerDefinition analyzerDefinition) { |
| NamedList<Object> analyzerNamedList = new NamedList<>(); |
| Map<String, Object> analyzerAttributes = analyzerDefinition.getAttributes(); |
| if (analyzerAttributes != null) |
| analyzerNamedList.addAll(analyzerAttributes); |
| List<Map<String, Object>> charFiltersAttributes = analyzerDefinition.getCharFilters(); |
| if (charFiltersAttributes != null) { |
| List<NamedList<Object>> charFiltersList = new LinkedList<>(); |
| for (Map<String, Object> charFilterAttributes : charFiltersAttributes) |
| charFiltersList.add(new NamedList<>(charFilterAttributes)); |
| analyzerNamedList.add("charFilters", charFiltersList); |
| } |
| Map<String, Object> tokenizerAttributes = analyzerDefinition.getTokenizer(); |
| if (tokenizerAttributes != null) { |
| analyzerNamedList.add("tokenizer", new NamedList<>(tokenizerAttributes)); |
| } |
| List<Map<String, Object>> filtersAttributes = analyzerDefinition.getFilters(); |
| if (filtersAttributes != null) { |
| List<NamedList<Object>> filtersList = new LinkedList<>(); |
| for (Map<String, Object> filterAttributes : filtersAttributes) |
| filtersList.add(new NamedList<>(filterAttributes)); |
| analyzerNamedList.add("filters", filtersList); |
| } |
| return analyzerNamedList; |
| } |
| |
| private static NamedList<Object> createAddFieldNamedList(Map<String, Object> fieldAttributes) { |
| final NamedList<Object> addFieldProps = new NamedList<>(); |
| if (fieldAttributes != null) addFieldProps.addAll(fieldAttributes); |
| return addFieldProps; |
| } |
| |
| @Override |
| protected SchemaResponse createResponse(SolrClient client) { |
| return new SchemaResponse(); |
| } |
| |
| /** |
| * Schema API request class that can be used to retrieve the name of the schema. |
| */ |
| public static class SchemaName extends AbstractSchemaRequest<SchemaResponse.SchemaNameResponse> { |
| public SchemaName() { |
| this(null); |
| } |
| |
| public SchemaName(SolrParams q) { |
| super(METHOD.GET, "/schema/name", q); |
| } |
| |
| @Override |
| protected SchemaResponse.SchemaNameResponse createResponse(SolrClient client) { |
| return new SchemaResponse.SchemaNameResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that can be used to retrieve the version |
| * of the schema for the specified collection. |
| */ |
| public static class SchemaVersion extends AbstractSchemaRequest<SchemaResponse.SchemaVersionResponse> { |
| public SchemaVersion() { |
| this(null); |
| } |
| |
| public SchemaVersion(SolrParams q) { |
| super(METHOD.GET, "/schema/version", q); |
| } |
| |
| @Override |
| protected SchemaResponse.SchemaVersionResponse createResponse(SolrClient client) { |
| return new SchemaResponse.SchemaVersionResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request class that lists the field definitions contained in the schema. |
| */ |
| public static class Fields extends AbstractSchemaRequest<SchemaResponse.FieldsResponse> { |
| public Fields() { |
| this(null); |
| } |
| |
| public Fields(SolrParams q) { |
| super(METHOD.GET, "/schema/fields", q); |
| } |
| |
| @Override |
| protected SchemaResponse.FieldsResponse createResponse(SolrClient client) { |
| return new SchemaResponse.FieldsResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that lists the field definition for the specified field |
| * contained in the schema. |
| */ |
| public static class Field extends AbstractSchemaRequest<SchemaResponse.FieldResponse> { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldName the name of the field for which the definition is to be retrieved |
| */ |
| public Field(String fieldName) { |
| this(fieldName, null); |
| } |
| |
| public Field(String fieldName, SolrParams q) { |
| super(METHOD.GET, "/schema/fields/" + fieldName, q); |
| } |
| |
| @Override |
| protected SchemaResponse.FieldResponse createResponse(SolrClient client) { |
| return new SchemaResponse.FieldResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that lists the dynamic field definitions contained in the schema. |
| */ |
| public static class DynamicFields extends AbstractSchemaRequest<SchemaResponse.DynamicFieldsResponse> { |
| |
| public DynamicFields() { |
| this(null); |
| } |
| |
| public DynamicFields(SolrParams q) { |
| super(METHOD.GET, "/schema/dynamicfields", q); |
| } |
| |
| @Override |
| protected SchemaResponse.DynamicFieldsResponse createResponse(SolrClient client) { |
| return new SchemaResponse.DynamicFieldsResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that lists the dynamic field definition for the specified field |
| * contained in the schema. |
| */ |
| public static class DynamicField extends AbstractSchemaRequest<SchemaResponse.DynamicFieldResponse> { |
| /** |
| * Creates a new instance of the class. |
| * |
| * @param dynamicFieldName the name of the dynamic field for which the definition is to be retrieved |
| */ |
| public DynamicField(String dynamicFieldName) { |
| this(dynamicFieldName, null); |
| } |
| |
| public DynamicField(String dynamicFieldName, SolrParams q) { |
| super(METHOD.GET, "/schema/dynamicfields/" + dynamicFieldName); |
| } |
| |
| @Override |
| protected SchemaResponse.DynamicFieldResponse createResponse(SolrClient client) { |
| return new SchemaResponse.DynamicFieldResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that lists the types definitions contained |
| * in the schema. |
| */ |
| public static class FieldTypes extends AbstractSchemaRequest<SchemaResponse.FieldTypesResponse> { |
| public FieldTypes() { |
| this(null); |
| } |
| |
| public FieldTypes(SolrParams q) { |
| super(METHOD.GET, "/schema/fieldtypes"); |
| } |
| |
| @Override |
| protected SchemaResponse.FieldTypesResponse createResponse(SolrClient client) { |
| return new SchemaResponse.FieldTypesResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that retrieves the type definitions for the specified field |
| * type contained in the schema. |
| */ |
| public static class FieldType extends AbstractSchemaRequest<SchemaResponse.FieldTypeResponse> { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldTypeName the name of the field type for which the definition is to be retrieved |
| */ |
| public FieldType(String fieldTypeName) { |
| this(fieldTypeName, null); |
| } |
| |
| public FieldType(String fieldTypeName, SolrParams q) { |
| super(METHOD.GET, "/schema/fieldtypes/" + fieldTypeName, q); |
| } |
| |
| @Override |
| protected SchemaResponse.FieldTypeResponse createResponse(SolrClient client) { |
| return new SchemaResponse.FieldTypeResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that retrieves the source and destination of |
| * each copy field in the schema. |
| */ |
| public static class CopyFields extends AbstractSchemaRequest<SchemaResponse.CopyFieldsResponse> { |
| public CopyFields() { |
| this(null); |
| } |
| |
| public CopyFields(SolrParams q) { |
| super(METHOD.GET, "/schema/copyfields", q); |
| } |
| |
| @Override |
| protected SchemaResponse.CopyFieldsResponse createResponse(SolrClient client) { |
| return new SchemaResponse.CopyFieldsResponse(); |
| } |
| } |
| |
| /** |
| * Schema API request that retrieves the field name that is defined as |
| * the uniqueKey for the index of the specified collection. |
| */ |
| public static class UniqueKey extends AbstractSchemaRequest<SchemaResponse.UniqueKeyResponse> { |
| public UniqueKey() { |
| this(null); |
| } |
| |
| public UniqueKey(SolrParams q) { |
| super(METHOD.GET, "/schema/uniquekey", q); |
| } |
| |
| @Override |
| protected SchemaResponse.UniqueKeyResponse createResponse(SolrClient client) { |
| return new SchemaResponse.UniqueKeyResponse(); |
| } |
| } |
| |
| /** |
| * Retrieves the class name of the global similarity defined (if any) in the schema. |
| */ |
| public static class GlobalSimilarity extends AbstractSchemaRequest<SchemaResponse.GlobalSimilarityResponse> { |
| public GlobalSimilarity() { |
| this(null); |
| } |
| |
| public GlobalSimilarity(SolrParams q) { |
| super(METHOD.GET, "/schema/similarity", q); |
| } |
| |
| @Override |
| protected SchemaResponse.GlobalSimilarityResponse createResponse(SolrClient client) { |
| return new SchemaResponse.GlobalSimilarityResponse(); |
| } |
| } |
| |
| /** |
| * Adds a new field definition to the schema. |
| * If the field already exists, the method {@link #process(SolrClient, String)} will fail. |
| * Note that the request will be translated to json, so please use concrete values (e.g. : true, 1) |
| * instead of their string representation (e.g. : "true", "1") for the field attributes expecting |
| * boolean or number values. |
| */ |
| public static class AddField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldAttributes field type attributes that can be used to enrich the field definition. |
| * @see <a href="https://lucene.apache.org/solr/guide/defining-fields.html">Defining Solr fields</a> |
| */ |
| public AddField(Map<String, Object> fieldAttributes) { |
| this(fieldAttributes, null); |
| } |
| |
| public AddField(Map<String, Object> fieldAttributes, SolrParams q) { |
| super(createRequestParameters(fieldAttributes), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(Map<String, Object> fieldAttributes) { |
| final NamedList<Object> addFieldParameters = createAddFieldNamedList(fieldAttributes); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("add-field", addFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Replaces a field's definition. Note that the full definition for a field must be supplied - this command |
| * will not partially modify a field's definition. If the field does not exist in the schema the method call |
| * {@link #process(SolrClient, String)} will fail. |
| * |
| * @see <a href="https://lucene.apache.org/solr/guide/defining-fields.html">Defining Solr fields</a> |
| */ |
| public static class ReplaceField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldAttributes field type attributes that can be used to enrich the field definition. |
| */ |
| public ReplaceField(Map<String, Object> fieldAttributes) { |
| this(fieldAttributes, null); |
| } |
| |
| public ReplaceField(Map<String, Object> fieldAttributes, SolrParams q) { |
| super(createRequestParameters(fieldAttributes), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(Map<String, Object> fieldAttributes) { |
| final NamedList<Object> replaceFieldParameters = createAddFieldNamedList(fieldAttributes); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("replace-field", replaceFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Removes a field definition from the schema. If the field does not exist in the schema, |
| * or if the field is the source or destination of a copy field rule the method call |
| * {@link #process(SolrClient, String)} will fail. |
| */ |
| public static class DeleteField extends SingleUpdate { |
| |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldName the name of the new field to be removed |
| */ |
| public DeleteField(String fieldName) { |
| this(fieldName, null); |
| } |
| |
| public DeleteField(String fieldName, SolrParams q) { |
| super(createRequestParameters(fieldName), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(String fieldName) { |
| final NamedList<Object> deleteFieldParameters = new NamedList<>(); |
| deleteFieldParameters.add("name", fieldName); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("delete-field", deleteFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Adds a new dynamic field rule to the schema of the specified collection. |
| * |
| * @see <a href="https://lucene.apache.org/solr/guide/defining-fields.html">Defining Solr fields</a> |
| * @see <a href="https://lucene.apache.org/solr/guide/dynamic-fields.html">Solr dynamic fields</a> |
| */ |
| public static class AddDynamicField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldAttributes field type attributes that can be used to enrich the field definition. |
| */ |
| public AddDynamicField(Map<String, Object> fieldAttributes) { |
| this(fieldAttributes, null); |
| } |
| |
| public AddDynamicField(Map<String, Object> fieldAttributes, SolrParams q) { |
| super(createRequestParameters(fieldAttributes), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(Map<String, Object> fieldAttributes) { |
| final NamedList<Object> addDynamicFieldParameters = createAddFieldNamedList(fieldAttributes); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("add-dynamic-field", addDynamicFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Replaces a dynamic field rule in the schema of the specified collection. |
| * Note that the full definition for a dynamic field rule must be supplied - this command |
| * will not partially modify a dynamic field rule's definition. |
| * If the dynamic field rule does not exist in the schema the method call |
| * {@link #process(SolrClient, String)} will fail. |
| */ |
| public static class ReplaceDynamicField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param dynamicFieldAttributes field type attributes that can be used to enrich the field definition. |
| * @see <a href="https://lucene.apache.org/solr/guide/defining-fields.html">Defining Solr fields</a> |
| * @see <a href="https://lucene.apache.org/solr/guide/dynamic-fields.html">Solr dynamic fields</a> |
| */ |
| public ReplaceDynamicField(Map<String, Object> dynamicFieldAttributes) { |
| this(dynamicFieldAttributes, null); |
| } |
| |
| public ReplaceDynamicField(Map<String, Object> dynamicFieldAttributes, SolrParams q) { |
| super(createRequestParameters(dynamicFieldAttributes), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters( |
| Map<String, Object> dynamicFieldAttributes) { |
| final NamedList<Object> replaceDynamicFieldParameters = createAddFieldNamedList(dynamicFieldAttributes); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("replace-dynamic-field", replaceDynamicFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Deletes a dynamic field rule from your schema. If the dynamic field rule does not exist in the schema, |
| * or if the schema contains a copy field rule with a target or destination that matches only this |
| * dynamic field rule the method call {@link #process(SolrClient, String)} will fail. |
| */ |
| public static class DeleteDynamicField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param dynamicFieldName the name of the dynamic field to be removed |
| */ |
| public DeleteDynamicField(String dynamicFieldName) { |
| this(dynamicFieldName, null); |
| } |
| |
| public DeleteDynamicField(String fieldName, SolrParams q) { |
| super(createRequestParameters(fieldName), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(String fieldName) { |
| final NamedList<Object> deleteDynamicFieldParameters = new NamedList<>(); |
| deleteDynamicFieldParameters.add("name", fieldName); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("delete-dynamic-field", deleteDynamicFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Update request used to add a new field type to the schema. |
| */ |
| public static class AddFieldType extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldTypeDefinition the field type definition |
| * @see <a href="https://lucene.apache.org/solr/guide/solr-field-types.html">Solr field types</a> |
| */ |
| public AddFieldType(FieldTypeDefinition fieldTypeDefinition) { |
| this(fieldTypeDefinition, null); |
| } |
| |
| public AddFieldType(FieldTypeDefinition fieldTypeDefinition, SolrParams q) { |
| super(createRequestParameters(fieldTypeDefinition), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(FieldTypeDefinition fieldTypeDefinition) { |
| final NamedList<Object> addFieldTypeParameters = createAddFieldTypeNamedList(fieldTypeDefinition); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("add-field-type", addFieldTypeParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Replaces a field type in schema belonging to the schema of the specified collection. |
| * Note that the full definition for a field type must be supplied- this command will not partially modify |
| * a field type's definition. If the field type does not exist in the schema the |
| * method call {@link #process(SolrClient, String)} will fail. |
| */ |
| public static class ReplaceFieldType extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldTypeDefinition the field type definition |
| * @see <a href="https://lucene.apache.org/solr/guide/solr-field-types.html">Solr field types</a> |
| */ |
| public ReplaceFieldType(FieldTypeDefinition fieldTypeDefinition) { |
| this(fieldTypeDefinition, null); |
| } |
| |
| public ReplaceFieldType(FieldTypeDefinition fieldTypeDefinition, SolrParams q) { |
| super(createRequestParameters(fieldTypeDefinition), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(FieldTypeDefinition fieldTypeDefinition) { |
| final NamedList<Object> replaceFieldTypeParameters = createAddFieldTypeNamedList(fieldTypeDefinition); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("replace-field-type", replaceFieldTypeParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Removes a field type from the schema of the specified collection. |
| * If the field type does not exist in the schema, or if any |
| * field or dynamic field rule in the schema uses the field type, the |
| * method call {@link #process(SolrClient, String)} will fail. |
| */ |
| public static class DeleteFieldType extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param fieldTypeName the name of the field type to be removed |
| */ |
| public DeleteFieldType(String fieldTypeName) { |
| this(fieldTypeName, null); |
| } |
| |
| public DeleteFieldType(String fieldTypeName, SolrParams q) { |
| super(createRequestParameters(fieldTypeName), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(String fieldTypeName) { |
| final NamedList<Object> deleteFieldTypeParameters = new NamedList<>(); |
| deleteFieldTypeParameters.add("name", fieldTypeName); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("delete-field-type", deleteFieldTypeParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Adds a new copy field rule to the schema of the specified collection. |
| */ |
| public static class AddCopyField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param source the source field name |
| * @param dest the collection of the destination field names |
| * @see <a href="https://lucene.apache.org/solr/guide/copying-fields.html">Copying fields</a> |
| */ |
| public AddCopyField(String source, List<String> dest) { |
| this(source, dest, (SolrParams) null); |
| } |
| |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param source the source field name |
| * @param dest the collection of the destination field names |
| * @param maxChars the number of characters to be copied from the source to the dest. Specifying |
| * 0 as value, means that all the source characters will be copied to the dest. |
| * @see <a href="https://lucene.apache.org/solr/guide/copying-fields.html">Copying fields</a> |
| */ |
| public AddCopyField(String source, List<String> dest, Integer maxChars) { |
| this(source, dest, maxChars, null); |
| } |
| |
| public AddCopyField(String source, List<String> dest, SolrParams q) { |
| super(createRequestParameters(source, dest, null), q); |
| } |
| |
| public AddCopyField(String source, List<String> dest, Integer maxChars, SolrParams q) { |
| super(createRequestParameters(source, dest, maxChars), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(String source, List<String> dest, Integer maxchars) { |
| final NamedList<Object> addCopyFieldParameters = new NamedList<>(); |
| addCopyFieldParameters.add("source", source); |
| addCopyFieldParameters.add("dest", dest); |
| if (maxchars != null) { |
| addCopyFieldParameters.add("maxChars", maxchars); |
| } |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("add-copy-field", addCopyFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * Deletes a copy field rule from the schema of the specified collection. |
| * If the copy field rule does not exist in the schema then the |
| * method call {@link #process(SolrClient, String)} will fail. |
| */ |
| public static class DeleteCopyField extends SingleUpdate { |
| /** |
| * Creates a new instance of the request. |
| * |
| * @param source the source field name |
| * @param dest the collection of the destination field names |
| */ |
| public DeleteCopyField(String source, List<String> dest) { |
| this(source, dest, null); |
| } |
| |
| public DeleteCopyField(String source, List<String> dest, SolrParams q) { |
| super(createRequestParameters(source, dest), q); |
| } |
| |
| private static NamedList<Object> createRequestParameters(String source, List<String> dest) { |
| final NamedList<Object> addCopyFieldParameters = new NamedList<>(); |
| addCopyFieldParameters.add("source", source); |
| addCopyFieldParameters.add("dest", dest); |
| final NamedList<Object> requestParameters = new NamedList<>(); |
| requestParameters.add("delete-copy-field", addCopyFieldParameters); |
| return requestParameters; |
| } |
| } |
| |
| public abstract static class Update extends AbstractSchemaRequest<SchemaResponse.UpdateResponse> { |
| |
| public Update() { |
| this(null); |
| } |
| |
| public Update(SolrParams q) { |
| super(METHOD.POST, "/schema", q); |
| } |
| |
| protected abstract NamedList<Object> getRequestParameters(); |
| |
| @Override |
| public Collection<ContentStream> getContentStreams() throws IOException { |
| CharArr json = new CharArr(); |
| new SchemaRequestJSONWriter(json).write(getRequestParameters()); |
| return Collections.singletonList(new ContentStreamBase.StringStream(json.toString())); |
| } |
| |
| @Override |
| protected SchemaResponse.UpdateResponse createResponse(SolrClient client) { |
| return new SchemaResponse.UpdateResponse(); |
| } |
| } |
| |
| private static abstract class SingleUpdate extends Update { |
| private final NamedList<Object> requestParameters; |
| |
| public SingleUpdate(NamedList<Object> requestParameters) { |
| this(requestParameters, null); |
| } |
| |
| public SingleUpdate(NamedList<Object> requestParameters, SolrParams q) { |
| super(q); |
| this.requestParameters = requestParameters; |
| } |
| |
| @Override |
| protected NamedList<Object> getRequestParameters() { |
| return requestParameters; |
| } |
| } |
| |
| /** |
| * <p>The Schema API offers the possibility to perform one or more add requests in a single command.</p> |
| * <p>The API is transactional and all commands in a single {@link #process(SolrClient, String)} call |
| * either succeed or fail together.</p> |
| */ |
| public static class MultiUpdate extends Update { |
| private List<Update> updateSchemaRequests = new LinkedList<>(); |
| |
| public MultiUpdate(List<Update> updateSchemaRequests) { |
| this(updateSchemaRequests, null); |
| } |
| |
| public MultiUpdate(List<Update> updateSchemaRequests, SolrParams q) { |
| super(q); |
| if (updateSchemaRequests == null) { |
| throw new IllegalArgumentException("updateSchemaRequests must be non-null"); |
| } |
| for (Update updateSchemaRequest : updateSchemaRequests) { |
| if (updateSchemaRequest == null) { |
| throw new IllegalArgumentException("updateSchemaRequests elements must be non-null"); |
| } |
| this.updateSchemaRequests.add(updateSchemaRequest); |
| } |
| } |
| |
| @Override |
| protected NamedList<Object> getRequestParameters() { |
| NamedList<Object> multipleRequestsParameters = new NamedList<>(); |
| for (Update updateSchemaRequest : updateSchemaRequests) { |
| multipleRequestsParameters.addAll(updateSchemaRequest.getRequestParameters()); |
| } |
| return multipleRequestsParameters; |
| } |
| } |
| |
| /** |
| * Simple extension of the noggit JSONWriter used to be write objects |
| * of type {@link NamedList}. |
| * Writing of objects of the type {@link NamedList} is done in very much |
| * the same way as for a map. |
| * <p> |
| * This writer is particularly useful when doing multiple update requests. |
| * In update Schema API there can be done multiple add operations of the same |
| * type (e.g. : add-field-type), they are grouped in an associative array, even though |
| * this can't be done normally in JSON. For such a use-case, the {@link NamedList} |
| * objects are particularly useful because they can group key-value mappings |
| * having the same values for the keys (unlike maps). |
| */ |
| private static class SchemaRequestJSONWriter extends JSONWriter { |
| public SchemaRequestJSONWriter(CharArr out, int indentSize) { |
| super(out, indentSize); |
| } |
| |
| public SchemaRequestJSONWriter(CharArr out) { |
| super(out); |
| } |
| |
| public void write(Object o) { |
| if (o instanceof NamedList) { |
| write((NamedList) o); |
| } else super.write(o); |
| } |
| |
| /** |
| * @see #write(Map) |
| */ |
| @SuppressWarnings("unchecked") |
| public void write(NamedList<?> val) { |
| this.startObject(); |
| int sz = val.size(); |
| boolean first = true; |
| Iterator i$ = val.iterator(); |
| |
| while (i$.hasNext()) { |
| Map.Entry<String, ?> entry = (Map.Entry<String, ?>) i$.next(); |
| if (first) { |
| first = false; |
| } else { |
| this.writeValueSeparator(); |
| } |
| |
| if (sz > 1) { |
| this.indent(); |
| } |
| |
| this.writeString(entry.getKey()); |
| this.writeNameSeparator(); |
| this.write(entry.getValue()); |
| } |
| |
| this.endObject(); |
| } |
| } |
| } |