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.app.service;
17
18 import java.util.Collections;
19 import java.util.List;
20
21 import org.codelibs.core.beans.util.BeanUtil;
22 import org.codelibs.fess.Constants;
23 import org.codelibs.fess.app.pager.CharMappingPager;
24 import org.codelibs.fess.dict.DictionaryFile.PagingList;
25 import org.codelibs.fess.dict.DictionaryManager;
26 import org.codelibs.fess.dict.mapping.CharMappingFile;
27 import org.codelibs.fess.dict.mapping.CharMappingItem;
28 import org.codelibs.fess.mylasta.direction.FessConfig;
29 import org.dbflute.optional.OptionalEntity;
30
31 import jakarta.annotation.Resource;
32
33 /**
34 * Service class for managing character mapping operations.
35 * <p>
36 * This service handles character mapping management including CRUD operations
37 * and list retrieval. Character mappings are used for text normalization
38 * and character substitution during document processing and search operations.
39 * </p>
40 */
41 public class CharMappingService {
42
43 /**
44 * Creates a new instance of CharMappingService.
45 */
46 public CharMappingService() {
47 // Default constructor
48 }
49
50 /**
51 * Dictionary manager for accessing and managing dictionary files.
52 */
53 @Resource
54 protected DictionaryManager dictionaryManager;
55
56 /**
57 * Fess configuration settings.
58 */
59 @Resource
60 protected FessConfig fessConfig;
61
62 /**
63 * Retrieves a paginated list of character mapping items from the specified dictionary.
64 * <p>
65 * This method fetches character mapping items with pagination support and updates
66 * the pager with the current page information including total count and page ranges.
67 * </p>
68 *
69 * @param dictId the dictionary ID to retrieve character mappings from
70 * @param charMappingPager the pager object containing pagination parameters
71 * @return a list of character mapping items for the current page, or empty list if dictionary not found
72 */
73 public List<CharMappingItem> getCharMappingList(final String dictId, final CharMappingPager charMappingPager) {
74 return getCharMappingFile(dictId).map(file -> {
75 final int pageSize = charMappingPager.getPageSize();
76 final PagingList<CharMappingItem> charMappingList =
77 file.selectList((charMappingPager.getCurrentPageNumber() - 1) * pageSize, pageSize);
78
79 // update pager
80 BeanUtil.copyBeanToBean(charMappingList, charMappingPager, option -> option.include(Constants.PAGER_CONVERSION_RULE));
81 charMappingList.setPageRangeSize(fessConfig.getPagingPageRangeSizeAsInteger());
82 charMappingPager.setPageNumberList(charMappingList.createPageNumberList());
83
84 return (List<CharMappingItem>) charMappingList;
85 }).orElse(Collections.emptyList());
86 }
87
88 /**
89 * Retrieves the character mapping file for the specified dictionary ID.
90 * <p>
91 * This method looks up the dictionary file and ensures it is a character mapping file
92 * before returning it wrapped in an OptionalEntity.
93 * </p>
94 *
95 * @param dictId the dictionary ID to retrieve the character mapping file for
96 * @return an OptionalEntity containing the character mapping file if found and valid, empty otherwise
97 */
98 public OptionalEntity<CharMappingFile> getCharMappingFile(final String dictId) {
99 return dictionaryManager.getDictionaryFile(dictId)
100 .filter(CharMappingFile.class::isInstance)
101 .map(file -> OptionalEntity.of((CharMappingFile) file))
102 .orElse(OptionalEntity.empty());
103 }
104
105 /**
106 * Retrieves a specific character mapping item by its ID from the specified dictionary.
107 * <p>
108 * This method looks up a character mapping item using its unique identifier
109 * within the context of the specified dictionary.
110 * </p>
111 *
112 * @param dictId the dictionary ID containing the character mapping item
113 * @param id the unique identifier of the character mapping item
114 * @return an OptionalEntity containing the character mapping item if found, empty otherwise
115 */
116 public OptionalEntity<CharMappingItem> getCharMappingItem(final String dictId, final long id) {
117 return getCharMappingFile(dictId).map(file -> file.get(id).get());
118 }
119
120 /**
121 * Stores a character mapping item in the specified dictionary.
122 * <p>
123 * This method performs either an insert operation (for new items with ID 0)
124 * or an update operation (for existing items with non-zero ID) depending on
125 * the item's current state.
126 * </p>
127 *
128 * @param dictId the dictionary ID to store the character mapping item in
129 * @param charMappingItem the character mapping item to store
130 */
131 public void store(final String dictId, final CharMappingItem charMappingItem) {
132 getCharMappingFile(dictId).ifPresent(file -> {
133 if (charMappingItem.getId() == 0) {
134 file.insert(charMappingItem);
135 } else {
136 file.update(charMappingItem);
137 }
138 });
139 }
140
141 /**
142 * Deletes a character mapping item from the specified dictionary.
143 * <p>
144 * This method removes the specified character mapping item from the dictionary
145 * if the dictionary file exists and is accessible.
146 * </p>
147 *
148 * @param dictId the dictionary ID to delete the character mapping item from
149 * @param charMappingItem the character mapping item to delete
150 */
151 public void delete(final String dictId, final CharMappingItem charMappingItem) {
152 getCharMappingFile(dictId).ifPresent(file -> {
153 file.delete(charMappingItem);
154 });
155 }
156 }