76a7d073a674a7030db0b45ca0560f85f9ca3877
[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 java.util.ArrayList;
13 import java.util.HashMap;
14 import java.util.List;
15 import java.util.Map;
16
17 import eu.svjatoslav.commons.network.Locale;
18 import eu.svjatoslav.commons.string.WildCardMatcher;
19
20 public class NavigationItem<NI extends NavigationItem, N extends Navigation> {
21
22         private String matchingPattern;
23
24         private final Map<Locale, String> localeToTitle = new HashMap<Locale, String>();
25         private final ArrayList<NI> subElements = new ArrayList<NI>();
26         private final NI parent;
27         private final N navigation;
28         private final String linkUrl;
29         /**
30          * CSS prefix is inherited to child menu items.
31          */
32         private String cssPrefix;
33
34         public NavigationItem(final N navigation) {
35                 this.navigation = navigation;
36                 parent = null;
37                 matchingPattern = null;
38                 linkUrl = null;
39         }
40
41         public NavigationItem(final NI parent, final String linkUrl,
42                         final String... titles) {
43                 this.navigation = (N) parent.getNavigation();
44                 this.parent = parent;
45                 this.linkUrl = linkUrl;
46                 matchingPattern = linkUrl;
47
48                 initializeLocalizedTitles(titles);
49
50                 parent.addNavigationItem(this);
51         }
52
53         public void addNavigationItem(final NI navigationItem) {
54                 subElements.add(navigationItem);
55         }
56
57         protected String getCssPrefix() {
58                 if (cssPrefix != null)
59                         return cssPrefix;
60
61                 if (parent == null)
62                         return null;
63
64                 return parent.getCssPrefix();
65         }
66
67         public String getLinkUrl() {
68                 return linkUrl;
69         }
70
71         NI getMatchingNavigationItem(final String requestPath) {
72                 if (matchesUrl(requestPath))
73                         return (NI) this;
74
75                 for (final NI childNavigationItem : subElements) {
76                         final NI match = (NI) childNavigationItem
77                                         .getMatchingNavigationItem(requestPath);
78
79                         if (match != null)
80                                 return match;
81                 }
82                 return null;
83         }
84
85         public N getNavigation() {
86                 return navigation;
87         }
88
89         public List<NI> getSubElements() {
90                 return subElements;
91         }
92
93         public String getTitle(final Locale locale) {
94                 return localeToTitle.get(locale);
95         }
96
97         private void initializeLocalizedTitles(final String... titles) {
98                 final List<Locale> locales = getNavigation().getLocaleConfiguration()
99                                 .getAllowedLocales();
100                 if (locales.size() != titles.length)
101                         throw new RuntimeException("There should be exactly "
102                                         + locales.size() + " title(s).");
103
104                 for (int i = 0; i < titles.length; i++)
105                         localeToTitle.put(locales.get(i), titles[i]);
106         }
107
108         public boolean matchesUrl(final String url) {
109                 return WildCardMatcher.match(url, matchingPattern);
110         }
111
112         public void setCssPrefix(final String cssPrefix) {
113                 this.cssPrefix = cssPrefix;
114         }
115
116         public NavigationItem setPattern(final String pattern) {
117                 matchingPattern = pattern;
118                 return this;
119         }
120
121         @Override
122         public String toString() {
123                 return "NavigationItem [matchingPattern=" + matchingPattern
124                                 + ", localeToTitle=" + localeToTitle + ", subElements count="
125                                 + subElements.size() + ", linkUrl=" + linkUrl + ", cssPrefix="
126                                 + cssPrefix + "]";
127         }
128
129 }