/** * Copyright 2008 The University of North Carolina at Chapel Hill * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package edu.unc.lib.dl.ui.util; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Properties; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Manages configuration of the header menu, interpreting the heirarchy of the menu options into a tree of sub-menus. * * @author bbpennel * */ public class HeaderMenuSettings { private static final Logger LOG = LoggerFactory.getLogger(HeaderMenuSettings.class); public static Pattern entryMatcher = Pattern.compile("^menu\\.(\\w+)(\\.(label|url|entry|order|referer|target))?(\\.(\\w+).(label|url|referer))?$"); // The root node of the menu tree private HeaderMenu menuRoot; // Map containing placeholder keys to seek in the supplied properties, which will be replaced with the value private Map<String,String> replacementValues; private Properties properties; private String propertiesUrl; public HeaderMenuSettings() { this.menuRoot = new HeaderMenu("root"); } public void init() { this.menuRoot.getSubMenus().clear(); this.processProperties(); this.orderMenu(this.menuRoot); } /** * Processes the given properties file into the menu tree */ private void processProperties() { Iterator<Entry<Object, Object>> propertiesIt = properties.entrySet().iterator(); while (propertiesIt.hasNext()) { Entry<Object, Object> property = propertiesIt.next(); String key = (String) property.getKey(); Matcher keyMatcher = entryMatcher.matcher(key); if (keyMatcher.find()) { String menuName = keyMatcher.group(1); // Catch the ordering of the root element's children if ("order".equals(menuName)){ this.menuRoot.setOrder((String)property.getValue()); continue; } String entryValue = this.replaceValues((String)property.getValue()); HeaderMenu headerMenu = this.menuRoot.subMenus.get(menuName); if (headerMenu == null) { headerMenu = new HeaderMenu(menuName); this.menuRoot.subMenus.put(menuName, headerMenu); } HeaderMenu targetedMenu; String menuType = keyMatcher.group(3); if ("entry".equals(menuType)) { String subMenuName = keyMatcher.group(5); targetedMenu = headerMenu.getSubMenus().get(subMenuName); if (targetedMenu == null){ targetedMenu = new HeaderMenu(subMenuName); headerMenu.subMenus.put(subMenuName, targetedMenu); } menuType = keyMatcher.group(6); } else { // Updating the parent entry. targetedMenu = headerMenu; } if ("label".equals(menuType)) { targetedMenu.setLabel(entryValue); } else if ("url".equals(menuType)) { targetedMenu.setUrl(entryValue); } else if ("order".equals(menuType)) { targetedMenu.setOrder(entryValue); } else if ("referer".equals(menuType)) { targetedMenu.setIncludeReferer(entryValue); } else if ("target".equals(menuType)) { targetedMenu.setTarget(entryValue); } } } } private void orderMenu(HeaderMenu menuEntry) { if (menuEntry.getOrder() == null) return; Map<String, HeaderMenu> reorderedEntries = new LinkedHashMap<String, HeaderMenu>(); String[] orderKeys = menuEntry.getOrder().split(","); for (String orderKey: orderKeys) { HeaderMenu childEntry = menuEntry.getSubMenus().get(orderKey); reorderedEntries.put(orderKey, childEntry); this.orderMenu(childEntry); } menuEntry.setSubMenus(reorderedEntries); } public void setProperties(Properties properties) { this.properties = properties; } public void setReplacementValues(Map<String, String> replacementValues) { this.replacementValues = replacementValues; } /** * Replaces all strings matching {key} with the associated value for that key. * @param value * @return */ private String replaceValues(String value) { if (this.replacementValues == null) return value; for (Map.Entry<String, String> replacementEntry: this.replacementValues.entrySet()) { value = value.replace("{" + replacementEntry.getKey() + "}", replacementEntry.getValue()); } return value; } public HeaderMenu getMenuRoot() { return menuRoot; } @Override public String toString() { return "HeaderMenuSettings [menuRoot=" + menuRoot + ", replacementValues=" + replacementValues + ", properties=" + properties + ", propertiesUrl=" + propertiesUrl + "]"; } public static class HeaderMenu { private Map<String, HeaderMenu> subMenus; private String key; private String label; private String url; private String order; private String target; private boolean includeReferer; public HeaderMenu(String key) { this.key = key; this.subMenus = new LinkedHashMap<String, HeaderMenu>(); this.includeReferer = false; } public Map<String, HeaderMenu> getSubMenus() { return subMenus; } public void setSubMenus(Map<String, HeaderMenu> subMenus) { this.subMenus = subMenus; } public String getOrder() { return order; } public void setOrder(String order) { this.order = order; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public String getUrl() { return url; } public void setUrl(String url) { this.url = url; } public String getKey() { return this.key; } public boolean isIncludeReferer() { return includeReferer; } public void setIncludeReferer(boolean includeReferer) { this.includeReferer = includeReferer; } public void setIncludeReferer(String referer) { this.includeReferer = Boolean.parseBoolean(referer); } public String getTarget() { return target; } public void setTarget(String target) { this.target = target; } @Override public String toString() { return "HeaderMenu [subMenus=" + subMenus + ", key=" + key + ", label=" + label + ", url=" + url + ", order=" + order + "]"; } } }