Package: TextResourcePropertyResolver
TextResourcePropertyResolver
name | instruction | branch | complexity | line | method | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
TextResourcePropertyResolver(ResourceFile) |
|
|
|
|
|
||||||||||||||||||||
findLocalizedFile(String) |
|
|
|
|
|
||||||||||||||||||||
resolveProperty(Id, Key) |
|
|
|
|
|
||||||||||||||||||||
static {...} |
|
|
|
|
|
Coverage
1: /*
2: * *************************************************************************************************************************************************************
3: *
4: * NorthernWind - lightweight CMS
5: * http://tidalwave.it/projects/northernwind
6: *
7: * Copyright (C) 2011 - 2025 Tidalwave s.a.s. (http://tidalwave.it)
8: *
9: * *************************************************************************************************************************************************************
10: *
11: * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
12: * You may obtain a copy of the License at
13: *
14: * http://www.apache.org/licenses/LICENSE-2.0
15: *
16: * 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
17: * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
18: *
19: * *************************************************************************************************************************************************************
20: *
21: * git clone https://bitbucket.org/tidalwave/northernwind-src
22: * git clone https://github.com/tidalwave-it/northernwind-src
23: *
24: * *************************************************************************************************************************************************************
25: */
26: package it.tidalwave.northernwind.core.impl.model;
27:
28: import javax.annotation.Nonnull;
29: import javax.inject.Inject;
30: import javax.inject.Provider;
31: import java.util.List;
32: import java.io.IOException;
33: import java.nio.charset.Charset;
34: import org.springframework.beans.factory.annotation.Configurable;
35: import it.tidalwave.util.Id;
36: import it.tidalwave.util.Key;
37: import it.tidalwave.util.NotFoundException;
38: import it.tidalwave.northernwind.core.model.RequestLocaleManager;
39: import it.tidalwave.northernwind.core.model.ResourceFile;
40: import it.tidalwave.northernwind.core.model.ResourceProperties;
41: import lombok.extern.slf4j.Slf4j;
42:
43: /***************************************************************************************************************************************************************
44: *
45: * This class tries to resolve a property by loading it from a text file. The file is searched in the given folder
46: * with the same name of the property, localized.If the searched property is {@code fullText}, and the managed locales
47: * are {@code en} and {@code it}, then the following files are searched for:
48: *
49: * <ul>
50: * <li>{@code fullText.xhtml}</li>
51: * <li>{@code fullText.html}</li>
52: * <li>{@code fullText.xml}</li>
53: * <li>{@code fullText.txt}</li>
54: * <li>{@code fullText_en.xhtml}</li>
55: * <li>{@code fullText_en.html}</li>
56: * <li>{@code fullText_en.xml}</li>
57: * <li>{@code fullText_en.txt}</li>
58: * <li>{@code fullText_it.xhtml}</li>
59: * <li>{@code fullText_it.html}</li>
60: * <li>{@code fullText_it.xml}</li>
61: * <li>{@code fullText_it.txt}</li>
62: * </ul>
63: *
64: * Files are pre-processed through the {@link FilterSetExpander}. If the file MIME type is XHTML, UTF-8 is used for the
65: * encoding, otherwise the default charset is used.
66: *
67: * HTML support is a legacy and will be removed in a future version.
68: *
69: * @author Fabrizio Giudici
70: *
71: **************************************************************************************************************************************************************/
72: @Configurable @Slf4j
73: public class TextResourcePropertyResolver implements ResourceProperties.PropertyResolver
74: {
75: private static final List<String> EXTENSIONS = List.of(".xhtml", ".html", ".xml", ".txt");
76:
77: @Inject
78: private RequestLocaleManager localeRequestManager;
79:
80: @Inject
81: private Provider<FilterSetExpander> filterSetExpander;
82:
83: @Nonnull
84: private final ResourceFile folder;
85:
86: /***********************************************************************************************************************************************************
87: *
88: **********************************************************************************************************************************************************/
89: public TextResourcePropertyResolver (@Nonnull final ResourceFile folder)
90:• {
91: this.folder = folder;
92:• }
93:
94: /***********************************************************************************************************************************************************
95: * {@inheritDoc}
96: **********************************************************************************************************************************************************/
97: @Nonnull
98: @Override @SuppressWarnings("unchecked")
99: public <Type> Type resolveProperty (@Nonnull final Id propertyGroupId, @Nonnull final Key<Type> propertyName)
100: throws NotFoundException, IOException
101: {
102: log.trace("resolveProperty({})", propertyName);
103:
104: final var propertyFile = findLocalizedFile(propertyName.stringValue());
105: log.trace(">>>> reading from {}", propertyFile.getPath());
106: final var mimeType = propertyFile.getMimeType();
107:• final var charset = "application/xhtml+xml".equals(mimeType) ? "UTF-8" : Charset.defaultCharset().name();
108:
109: try
110: {
111: return (Type)filterSetExpander.get().filter(propertyFile.asText(charset), mimeType);
112: }
113: catch (RuntimeException e) // FIXME: introduce a FilterException
114: {
115: throw new IOException(e);
116: }
117: }
118:
119: /***********************************************************************************************************************************************************
120: *
121: **********************************************************************************************************************************************************/
122: @Nonnull
123: private ResourceFile findLocalizedFile (@Nonnull final String fileName)
124: throws NotFoundException
125: {
126: log.trace("findLocalizedFile({})", fileName);
127: final var fileNamesNotFound = new StringBuilder();
128: var separator = "";
129:
130:• for (final var localeSuffix : localeRequestManager.getLocaleSuffixes())
131: {
132:• for (final var extension : EXTENSIONS)
133: {
134: final var localizedFileName = fileName + localeSuffix + extension;
135:
136: try
137: {
138: return folder.findChildren().withName(localizedFileName).result();
139: }
140: catch (NotFoundException e)
141: {
142: // continue
143: }
144:
145: fileNamesNotFound.append(separator);
146: fileNamesNotFound.append(localizedFileName);
147: separator = ",";
148: }
149: }
150:
151: throw new NotFoundException(String.format("%s/{%s}", folder.getPath().asString(), fileNamesNotFound));
152: }
153: }