16e07080311d85a5d8559b0a2da85bd6d7786db2
[svjatoslav_commons.git] / src / main / java / eu / svjatoslav / commons / network / navigation / NavigationItem.java
1 /*
2  * Svjatoslav Commons - shared library of common functionality.
3  * Copyright ©2012-2014, Svjatoslav Agejenko, svjatoslav@svjatoslav.eu
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 3 of the GNU Lesser General Public License
7  * or later as published by the Free Software Foundation.
8  */
9
10 package eu.svjatoslav.commons.network.navigation;
11
12 import eu.svjatoslav.commons.string.WildCardMatcher;
13
14 import java.util.ArrayList;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18
19 public class NavigationItem {
20
21     private final Map<String, String> localeToTitle = new HashMap<>();
22     private final ArrayList<NavigationItem> subElements = new ArrayList<>();
23     private final NavigationItem parent;
24     private final Navigation<? extends NavigationItem> navigation;
25     private final String linkUrl;
26     private String matchingPattern;
27     /**
28      * CSS prefix is inherited to child menu items.
29      */
30     private String cssPrefix;
31
32     /**
33      * Used to build root navigation item.
34      */
35     public NavigationItem(final Navigation<? extends NavigationItem> navigation) {
36         this.navigation = navigation;
37         parent = null;
38         matchingPattern = null;
39         linkUrl = null;
40     }
41
42     public NavigationItem(final NavigationItem parent, final String linkUrl, final String... titles) {
43
44         navigation = parent.getNavigation();
45         this.parent = parent;
46         this.linkUrl = linkUrl;
47         matchingPattern = linkUrl;
48
49         initializeLocalizedTitles(titles);
50
51         parent.addNavigationItem(this);
52     }
53
54     public void addNavigationItem(final NavigationItem navigationItem) {
55         subElements.add(navigationItem);
56     }
57
58     protected String getCssPrefix() {
59         if (cssPrefix != null)
60             return cssPrefix;
61
62         if (parent == null)
63             return null;
64
65         return parent.getCssPrefix();
66     }
67
68     public void setCssPrefix(final String cssPrefix) {
69         this.cssPrefix = cssPrefix;
70     }
71
72     public String getLinkUrl() {
73         return linkUrl;
74     }
75
76     NavigationItem getMatchingNavigationItem(final String requestPath) {
77         if (matchesUrl(requestPath))
78             return this;
79
80         for (final NavigationItem childNavigationItem : subElements) {
81             final NavigationItem match = childNavigationItem.getMatchingNavigationItem(requestPath);
82
83             if (match != null)
84                 return match;
85         }
86         return null;
87     }
88
89     public Navigation<? extends NavigationItem> getNavigation() {
90         return navigation;
91     }
92
93     public List<NavigationItem> getSubElements() {
94         return subElements;
95     }
96
97     public String getTitle(final String locale) {
98         return localeToTitle.get(locale);
99     }
100
101     private void initializeLocalizedTitles(final String... titles) {
102         final List<String> locales = getNavigation().getLocaleConfiguration().getAllowedLocales();
103         if (locales.size() != titles.length)
104             throw new RuntimeException("There should be exactly " + locales.size() + " title(s).");
105
106         for (int i = 0; i < titles.length; i++)
107             localeToTitle.put(locales.get(i), titles[i]);
108     }
109
110     public boolean matchesUrl(final String url) {
111         return WildCardMatcher.match(url, matchingPattern);
112     }
113
114     public NavigationItem setPattern(final String pattern) {
115         matchingPattern = pattern;
116         return this;
117     }
118
119     @Override
120     public String toString() {
121         return "NavigationItem [matchingPattern=" + matchingPattern + ", localeToTitle=" + localeToTitle
122                 + ", subElements count=" + subElements.size() + ", linkUrl=" + linkUrl + ", cssPrefix=" + cssPrefix
123                 + "]";
124     }
125
126 }