BrightSide Workbench Full Report + Source Code
NavigationParser.java
Go to the documentation of this file.
1 /*
2  * TurrĂ³ i Cutiller Foundation. License notice.
3  * Copyright (C) 2020 Lluis TurrĂ³ Cutiller <http://www.turro.org/>
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Affero General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Affero General Public License for more details.
14  *
15  * You should have received a copy of the GNU Affero General Public License
16  * along with this program. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 package org.turro.parser;
20 
21 import java.io.IOException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.List;
25 import java.util.Set;
26 import java.util.logging.Level;
27 import java.util.logging.Logger;
28 import org.turro.string.ObjectString;
29 import org.turro.string.Strings;
30 import org.turro.annotation.ExternalParser;
31 import org.turro.elephant.context.ElephantContext;
32 import org.turro.elephant.impl.navigation.Navigator;
33 import org.turro.elephant.impl.navigation.NavigatorType;
34 import org.turro.elephant.impl.navigation.WebMap;
35 import org.turro.elephant.web.ElContext;
36 import org.turro.elephant.web.ElContextMap;
37 import org.turro.html.HTMLHelper;
38 
43 @ExternalParser
44 public class NavigationParser extends AbstractParser {
45 
46  @Override
47  public String getParserName() {
48  return "Navigation";
49  }
50 
51  @Override
52  protected boolean doExecute() {
53  boolean done = false;
54  if("list".equals(getMacroName()) || "anchor".equals(getMacroName())) {
55  int currToken = 1;
56  boolean verbosePath = false;
57  boolean hidden = false;
58  boolean external = false;
60  List<ElContext> result = null;
61  String clickAction = "", cssClass = "";
62  while(currToken < tokens.length && root != null) {
63  if("popup".equals(tokens[currToken])) {
64  clickAction = "popupElement('" + ElephantContext.getRootWebPath() + "', $(this)); return false;";
65  cssClass = "popup";
66  }
67  else if("verbose".equals(tokens[currToken])) {
68  verbosePath = true;
69  }
70  else if("hidden".equals(tokens[currToken])) {
71  hidden = true;
72  }
73  else if("external".equals(tokens[currToken])) {
74  external = true;
75  }
76  else if("parent".equals(tokens[currToken])) {
77  root = root.getParent();
78  }
79  else if("root".equals(tokens[currToken])) {
80  root = ElContextMap.getContext("/");
81  }
82  else if("locate".equals(tokens[currToken])) {
83  if(tokens.length > currToken + 1) {
84  root = ElContextMap.getContext(tokens[currToken + 1].replace("*", constructor.getRenderingContext().getPath()));
85  currToken++;
86  }
87  }
88  else if("match".equals(tokens[currToken])) {
89  if(tokens.length > currToken + 1) {
90  root = getSingleContextFrom(root, tokens[currToken + 1]);
91  currToken++;
92  }
93  }
94  else if("level".equals(tokens[currToken])) {
95  if(tokens.length > currToken + 1) {
96  root = getLevelContextFrom(root, tokens[currToken + 1]);
97  currToken++;
98  }
99  }
100  else if("children".equals(tokens[currToken])) {
101  result = new ArrayList(root.getChildren());
102  break;
103  }
104  else if("all".equals(tokens[currToken])) {
105  result = getAllFrom(root, false);
106  break;
107  }
108  else if("leaf".equals(tokens[currToken])) {
109  result = getAllFrom(root, true);
110  break;
111  }
112  else if("ancestors".equals(tokens[currToken])) {
113  result = new ArrayList(root.getAncestors());
114  break;
115  }
116  else if("siblings".equals(tokens[currToken])) {
117  result = new ArrayList(root.getSiblings());
118  break;
119  }
120  else if("search".equals(tokens[currToken])) {
121  if(tokens.length > currToken + 1) {
122  result = getContextsFrom(root, tokens[currToken + 1]);
123  break;
124  }
125  }
126  else if("self".equals(tokens[currToken])) {
127  result = new ArrayList<>();
128  result.add(root);
129  break;
130  }
131  currToken++;
132  }
133  HTMLHelper hh = new HTMLHelper(out);
134  boolean list = "list".equals(tokens[0]);
135  if(result != null && !result.isEmpty()) {
136  if(list) {
137  hh.startTag("ul", "class='m_list'");
138  } else if(result.size() > 1) {
139  hh.write("[ ");
140  }
141  for(ElContext ctx : result) {
142  if(hidden || ctx.canDisplay()) {
143  if(list) {
144  hh.startTag("li");
145  }
146  if(external) {
147  hh.startExtAnchor(ctx.getWebPath(), null);
148  } else {
149  if(Strings.isBlank(ctx.getTarget()) || !Strings.isBlank(clickAction)) {
150  hh.startAnchor(ctx.getWebPath(), null, cssClass, clickAction);
151  } else {
152  hh.startTargetAnchor(ctx.getWebPath(), ctx.getTarget(), null);
153  }
154  }
155  if(verbosePath) {
156  hh.write(ctx.getVerbosePath(root));
157  } else {
158  hh.write(ctx.getName());
159  }
160  hh.endTag();
161  if(list) {
162  hh.endTag();
163  } else if(result.lastIndexOf(ctx) < result.size() - 1) {
164  hh.write(", ");
165  }
166  }
167  }
168  if(!list && result.size() > 1) {
169  hh.write(" ]");
170  }
171  hh.endAllTags();
172  } else {
173  hh.startTag((list ? "div" : "span"), "class='m_error'");
174  hh.write(getMacroName());
175  hh.endTag();
176  }
177  done = true;
178  } else if("navigator".equals(getMacroName())) {
180  Navigator navigator = new Navigator(root);
181  navigator.setDynamicLoad("dynamic".equals(ElephantContext.getContextLoad()));
182  if("location".equals(getToken(1))) {
183  try {
184  navigator.setType(NavigatorType.LOCATION);
185  navigator.initialize();
186  navigator.draw();
187  } catch (IOException ex) {
188  Logger.getLogger(NavigationParser.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
189  }
190  } else if("traversal".equals(getToken(1))) {
191  try {
192  navigator.setType(NavigatorType.TRAVERSAL);
193  navigator.setShowTitle((Boolean) ObjectString.parseNativeString(getToken(2), Boolean.class, true));
194  navigator.initialize();
195  navigator.draw();
196  } catch (IOException ex) {
197  Logger.getLogger(NavigationParser.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
198  }
199  } else if("options".equals(getToken(1))) {
200  navigator.setType(NavigatorType.OPTIONS);
201  navigator.setDrawDecorators((Boolean) ObjectString.parseNativeString(getToken(2), Boolean.class, true));
202  navigator.setLevel((Integer) ObjectString.parseNativeString(getToken(3), Integer.class, true));
203  navigator.setPreloaded((Integer) ObjectString.parseNativeString(getToken(4), Integer.class, true));
204  navigator.setShowCurrent((Boolean) ObjectString.parseNativeString(getToken(5), Boolean.class, true));
205  navigator.initialize();
206  try {
207  navigator.draw();
208  } catch (IOException ex) {
209  Logger.getLogger(NavigationParser.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
210  }
211  } else if("tabulator".equals(getToken(1))) {
212  try {
213  navigator.setType(NavigatorType.TABULATOR);
214  navigator.setLevel((Integer) ObjectString.parseNativeString(getToken(2), Integer.class, true));
215  navigator.initialize();
216  navigator.draw();
217  } catch (IOException ex) {
218  Logger.getLogger(NavigationParser.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
219  }
220  }
221  done = true;
222  } else if("webmap".equals(getMacroName())) {
223  WebMap wm = new WebMap(constructor);
224  try {
225  wm.draw((Integer) ObjectString.parseNativeString(getToken(1), Integer.class, true));
226  } catch (IOException ex) {
227  Logger.getLogger(CoreParser.class.getName()).log(Level.SEVERE, ElephantContext.logMsg(null), ex);
228  }
229  done = true;
230  }
231  return done;
232  }
233 
234  @Override
235  protected void explainMacros(ParserMacroSet macros) {
236  macros.addMacro("navigator")
237  .addParameter("location", false);
238  macros.addMacro("navigator")
239  .addParameter("traversal", false)
240  .addParameter("show-title", true, "false");
241  macros.addMacro("navigator")
242  .addParameter("options", false)
243  .addParameter("decorators", false)
244  .addParameter("level", false)
245  .addParameter("preloaded", false)
246  .addParameter("show-current", true, "true");
247  macros.addMacro("navigator")
248  .addParameter("tabulator", false)
249  .addParameter("level", false);
250  macros.addMacro("webmap")
251  .addParameter("level", true, "1");
252  macros.addMacro("list")
253  .addParameter("behavioural_keywords", false, null, true)
254  .addPossibleValue("verbose")
255  .addPossibleValue("popup")
256  .addPossibleValue("hidden")
257  .addPossibleValue("external")
258  .addParameter("navigational_keywords", false, null, true)
259  .addPossibleValue("parent")
260  .addPossibleValue("root")
261  .addPossibleValue("level")
262  .addPossibleValue("locate")
263  .addPossibleValue("match")
264  .addParameter("selection_keywords", false, null, true)
265  .addPossibleValue("self")
266  .addPossibleValue("children")
267  .addPossibleValue("all")
268  .addPossibleValue("leaf")
269  .addPossibleValue("ancestors")
270  .addPossibleValue("siblings")
271  .addPossibleValue("search");
272  macros.addMacro("anchor")
273  .copyParametersFrom("list", macros);
274  }
275 
276  private static List<ElContext> getAllFrom(ElContext root, boolean leaf) {
277  ArrayList v = new ArrayList();
278  processContext(root, v, leaf, false);
279  return v;
280  }
281 
282  private static void processContext(ElContext root, Collection v, boolean leaf, boolean addRoot) {
283  Set<ElContext> children = root.getChildren();
284  if(addRoot && (!leaf || (leaf && children.isEmpty()))) {
285  v.add(root);
286  }
287  for(ElContext c : children) {
288  processContext(c, v, leaf, true);
289  }
290  }
291 
292  private static ElContext getLevelContextFrom(ElContext root, String level) {
293  ElContext[] ctxs = root.getAncestors().toArray(new ElContext[0]);
294  int idx = Integer.valueOf(level);
295  if(idx < ctxs.length) {
296  return ctxs[idx];
297  } else if(ctxs.length > 0) {
298  return ctxs[ctxs.length - 1];
299  } else {
300  return root;
301  }
302  }
303 
304  private static List<ElContext> getContextsFrom(ElContext root, String regExp) {
305  ArrayList v = new ArrayList();
306  processSearchFrom(root, regExp, v);
307  return v;
308  }
309 
310  private static ElContext getSingleContextFrom(ElContext root, String regExp) {
311  return processSingleSearchFrom(root, regExp);
312  }
313 
314  private static void processSearchFrom(ElContext root, String regExp, Collection v) {
315  for(ElContext ctx : root.getChildren()) {
316  if(ctx.getId().matches(regExp)) {
317  v.add(ctx);
318  }
319  processSearchFrom(ctx, regExp, v);
320  }
321  }
322 
323  private static ElContext processSingleSearchFrom(ElContext root, String regExp) {
324  for(ElContext ctx : root.getChildren()) {
325  if(ctx.getId().matches(regExp)) {
326  return ctx;
327  }
328  ctx = processSingleSearchFrom(ctx, regExp);
329  if(ctx != null) return ctx;
330  }
331  return null;
332  }
333 
334  public static String escapeGrouping(String sequence) {
335  if(sequence == null || !sequence.contains("$")) return sequence;
336  StringBuilder sb = new StringBuilder(sequence);
337  int start = 0, p;
338  while((p = sb.indexOf("$", start)) > -1) {
339  sb.insert(p, '\\');
340  start = p + 2;
341  }
342  return sb.toString();
343  }
344 
345 }
void setDrawDecorators(boolean drawDecorators)
Definition: Navigator.java:324
void setDynamicLoad(boolean dynamicLoad)
Definition: Navigator.java:340
void setShowCurrent(boolean showCurrent)
Definition: Navigator.java:356
static ElContext getContext(IConstructor constructor)
TreeSet< ElContext > getChildren()
Definition: ElContext.java:196
TreeSet< ElContext > getSiblings()
Definition: ElContext.java:217
TreeSet< ElContext > getAncestors()
Definition: ElContext.java:235
HTMLGenerator startTag(String tag)
HTMLGenerator startTargetAnchor(String url, String target, String hint)
HTMLGenerator startExtAnchor(String url, String hint)
HTMLGenerator startAnchor(String url, String hint)
HTMLGenerator write(String value)
Definition: HTMLHelper.java:69
static String escapeGrouping(String sequence)
void explainMacros(ParserMacroSet macros)
ParserMacro addMacro(String macroName)
ParserMacro addPossibleValue(String value)
void copyParametersFrom(String macroName, ParserMacroSet macros)
ParserMacro addParameter(String name, boolean optional)