View Javadoc
1   /*
2    * Copyright 2012-2025 CodeLibs Project and the Others.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://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,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13   * either express or implied. See the License for the specific language
14   * governing permissions and limitations under the License.
15   */
16  package org.codelibs.fess.util;
17  
18  import java.util.HashMap;
19  import java.util.LinkedHashMap;
20  import java.util.Map;
21  import java.util.regex.Pattern;
22  
23  import org.codelibs.core.lang.StringUtil;
24  import org.codelibs.core.misc.Pair;
25  import org.codelibs.fess.opensearch.config.exentity.CrawlingConfig.ConfigName;
26  import org.lastaflute.core.security.PrimaryCipher;
27  
28  /**
29   * Utility class for parameter operations.
30   */
31  public class ParameterUtil {
32      private static final String CIPHER_PREFIX = "{cipher}";
33  
34      /** The XPath field prefix. */
35      protected static final String XPATH_PREFIX = "field.xpath.";
36  
37      /** The meta field prefix. */
38      protected static final String META_PREFIX = "field.meta.";
39  
40      /** The value field prefix. */
41      protected static final String VALUE_PREFIX = "field.value.";
42  
43      /** The script field prefix. */
44      protected static final String SCRIPT_PREFIX = "field.script.";
45  
46      /** The client prefix. */
47      protected static final String CLIENT_PREFIX = "client.";
48  
49      /** The config prefix. */
50      protected static final String CONFIG_PREFIX = "config.";
51  
52      /** The field config prefix. */
53      protected static final String FIELD_PREFIX = "field.config.";
54  
55      /**
56       * Protected constructor.
57       */
58      protected ParameterUtil() {
59          // nothing
60      }
61  
62      /**
63       * Parses parameter string into a map.
64       *
65       * @param value the parameter string
66       * @return the parameter map
67       */
68      public static Map<String, String> parse(final String value) {
69          final Map<String, String> paramMap = new LinkedHashMap<>();
70          if (value != null) {
71              int unknownKey = 0;
72              final Pattern properyPattern = Pattern.compile(ComponentUtil.getFessConfig().getAppEncryptPropertyPattern());
73              final PrimaryCipher cipher = ComponentUtil.getPrimaryCipher();
74              final String[] lines = value.split("[\r\n]");
75              for (final String line : lines) {
76                  if (StringUtil.isNotBlank(line)) {
77                      final int pos = line.indexOf('=');
78                      if (pos == 0) {
79                          paramMap.put("unknown." + (unknownKey + 1), line.substring(pos + 1).trim());
80                          unknownKey++;
81                      } else if (pos > 0) {
82                          final String key = line.substring(0, pos).trim();
83                          if (pos < line.length()) {
84                              String data = line.substring(pos + 1).trim();
85                              if (properyPattern.matcher(key).matches() && data.startsWith(CIPHER_PREFIX)) {
86                                  data = cipher.decrypt(data.substring(CIPHER_PREFIX.length()));
87                              }
88                              paramMap.put(key, data);
89                          } else {
90                              paramMap.put(key, StringUtil.EMPTY);
91                          }
92                      } else {
93                          paramMap.put(line.trim(), StringUtil.EMPTY);
94                      }
95                  }
96              }
97          }
98          return paramMap;
99      }
100 
101     /**
102      * Encrypts sensitive parameter values.
103      *
104      * @param value the parameter string
105      * @return the encrypted parameter string
106      */
107     public static String encrypt(final String value) {
108         final StringBuilder buf = new StringBuilder();
109         final Pattern properyPattern = Pattern.compile(ComponentUtil.getFessConfig().getAppEncryptPropertyPattern());
110         final PrimaryCipher cipher = ComponentUtil.getPrimaryCipher();
111         ParameterUtil.parse(value).entrySet().stream().map(e -> {
112             final String k = e.getKey();
113             final String v = e.getValue();
114             if (properyPattern.matcher(k).matches() && !v.startsWith(CIPHER_PREFIX)) {
115                 return new Pair<>(k, CIPHER_PREFIX + cipher.encrypt(v));
116             }
117             return new Pair<>(k, v);
118         }).forEach(e -> {
119             if (buf.length() > 0) {
120                 buf.append('\n');
121             }
122             buf.append(e.getFirst());
123             buf.append('=');
124             buf.append(e.getSecond());
125         });
126         return buf.toString();
127     }
128 
129     /**
130      * Loads configuration parameters into a map.
131      *
132      * @param paramMap the parameter map
133      * @param configParam the configuration parameter string
134      */
135     public static void loadConfigParams(final Map<String, Object> paramMap, final String configParam) {
136         final Map<String, String> map = ParameterUtil.parse(configParam);
137         if (!map.isEmpty()) {
138             paramMap.putAll(map);
139         }
140     }
141 
142     /**
143      * Creates a configuration parameter map.
144      *
145      * @param configParameters the configuration parameters
146      * @return the configuration parameter map
147      */
148     public static Map<ConfigName, Map<String, String>> createConfigParameterMap(final String configParameters) {
149         final Map<ConfigName, Map<String, String>> map = new HashMap<>();
150         final Map<String, String> configConfigMap = new LinkedHashMap<>();
151         final Map<String, String> clientConfigMap = new LinkedHashMap<>();
152         final Map<String, String> xpathConfigMap = new LinkedHashMap<>();
153         final Map<String, String> metaConfigMap = new LinkedHashMap<>();
154         final Map<String, String> valueConfigMap = new LinkedHashMap<>();
155         final Map<String, String> scriptConfigMap = new LinkedHashMap<>();
156         final Map<String, String> fieldConfigMap = new LinkedHashMap<>();
157         map.put(ConfigName.CONFIG, configConfigMap);
158         map.put(ConfigName.CLIENT, clientConfigMap);
159         map.put(ConfigName.XPATH, xpathConfigMap);
160         map.put(ConfigName.META, metaConfigMap);
161         map.put(ConfigName.VALUE, valueConfigMap);
162         map.put(ConfigName.SCRIPT, scriptConfigMap);
163         map.put(ConfigName.FIELD, fieldConfigMap);
164         for (final Map.Entry<String, String> entry : ParameterUtil.parse(configParameters).entrySet()) {
165             final String key = entry.getKey();
166             if (key.startsWith(CONFIG_PREFIX)) {
167                 configConfigMap.put(key.substring(CONFIG_PREFIX.length()), entry.getValue());
168             } else if (key.startsWith(CLIENT_PREFIX)) {
169                 clientConfigMap.put(key.substring(CLIENT_PREFIX.length()), entry.getValue());
170             } else if (key.startsWith(XPATH_PREFIX)) {
171                 xpathConfigMap.put(key.substring(XPATH_PREFIX.length()), entry.getValue());
172             } else if (key.startsWith(META_PREFIX)) {
173                 metaConfigMap.put(key.substring(META_PREFIX.length()), entry.getValue());
174             } else if (key.startsWith(VALUE_PREFIX)) {
175                 valueConfigMap.put(key.substring(VALUE_PREFIX.length()), entry.getValue());
176             } else if (key.startsWith(SCRIPT_PREFIX)) {
177                 scriptConfigMap.put(key.substring(SCRIPT_PREFIX.length()), entry.getValue());
178             } else if (key.startsWith(FIELD_PREFIX)) {
179                 fieldConfigMap.put(key.substring(FIELD_PREFIX.length()), entry.getValue());
180             }
181         }
182 
183         return map;
184     }
185 }