001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.ade.configuration; 029 030import org.opencms.ade.configuration.formatters.CmsFormatterConfigurationCacheState; 031import org.opencms.util.CmsUUID; 032import org.opencms.xml.containerpage.I_CmsFormatterBean; 033 034import java.util.ArrayList; 035import java.util.Collection; 036import java.util.Collections; 037import java.util.HashMap; 038import java.util.Iterator; 039import java.util.List; 040import java.util.Map; 041 042import org.apache.commons.lang3.builder.ReflectionToStringBuilder; 043import org.apache.commons.lang3.builder.ToStringStyle; 044 045/** 046 * Helper class for computing dynamic function availability based on sitemap configuration settings. 047 */ 048public class CmsFunctionAvailability { 049 050 /** The formatter configuration state. */ 051 private CmsFormatterConfigurationCacheState m_formatterConfig; 052 053 /** The map of states for dynamic functions - true for explicitly added functions, false for explicitly removed functions (unless there is a whitelist and they are not in it. */ 054 private Map<CmsUUID, Boolean> m_functionStates = new HashMap<>(); 055 056 /** True if whitelisting has been enabled. */ 057 private boolean m_hasWhitelist; 058 059 /** 060 * Create a new instance. 061 * 062 * @param formatterConfig the formatter configuration state 063 */ 064 public CmsFunctionAvailability(CmsFormatterConfigurationCacheState formatterConfig) { 065 066 m_formatterConfig = formatterConfig; 067 } 068 069 /** 070 * Adds a dynamic function id and enables whitelisting. 071 * 072 * @param functionId the function id to add 073 */ 074 public void add(CmsUUID functionId) { 075 076 if (m_hasWhitelist) { 077 // If we have a whitelist, and we explicitly add a function, 078 // remove all whitelisted functions with the same key. 079 I_CmsFormatterBean functionFormatter = m_formatterConfig.getFormatters().get(functionId); 080 if ((functionFormatter != null) && (functionFormatter.getKey() != null)) { 081 String key = functionFormatter.getKey(); 082 Iterator<Map.Entry<CmsUUID, Boolean>> iter = m_functionStates.entrySet().iterator(); 083 while (iter.hasNext()) { 084 Map.Entry<CmsUUID, Boolean> entry = iter.next(); 085 CmsUUID id = entry.getKey(); 086 I_CmsFormatterBean existingBean = m_formatterConfig.getFormatters().get(id); 087 if ((existingBean != null) && key.equals(existingBean.getKey())) { 088 iter.remove(); 089 } 090 } 091 092 } 093 } 094 m_hasWhitelist = true; 095 m_functionStates.put(functionId, Boolean.TRUE); 096 } 097 098 /** 099 * Adds all ids from the given collection. 100 * 101 * @param enabledIds the ids to add 102 */ 103 public void addAll(Collection<CmsUUID> enabledIds) { 104 105 for (CmsUUID id : enabledIds) { 106 add(id); 107 } 108 } 109 110 /** 111 * Check if the function with the given id is available with this configuration. 112 * 113 * @param id the id to check 114 * @return true if the function is available 115 */ 116 public boolean checkAvailable(CmsUUID id) { 117 118 Boolean state = m_functionStates.get(id); 119 if (state != null) { 120 return state.booleanValue(); 121 } else { 122 return !m_hasWhitelist; 123 } 124 } 125 126 /** 127 * Gets the blacklist of explicitly removed functions that are not already covered by not being in a whitelist. 128 * 129 * @return the list of explicitly removed functions 130 */ 131 public Collection<CmsUUID> getBlacklist() { 132 133 List<CmsUUID> result = new ArrayList<>(); 134 for (Map.Entry<CmsUUID, Boolean> entry : m_functionStates.entrySet()) { 135 if (!entry.getValue().booleanValue()) { 136 result.add(entry.getKey()); 137 } 138 } 139 Collections.sort(result); 140 return result; 141 } 142 143 /** 144 * Gets the whitelist of explicitly enabled functions. 145 * 146 * <p>If no functions have been explicitly added, and no "remove all" option has been used, this will return null. 147 * 148 * @return the whitelist of functions 149 */ 150 public Collection<CmsUUID> getWhitelist() { 151 152 if (!m_hasWhitelist) { 153 return null; 154 } 155 List<CmsUUID> result = new ArrayList<>(); 156 for (Map.Entry<CmsUUID, Boolean> entry : m_functionStates.entrySet()) { 157 if (entry.getValue().booleanValue()) { 158 result.add(entry.getKey()); 159 } 160 } 161 Collections.sort(result); 162 return result; 163 164 } 165 166 /** 167 * Checks if this object has any restrictions on functions. 168 * 169 * @return true if this has any restrictions on functions 170 */ 171 public boolean isDefined() { 172 173 return m_hasWhitelist || (m_functionStates.size() > 0); 174 } 175 176 /** 177 * Removes a single function. 178 * 179 * @param functionId the id of the function 180 */ 181 public void remove(CmsUUID functionId) { 182 183 if (m_hasWhitelist) { 184 m_functionStates.remove(functionId); 185 } else { 186 m_functionStates.put(functionId, Boolean.FALSE); 187 } 188 } 189 190 /** 191 * Removes all functions and enables the whitelist. 192 */ 193 public void removeAll() { 194 195 m_hasWhitelist = true; 196 m_functionStates.clear(); 197 } 198 199 /** 200 * @see java.lang.Object#toString() 201 */ 202 @Override 203 public String toString() { 204 205 return ReflectionToStringBuilder.toString(this, ToStringStyle.SHORT_PREFIX_STYLE); 206 } 207 208}