Skip to content

Method: addAttribute(String, String)

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.frontend.ui.component.htmltemplate;
27:
28: import javax.annotation.Nonnull;
29: import javax.inject.Inject;
30: import javax.inject.Provider;
31: import java.util.ArrayList;
32: import java.util.HashMap;
33: import java.util.List;
34: import java.util.Map;
35: import java.io.FileNotFoundException;
36: import java.io.IOException;
37: import java.io.InputStreamReader;
38: import java.io.Reader;
39: import java.nio.CharBuffer;
40: import java.nio.charset.Charset;
41: import org.springframework.beans.factory.annotation.Configurable;
42: import org.springframework.core.io.ClassPathResource;
43: import org.springframework.core.io.Resource;
44: import org.stringtemplate.v4.ST;
45: import it.tidalwave.util.Id;
46: import it.tidalwave.northernwind.core.model.SiteProvider;
47: import it.tidalwave.northernwind.frontend.ui.SiteViewController;
48: import lombok.Getter;
49: import lombok.Setter;
50: import lombok.ToString;
51: import lombok.extern.slf4j.Slf4j;
52:
53: /***************************************************************************************************************************************************************
54: *
55: * The HtmlTemplate specialization of {@link SiteViewController}.
56: *
57: * @author Fabrizio Giudici
58: *
59: **************************************************************************************************************************************************************/
60: @Configurable @Slf4j @ToString(exclude="siteProvider")
61: public class TextHolder
62: {
63: private final Map<String, String> attributeMap = new HashMap<>();
64:
65: private final List<TextHolder> contents = new ArrayList<>();
66:
67: @Getter @Setter
68: private String template;
69:
70: @Inject
71: private Provider<SiteProvider> siteProvider;
72:
73: @Getter @Setter
74: private String mimeType = "text/plain";
75:
76: /***********************************************************************************************************************************************************
77: * Creates an instance with the given name.
78: *
79: * @param name the component name
80: **********************************************************************************************************************************************************/
81: public TextHolder (@Nonnull final Id id)
82: {
83: attributeMap.put("content", "");
84:
85: try
86: {
87: loadTemplate();
88: }
89: catch (IOException e)
90: {
91: throw new RuntimeException(e);
92: }
93: }
94:
95: public TextHolder (@Nonnull final String html)
96: {
97: addAttribute("content", html);
98: template = "$content$";
99: }
100:
101: // @Override
102: public void setContent (@Nonnull final String content)
103: {
104: addAttribute("content", content);
105: // setValue(html);
106: }
107:
108: public void addComponent (@Nonnull final TextHolder child)
109: {
110: contents.add(child);
111: }
112:
113: public void addAttribute (@Nonnull final String name, @Nonnull final String value)
114: {
115: attributeMap.put(name, value);
116: }
117:
118: // @Nonnull
119: // public byte[] asBytes2 (final @Nonnull Charset charset)
120: // {
121: // return asString2(charset).getBytes(charset);
122: // }
123: //
124: // @Nonnull
125: // public String asString2 (final @Nonnull Charset charset)
126: // {
127: // return template;
128: // }
129:
130: @Nonnull
131: public byte[] asBytes (@Nonnull final Charset charset)
132: {
133: return asString(charset).getBytes(charset);
134: }
135:
136: @Nonnull
137: public String asString (@Nonnull final Charset charset)
138: {
139: var t = new ST(template, '$', '$');
140:
141: for (final var entry : attributeMap.entrySet())
142: {
143: t = t.add(entry.getKey(), entry.getValue());
144: }
145:
146: final var builder = new StringBuilder();
147:
148: for (final var child : contents)
149: {
150: builder.append(child.asString(charset)).append("\n");
151: }
152:
153: t = t.add("content", builder.toString());
154: // t = t.add("contextPath", siteProvider.get().getSite().getContextPath());
155: t = t.add("charset", charset.name());
156: // t = t.add("language", "");
157:
158: return t.render();
159: }
160:
161: private void loadTemplate() // FIXME: use TemplateHelper
162: throws IOException
163: {
164: // FIXME: this should be done only once...
165: Resource resource = null;
166:
167: for (Class<?> clazz = getClass(); clazz.getSuperclass() != null; clazz = clazz.getSuperclass())
168: {
169: final var templateName = clazz.getSimpleName() + ".txt";
170: resource = new ClassPathResource(templateName, clazz);
171:
172: if (resource.exists())
173: {
174: break;
175: }
176: }
177:
178: try
179: {
180: if (resource == null)
181: {
182: throw new FileNotFoundException();
183: }
184:
185: try (final Reader r = new InputStreamReader(resource.getInputStream()))
186: {
187: final var charBuffer = CharBuffer.allocate((int)resource.contentLength());
188: final var length = r.read(charBuffer);
189: template = new String(charBuffer.array(), 0, length);
190: }
191: }
192: catch (FileNotFoundException e) // no specific template, fallback
193: {
194: log.warn("No template for {}, using default", getClass().getSimpleName());
195: template = "$content$\n";
196: }
197: }
198: }