possibility to use CSS prefix for menu items
[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 {
21
22         private String matchingPattern;
23         private final Map<Locale, String> localeToTitle = new HashMap<Locale, String>();
24         ArrayList<NavigationItem> subElements = new ArrayList<NavigationItem>();
25         private Locale[] localeOrder;
26         private NavigationItem parent;
27         private final String linkUrl;
28
29         /**
30          * CSS prefix is inherited to child menu items.
31          */
32         private String cssPrefix;
33
34         public NavigationItem(final Locale... localeOrder) {
35                 if (localeOrder.length == 0)
36                         this.localeOrder = new Locale[] { Locale.ENG };
37                 else
38                         this.localeOrder = localeOrder;
39
40                 matchingPattern = null;
41                 linkUrl = null;
42         }
43
44         public NavigationItem(final NavigationItem parent, final String linkUrl,
45                         final String... titles) {
46                 this.parent = parent;
47                 this.linkUrl = linkUrl;
48                 matchingPattern = linkUrl;
49
50                 initializeLocalizedTitles(titles);
51         }
52
53         public NavigationItem addChild(final String linkUrl, final String... titles) {
54
55                 final NavigationItem item = new NavigationItem(this, linkUrl, titles);
56                 subElements.add(item);
57
58                 return item;
59         }
60
61         protected String getCssPrefix() {
62                 if (cssPrefix != null)
63                         return cssPrefix;
64
65                 if (parent == null)
66                         return null;
67
68                 return parent.getCssPrefix();
69         }
70
71         public String getLinkUrl() {
72                 return linkUrl;
73         }
74
75         public Locale[] getLocaleOrder() {
76                 if (localeOrder != null)
77                         return localeOrder;
78
79                 return parent.getLocaleOrder();
80         }
81
82         NavigationItem getMatchingNavigationItem(final String requestPath) {
83                 if (matchesUrl(requestPath))
84                         return this;
85
86                 for (final NavigationItem childNavigationItem : subElements) {
87                         final NavigationItem match = childNavigationItem
88                                         .getMatchingNavigationItem(requestPath);
89
90                         if (match != null)
91                                 return match;
92                 }
93                 return null;
94         }
95
96         public List<NavigationItem> getSubElements() {
97                 return subElements;
98         }
99
100         public String getTitle() {
101                 if (localeToTitle.size() != 1)
102                         throw new RuntimeException("there shall be exactly one title");
103
104                 return localeToTitle.values().iterator().next();
105         }
106
107         public String getTitle(final Locale locale) {
108                 return localeToTitle.get(locale);
109         }
110
111         private void initializeLocalizedTitles(final String... titles) {
112                 final Locale[] locales = getLocaleOrder();
113                 if (locales.length != titles.length)
114                         throw new RuntimeException("There should be exactly "
115                                         + locales.length + " title(s).");
116
117                 for (int i = 0; i < titles.length; i++)
118                         localeToTitle.put(locales[i], titles[i]);
119         }
120
121         public boolean matchesUrl(final String url) {
122                 return WildCardMatcher.match(url, matchingPattern);
123         }
124
125         public void setCssPrefix(final String cssPrefix) {
126                 this.cssPrefix = cssPrefix;
127         }
128
129         public NavigationItem setPattern(final String pattern) {
130                 matchingPattern = pattern;
131                 return this;
132         }
133
134 }