1   /*
2    * Copyright 2017 LINE Corporation
3    *
4    * LINE Corporation licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  
17  package com.linecorp.centraldogma.server.internal.api.converter;
18  
19  import static com.google.common.base.Strings.isNullOrEmpty;
20  import static com.linecorp.centraldogma.internal.Util.isValidFilePath;
21  
22  import java.lang.reflect.ParameterizedType;
23  import java.util.List;
24  
25  import javax.annotation.Nullable;
26  
27  import com.google.common.collect.ImmutableList;
28  
29  import com.linecorp.armeria.common.AggregatedHttpRequest;
30  import com.linecorp.armeria.server.ServiceRequestContext;
31  import com.linecorp.armeria.server.annotation.RequestConverterFunction;
32  import com.linecorp.centraldogma.common.Query;
33  import com.linecorp.centraldogma.common.QueryType;
34  
35  import io.netty.handler.codec.http.QueryStringDecoder;
36  
37  /**
38   * A request converter that converts to {@link Query} when the request has a valid file path.
39   */
40  public final class QueryRequestConverter implements RequestConverterFunction {
41  
42      /**
43       * Converts the specified {@code request} to a {@link Query} when the request has a valid file path.
44       * {@code null} otherwise.
45       */
46      @Override
47      @Nullable
48      public Query<?> convertRequest(
49              ServiceRequestContext ctx, AggregatedHttpRequest request, Class<?> expectedResultType,
50              @Nullable ParameterizedType expectedParameterizedResultType) throws Exception {
51  
52          final String path = getPath(ctx);
53          final Iterable<String> jsonPaths = getJsonPaths(ctx);
54          if (jsonPaths != null) {
55              return Query.ofJsonPath(path, jsonPaths);
56          }
57  
58          if (isValidFilePath(path)) {
59              return Query.of(QueryType.IDENTITY, path);
60          }
61  
62          return null;
63      }
64  
65      private static String getPath(ServiceRequestContext ctx) {
66          // check the path param first
67          final String path = ctx.pathParam("path");
68          if (!isNullOrEmpty(path)) {
69              return path;
70          }
71  
72          // then check HTTP query
73          final String query = ctx.query();
74          if (query != null) {
75              final List<String> params = new QueryStringDecoder(query, false).parameters().get("path");
76              if (params != null) {
77                  return params.get(0);
78              }
79          }
80          // return empty string if there's no path
81          return "";
82      }
83  
84      @Nullable
85      private static Iterable<String> getJsonPaths(ServiceRequestContext ctx) {
86          final String query = ctx.query();
87          if (query != null) {
88              final List<String> jsonPaths = new QueryStringDecoder(query, false).parameters().get(
89                      "jsonpath");
90              if (jsonPaths != null) {
91                  return ImmutableList.copyOf(jsonPaths);
92              }
93          }
94          return null;
95      }
96  }