1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.devacfr.maven.skins.reflow.context;
17
18 import static java.util.Objects.requireNonNull;
19
20 import com.google.common.collect.ImmutableMap;
21 import com.google.common.collect.Lists;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.Optional;
25 import javax.annotation.Nonnull;
26 import org.apache.commons.lang3.builder.ToStringBuilder;
27 import org.codehaus.plexus.util.xml.Xpp3Dom;
28 import org.devacfr.maven.skins.reflow.HtmlTool;
29 import org.devacfr.maven.skins.reflow.ISkinConfig;
30 import org.devacfr.maven.skins.reflow.model.Component;
31 import org.devacfr.maven.skins.reflow.model.Footer;
32 import org.devacfr.maven.skins.reflow.model.NavSideMenu;
33 import org.devacfr.maven.skins.reflow.model.Navbar;
34 import org.devacfr.maven.skins.reflow.model.ScrollTop;
35 import org.devacfr.maven.skins.reflow.model.SideNavMenuItem;
36 import org.slf4j.Logger;
37 import org.slf4j.LoggerFactory;
38
39
40
41
42
43
44
45
46
47 public abstract class Context<T extends Context<?>> extends Component {
48
49
50
51
52 private static final Map<String, String> ICON_REPLACEMENTS = ImmutableMap.<String, String> builder()
53 .put("img[src$=images/add.gif]", "<i class=\"fas fa-plus\"></i>")
54 .put("img[src$=images/remove.gif]", "<i class=\"fas fa-minus\"></i>")
55 .put("img[src$=images/fix.gif]", "<i class=\"fas fa-wrench\"></i>")
56 .put("img[src$=images/update.gif]", "<i class=\"fas fa-redo\"></i>")
57 .put("img[src$=images/icon_help_sml.gif]", "<i class=\"fas fa-question\"></i>")
58 .put("img[src$=images/icon_success_sml.gif]", "<i class=\"fas fa-check-circle\"></i>")
59 .put("img[src$=images/icon_warning_sml.gif]", "<i class=\"fas fa-exclamation-triangle\"></i>")
60 .put("img[src$=images/icon_error_sml.gif]", "<i class=\"fas fa-exclamation-circle\"></i>")
61 .put("img[src$=images/icon_info_sml.gif]", "<i class=\"fas fa-info\"></i>")
62 .build();
63
64
65 private static final Logger LOGGER = LoggerFactory.getLogger(Context.class);
66
67
68 private ContextType type;
69
70
71 private final Navbar navbar;
72
73
74 private final Footer footer;
75
76
77 private final ScrollTop scrollTop;
78
79
80
81
82
83
84
85
86 @Nonnull
87 public static Context<?> buildContext(@Nonnull final ISkinConfig config) {
88 requireNonNull(config);
89 final String fileId = requireNonNull(config.getFileId());
90
91 ContextType type = ContextType.page;
92 final List<SideNavMenuItem> allSideNaveMenuItems = NavSideMenu.findAllSideNavMenuItems(config);
93 if (LOGGER.isTraceEnabled()) {
94 LOGGER.trace("findAllSideNavMenuItems: " + allSideNaveMenuItems);
95 }
96 final Xpp3Dom pageProperties = config.getPageProperties();
97
98 if (pageProperties != null) {
99 if (pageProperties.getAttribute("type") != null) {
100 type = ContextType.valueOf(pageProperties.getAttribute("type"));
101 }
102
103
104 if (allSideNaveMenuItems.stream().filter(item -> fileId.equals(item.getSlugName())).count() > 0) {
105 type = ContextType.frame;
106 }
107 }
108
109
110
111 Context<?> context = null;
112 switch (type) {
113 case doc:
114 context = new DocumentContext(config);
115 break;
116
117 case frame:
118
119 final Optional<SideNavMenuItem> menuItem = allSideNaveMenuItems.stream()
120 .filter(item -> fileId.equals(item.getSlugName()))
121 .findFirst();
122 final SideNavMenuItem item = menuItem.get();
123 final String documentParent = item.getParent();
124 context = new FrameContext(config, documentParent);
125 break;
126 case body:
127 context = new BodyContext(config);
128 break;
129 case page:
130 default:
131 context = new PageContext(config);
132 break;
133 }
134 return context;
135 }
136
137
138
139
140
141
142
143
144
145 public Context(@Nonnull final ISkinConfig config, @Nonnull final ContextType type) {
146 super(config);
147 this.withType(requireNonNull(type));
148 this.navbar = new Navbar(config);
149 this.scrollTop = new ScrollTop(config);
150 this.footer = new Footer(config);
151
152 this.initialize();
153
154
155 this.addChildren(this.navbar, this.scrollTop, this.footer);
156 }
157
158
159
160
161 protected void initialize() {
162
163 if (!config.not("anchorJS")) {
164 this.addCssOptions("anchorjs-enabled");
165 }
166 }
167
168
169
170
171
172
173
174 public String preRender() {
175 return onPreRender(config.getBodyContent());
176 }
177
178 @Override
179 protected String onPreRender(final @Nonnull String bodyContent) {
180 final HtmlTool htmlTool = config.getHtmlTool();
181 String content = bodyContent;
182 if (!config.not("imgLightbox")) {
183
184 content = htmlTool.setAttr(content,
185 "a[href$=jpg], a[href$=JPG], a[href$=jpeg], a[href$=JPEG], "
186 + "a[href$=png], a[href$=gif],a[href$=bmp]:has(img)",
187 "data-lightbox",
188 "page");
189 }
190
191 if (!config.not("html5Anchor")) {
192
193 content = htmlTool.headingAnchorToId(content);
194 }
195
196 if (!config.not("bootstrapCss")) {
197
198
199 content = htmlTool
200 .addClass(content, "table.bodyTable", Lists.newArrayList("table", "table-striped", "table-hover"));
201
202 content = htmlTool.addClass(content, "img", Lists.newArrayList("img-fluid"));
203 content = htmlTool.fixTableHeads(content);
204 }
205
206 if (!config.not("bootstrapIcons")) {
207
208 content = htmlTool.replaceAll(content, ICON_REPLACEMENTS);
209 }
210
211
212
213 content = htmlTool.replaceWith(content, "tt", "<code class=\"literal\">");
214 return super.onPreRender(content);
215 }
216
217
218
219
220 public Navbar getNavbar() {
221 return navbar;
222 }
223
224
225
226
227 public ScrollTop getScrollTop() {
228 return scrollTop;
229 }
230
231
232
233
234 public Footer getFooter() {
235 return footer;
236 }
237
238
239
240
241
242
243
244
245 protected T withType(final ContextType type) {
246 this.type = type;
247 return self();
248 }
249
250
251
252
253 public String getType() {
254 return type.name();
255 }
256
257
258
259
260 @SuppressWarnings("unchecked")
261 protected T self() {
262 return (T) this;
263 }
264
265
266
267
268 @Override
269 public String toString() {
270 return ToStringBuilder.reflectionToString(this);
271 }
272
273 }