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.dict;
17
18 import java.util.Base64;
19 import java.util.Date;
20 import java.util.regex.Pattern;
21
22 import org.codelibs.fess.Constants;
23
24 import jakarta.annotation.Resource;
25
26 /**
27 * Abstract base class for creating dictionary files from file paths.
28 * Dictionary creators are responsible for recognizing specific file patterns
29 * and creating appropriate DictionaryFile instances for them.
30 */
31 public abstract class DictionaryCreator {
32
33 /** Pattern used to match file paths that this creator can handle. */
34 protected Pattern pattern;
35
36 /** Manager for dictionary operations and lifecycle. */
37 @Resource
38 protected DictionaryManager dictionaryManager;
39
40 /**
41 * Creates a new DictionaryCreator with the specified pattern.
42 *
43 * @param pattern the regular expression pattern to match file paths
44 */
45 protected DictionaryCreator(final String pattern) {
46 this.pattern = Pattern.compile(pattern);
47 }
48
49 /**
50 * Creates a dictionary file for the given path and timestamp if it matches this creator's pattern.
51 *
52 * @param path the file path to create a dictionary file for
53 * @param timestamp the timestamp of the dictionary file
54 * @return a DictionaryFile instance if the path matches, null otherwise
55 */
56 public DictionaryFile<? extends DictionaryItem> create(final String path, final Date timestamp) {
57 if (!isTarget(path)) {
58 return null;
59 }
60
61 return newDictionaryFile(encodePath(path), path, timestamp);
62 }
63
64 /**
65 * Encodes a file path using Base64 URL-safe encoding.
66 *
67 * @param path the file path to encode
68 * @return the Base64 encoded path
69 */
70 protected String encodePath(final String path) {
71 return Base64.getUrlEncoder().encodeToString(path.getBytes(Constants.CHARSET_UTF_8));
72 }
73
74 /**
75 * Checks if the given path matches this creator's pattern.
76 *
77 * @param path the file path to check
78 * @return true if the path matches the pattern, false otherwise
79 */
80 protected boolean isTarget(final String path) {
81 return pattern.matcher(path).find();
82 }
83
84 /**
85 * Creates a new dictionary file instance for the given parameters.
86 *
87 * @param id the encoded identifier for the dictionary file
88 * @param path the file path of the dictionary
89 * @param timestamp the timestamp of the dictionary file
90 * @return a new DictionaryFile instance
91 */
92 protected abstract DictionaryFile<? extends DictionaryItem> newDictionaryFile(String id, String path, Date timestamp);
93
94 /**
95 * Sets the dictionary manager for this creator.
96 *
97 * @param dictionaryManager the dictionary manager to set
98 */
99 public void setDictionaryManager(final DictionaryManager dictionaryManager) {
100 this.dictionaryManager = dictionaryManager;
101 }
102 }