You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ds...@apache.org on 2026/07/28 14:13:59 UTC

(solr) 06/06: Remove dead classes BaseHandlerApiSupport and PrintWriterWrapper (#4654)

This is an automated email from the ASF dual-hosted git repository.

dsmiley pushed a commit to branch branch_10x
in repository https://gitbox.apache.org/repos/asf/solr.git

commit e76c7588624c5f84d1da1bfb04daefc4d6b81bae
Author: Pierre Salagnac <ps...@apache.org>
AuthorDate: Mon Jul 27 14:16:03 2026 +0200

    Remove dead classes BaseHandlerApiSupport and PrintWriterWrapper (#4654)
    
    (cherry picked from commit 63b3d6bf12015e73c1ddda096a1c864af4a3dcb8)
---
 .../solr/handler/admin/BaseHandlerApiSupport.java  | 236 ---------------------
 .../apache/solr/security/PrintWriterWrapper.java   | 211 ------------------
 2 files changed, 447 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java b/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java
deleted file mode 100644
index 82d2e869aad..00000000000
--- a/solr/core/src/java/org/apache/solr/handler/admin/BaseHandlerApiSupport.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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.handler.admin;
-
-import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
-import static org.apache.solr.common.SolrException.ErrorCode.BAD_REQUEST;
-import static org.apache.solr.common.util.StrUtils.splitSmart;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.stream.Collectors;
-import org.apache.solr.api.Api;
-import org.apache.solr.api.ApiSupport;
-import org.apache.solr.client.solrj.SolrRequest;
-import org.apache.solr.client.solrj.request.ApiMapping.CommandMeta;
-import org.apache.solr.client.solrj.request.ApiMapping.V2EndPoint;
-import org.apache.solr.common.SolrException;
-import org.apache.solr.common.params.SolrParams;
-import org.apache.solr.common.util.CommandOperation;
-import org.apache.solr.common.util.SuppressForbidden;
-import org.apache.solr.common.util.Utils;
-import org.apache.solr.request.SolrQueryRequest;
-import org.apache.solr.response.SolrQueryResponse;
-
-/**
- * This is a utility class to provide an easy mapping of request handlers which support multiple
- * commands to the V2 API format (core admin api, collections api). This helps in automatically
- * mapping paths to actions and old parameter names to new parameter names
- */
-public abstract class BaseHandlerApiSupport implements ApiSupport {
-  protected final Map<SolrRequest.METHOD, Map<V2EndPoint, List<ApiCommand>>> commandsMapping;
-
-  protected BaseHandlerApiSupport() {
-    commandsMapping = new HashMap<>();
-    for (ApiCommand cmd : getCommands()) {
-      Map<V2EndPoint, List<ApiCommand>> m = commandsMapping.get(cmd.meta().getHttpMethod());
-      if (m == null) commandsMapping.put(cmd.meta().getHttpMethod(), m = new HashMap<>());
-      List<ApiCommand> list = m.get(cmd.meta().getEndPoint());
-      if (list == null) m.put(cmd.meta().getEndPoint(), list = new ArrayList<>());
-      list.add(cmd);
-    }
-  }
-
-  @Override
-  public synchronized Collection<Api> getApis() {
-    return getEndPoints().stream().map(this::getApi).collect(Collectors.toUnmodifiableList());
-  }
-
-  private Api getApi(final V2EndPoint op) {
-    final BaseHandlerApiSupport apiHandler = this;
-    return new Api(Utils.getSpec(op.getSpecName())) {
-      @Override
-      public void call(SolrQueryRequest req, SolrQueryResponse rsp) {
-        SolrParams params = req.getParams();
-        SolrRequest.METHOD method = SolrRequest.METHOD.valueOf(req.getHttpMethod());
-        List<ApiCommand> commands = commandsMapping.get(method).get(op);
-        try {
-          if (method == POST) {
-            List<CommandOperation> cmds = req.getCommands(true);
-            if (cmds.size() > 1)
-              throw new SolrException(BAD_REQUEST, "Only one command is allowed");
-            CommandOperation c = cmds.size() == 0 ? null : cmds.get(0);
-            ApiCommand command = null;
-            String commandName = c == null ? null : c.name;
-            for (ApiCommand cmd : commands) {
-              if (Objects.equals(cmd.meta().getName(), commandName)) {
-                command = cmd;
-                break;
-              }
-            }
-
-            if (command == null) {
-              throw new SolrException(BAD_REQUEST, " no such command " + c);
-            }
-            wrapParams(req, c, command, false);
-            command.invoke(req, rsp, apiHandler);
-
-          } else {
-            if (commands == null || commands.isEmpty()) {
-              rsp.add("error", "No support for : " + method + " at :" + req.getPath());
-              return;
-            }
-            if (commands.size() > 1) {
-              for (ApiCommand command : commands) {
-                if (command.meta().getName().equals(req.getPath())) {
-                  commands = List.of(command);
-                  break;
-                }
-              }
-            }
-            wrapParams(req, new CommandOperation("", Map.of()), commands.get(0), true);
-            commands.get(0).invoke(req, rsp, apiHandler);
-          }
-
-        } catch (SolrException e) {
-          throw e;
-        } catch (Exception e) {
-          // TODO BAD_REQUEST is a wild guess; should we flip the default?  fail here to investigate
-          // how this happens in tests
-          throw new SolrException(BAD_REQUEST, e);
-        } finally {
-          req.setParams(params);
-        }
-      }
-    };
-  }
-
-  /** Wrapper for SolrParams that wraps V2 params and exposes them as V1 params. */
-  @SuppressForbidden(
-      reason = "CommandOperation.getCommandData can return null when there is no payload")
-  private static void wrapParams(
-      final SolrQueryRequest req,
-      final CommandOperation co,
-      final ApiCommand cmd,
-      final boolean useRequestParams) {
-    final Map<String, String> pathValues = req.getPathTemplateValues();
-    final Map<String, Object> map =
-        co == null || !(co.getCommandData() instanceof Map)
-            ? Collections.singletonMap("", co.getCommandData())
-            : co.getDataMap();
-    final SolrParams origParams = req.getParams();
-
-    req.setParams(
-        new SolrParams() {
-          @Override
-          public String get(String param) {
-            Object vals = getParams0(param);
-            if (vals == null) return null;
-            if (vals instanceof String) return (String) vals;
-            if (vals instanceof Boolean || vals instanceof Number) return String.valueOf(vals);
-            if (vals instanceof String[] && ((String[]) vals).length > 0)
-              return ((String[]) vals)[0];
-            return null;
-          }
-
-          private Object getParams0(String param) {
-            param = cmd.meta().getParamSubstitute(param); // v1 -> v2, possibly dotted path
-            Object o =
-                param.indexOf('.') > 0
-                    ? Utils.getObjectByPath(map, true, splitSmart(param, '.'))
-                    : map.get(param);
-            if (o == null) o = pathValues.get(param);
-            if (o == null && useRequestParams) o = origParams.getParams(param);
-            if (o instanceof List) {
-              @SuppressWarnings("unchecked")
-              List<String> l = (List<String>) o;
-              return l.toArray(new String[0]);
-            }
-
-            return o;
-          }
-
-          @Override
-          public String[] getParams(String param) {
-            Object vals = getParams0(param);
-            return vals == null || vals instanceof String[]
-                ? (String[]) vals
-                : new String[] {vals.toString()};
-          }
-
-          @Override
-          public Iterator<String> getParameterNamesIterator() {
-            return cmd.meta().getParamNamesIterator(co);
-          }
-
-          @Override
-          public void writeMap(EntryWriter ew) throws IOException {
-            for (Iterator<String> it = getParameterNamesIterator(); it.hasNext(); ) {
-              final String param = it.next();
-              String key = cmd.meta().getParamSubstitute(param);
-              Object o =
-                  key.indexOf('.') > 0
-                      ? Utils.getObjectByPath(map, true, splitSmart(key, '.'))
-                      : map.get(key);
-              if (o == null) o = pathValues.get(key);
-              if (o == null && useRequestParams) o = origParams.getParams(key);
-              if (o == null) continue;
-              // make strings out of as many things as we can now to minimize differences from
-              // the standard impls that pass through a NamedList/SimpleOrderedMap...
-              Class<?> oClass = o.getClass();
-              if (oClass.isPrimitive()
-                  || Number.class.isAssignableFrom(oClass)
-                  || Character.class.isAssignableFrom(oClass)
-                  || Boolean.class.isAssignableFrom(oClass)) {
-                ew.put(param, String.valueOf(o));
-              } else if (List.class.isAssignableFrom(oClass)) {
-                @SuppressWarnings({"unchecked"})
-                List<?> l = (List<?>) o;
-                if (l.isEmpty() || l.get(0) instanceof String) {
-                  ew.put(param, l.toArray(new String[0]));
-                } else {
-                  ew.put(param, o);
-                }
-              } else {
-                // Lists pass through but will require special handling downstream
-                // if they contain non-string elements.
-                ew.put(param, o);
-              }
-            }
-          }
-        });
-  }
-
-  protected abstract Collection<ApiCommand> getCommands();
-
-  protected abstract Collection<V2EndPoint> getEndPoints();
-
-  public interface ApiCommand {
-    CommandMeta meta();
-
-    void invoke(SolrQueryRequest req, SolrQueryResponse rsp, BaseHandlerApiSupport apiHandler)
-        throws Exception;
-  }
-}
diff --git a/solr/core/src/java/org/apache/solr/security/PrintWriterWrapper.java b/solr/core/src/java/org/apache/solr/security/PrintWriterWrapper.java
deleted file mode 100644
index 532a828e384..00000000000
--- a/solr/core/src/java/org/apache/solr/security/PrintWriterWrapper.java
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * 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.security;
-
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Locale;
-
-/** Wrapper for PrintWriter that delegates to constructor arg */
-public class PrintWriterWrapper extends PrintWriter {
-  private PrintWriter printWriter;
-
-  public PrintWriterWrapper(PrintWriter printWriter) {
-    super(new StringWriter());
-    this.printWriter = printWriter;
-  }
-
-  @Override
-  public PrintWriter append(char c) {
-    return printWriter.append(c);
-  }
-
-  @Override
-  public PrintWriter append(CharSequence csq) {
-    return printWriter.append(csq);
-  }
-
-  @Override
-  public PrintWriter append(CharSequence csq, int start, int end) {
-    return printWriter.append(csq, start, end);
-  }
-
-  @Override
-  public boolean checkError() {
-    return printWriter.checkError();
-  }
-
-  @Override
-  protected void clearError() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void close() {
-    printWriter.close();
-  }
-
-  @Override
-  public void flush() {
-    printWriter.flush();
-  }
-
-  @Override
-  public PrintWriter format(Locale l, String format, Object... args) {
-    return printWriter.format(l, format, args);
-  }
-
-  @Override
-  public PrintWriter format(String format, Object... args) {
-    throw new UnsupportedOperationException("Forbidden API");
-  }
-
-  @Override
-  public void print(boolean b) {
-    printWriter.print(b);
-  }
-
-  @Override
-  public void print(char c) {
-    printWriter.print(c);
-  }
-
-  @Override
-  public void print(char[] s) {
-    printWriter.print(s);
-  }
-
-  @Override
-  public void print(double d) {
-    printWriter.print(d);
-  }
-
-  @Override
-  public void print(float f) {
-    printWriter.print(f);
-  }
-
-  @Override
-  public void print(int i) {
-    printWriter.print(i);
-  }
-
-  @Override
-  public void print(long l) {
-    printWriter.print(l);
-  }
-
-  @Override
-  public void print(Object obj) {
-    printWriter.print(obj);
-  }
-
-  @Override
-  public void print(String s) {
-    printWriter.print(s);
-  }
-
-  @Override
-  public PrintWriter printf(Locale l, String format, Object... args) {
-    return printWriter.printf(l, format, args);
-  }
-
-  @Override
-  public PrintWriter printf(String format, Object... args) {
-    throw new UnsupportedOperationException("Forbidden API");
-  }
-
-  @Override
-  public void println() {
-    printWriter.println();
-  }
-
-  @Override
-  public void println(boolean x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(char x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(char[] x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(double x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(float x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(int x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(long x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(Object x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  public void println(String x) {
-    printWriter.println(x);
-  }
-
-  @Override
-  protected void setError() {
-    throw new UnsupportedOperationException();
-  }
-
-  @Override
-  public void write(char[] buf) {
-    printWriter.write(buf);
-  }
-
-  @Override
-  public void write(char[] buf, int off, int len) {
-    printWriter.write(buf, off, len);
-  }
-
-  @Override
-  public void write(int c) {
-    printWriter.write(c);
-  }
-
-  @Override
-  public void write(String s) {
-    printWriter.write(s);
-  }
-
-  @Override
-  public void write(String s, int off, int len) {
-    printWriter.write(s, off, len);
-  }
-}