Java tutorial
/* * Copyright (C) 2005-2012 BetaCONCEPT Limited * * This file is part of Astroboa. * * Astroboa is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Astroboa is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Astroboa. If not, see <http://www.gnu.org/licenses/>. */ package org.betaconceptframework.astroboa.cache; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.StringUtils; import org.betaconceptframework.astroboa.api.model.ValueType; import org.betaconceptframework.astroboa.api.model.definition.CmsDefinition; import org.betaconceptframework.astroboa.api.model.definition.CmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.definition.ComplexCmsPropertyDefinition; import org.betaconceptframework.astroboa.api.model.definition.ContentObjectTypeDefinition; import org.betaconceptframework.astroboa.context.AstroboaClientContextHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author Gregory Chomatas (gchomatas@betaconcept.com) * @author Savvas Triantafyllou (striantafyllou@betaconcept.com) * */ public class DefinitionCacheManager { private final Logger logger = LoggerFactory.getLogger(DefinitionCacheManager.class); //This map holds definitions for all repositories //First key is repository id //Second Key is ValueType of Definition //Third key is property name private Map<String, Map<ValueType, Map<String, CmsDefinition>>> definitionCache = new ConcurrentHashMap<String, Map<ValueType, Map<String, CmsDefinition>>>(); public void clearAllDefinitionsForCurrentRepository() { clearAllDefinitionsForRepository(AstroboaClientContextHolder.getActiveRepositoryId()); } public CmsDefinition getPropertyDefinition(ValueType valueType, String propertyName) { Map<String, CmsDefinition> map = getPropertyDefinitionsForValueType(valueType); if (map != null) return map.get(propertyName); return null; } public Map<String, CmsDefinition> getPropertyDefinitionsForValueType(ValueType valueType) { String currentRepositoryId = AstroboaClientContextHolder.getActiveRepositoryId(); if (StringUtils.isNotBlank(currentRepositoryId) && definitionCache.containsKey(currentRepositoryId)) { Map<ValueType, Map<String, CmsDefinition>> currentRepositoryCache = definitionCache .get(currentRepositoryId); if (!currentRepositoryCache.containsKey(valueType)) return null; return currentRepositoryCache.get(valueType); } return null; } public void addPropertyDefinitionsForValueType(ValueType valueType, Map<String, CmsDefinition> propertyDefinitions) { if (MapUtils.isNotEmpty(propertyDefinitions)) { for (Entry<String, CmsDefinition> propertyDefinition : propertyDefinitions.entrySet()) { addPropertyDefinition(valueType, propertyDefinition.getKey(), propertyDefinition.getValue()); } } } public void addPropertyDefinition(ValueType valueType, String propertyName, CmsDefinition propertyDefinition) { String currentRepositoryId = AstroboaClientContextHolder.getActiveRepositoryId(); if (StringUtils.isNotBlank(currentRepositoryId)) { if (!definitionCache.containsKey(currentRepositoryId)) { definitionCache.put(currentRepositoryId, new ConcurrentHashMap<ValueType, Map<String, CmsDefinition>>()); } Map<ValueType, Map<String, CmsDefinition>> currentRepositoryCache = definitionCache .get(currentRepositoryId); if (!currentRepositoryCache.containsKey(valueType)) currentRepositoryCache.put(valueType, new ConcurrentHashMap<String, CmsDefinition>()); currentRepositoryCache.get(valueType).put(propertyName, propertyDefinition); } } public boolean atLeastOneDefinitionExistsForValueType(ValueType valueType) { String currentRepositoryId = AstroboaClientContextHolder.getActiveRepositoryId(); if (StringUtils.isNotBlank(currentRepositoryId)) { return definitionCache.containsKey(currentRepositoryId) && definitionCache.get(currentRepositoryId).containsKey(valueType); } return false; } public boolean definitionExistsForProperty(ValueType valueType, String propertyName) { String currentRepositoryId = AstroboaClientContextHolder.getActiveRepositoryId(); if (StringUtils.isNotBlank(currentRepositoryId)) { return definitionCache.containsKey(currentRepositoryId) //Definitions for repository must exist && definitionCache.get(currentRepositoryId).containsKey(valueType) //Definitions for provided value type must exist && definitionCache.get(currentRepositoryId).get(valueType).containsKey(propertyName); //Definition for provided property must exist } return false; } public void printDefinitionsToLog() { if (logger.isDebugEnabled()) { StringBuilder sb = new StringBuilder(); //Detailed debug info for all definition tree Set<Entry<String, Map<ValueType, Map<String, CmsDefinition>>>> definitionsPerRepository = definitionCache .entrySet(); for (Entry<String, Map<ValueType, Map<String, CmsDefinition>>> repositoryDefinitions : definitionsPerRepository) { sb.append("Definitions for repository ").append(repositoryDefinitions.getKey()); Map<ValueType, Map<String, CmsDefinition>> definitions = repositoryDefinitions.getValue(); for (Entry<ValueType, Map<String, CmsDefinition>> definitionForValueType : definitions.entrySet()) { if (ValueType.ContentType == definitionForValueType.getKey() || ValueType.Complex == definitionForValueType.getKey()) { printDefinitions(definitionForValueType.getValue(), 0, sb); } } } logger.debug("{}", sb.toString()); } } private void printDefinitions(Map<String, CmsDefinition> cmsPropertyDefinitions, int depth, StringBuilder sb) { String tabs = generateTabs(depth); if (MapUtils.isNotEmpty(cmsPropertyDefinitions)) { for (CmsDefinition def : cmsPropertyDefinitions.values()) { sb.append(tabs).append(def.getName()).append(", instance ").append(System.identityHashCode(def)); if (def instanceof ContentObjectTypeDefinition) { printPropertyDefinitions(((ContentObjectTypeDefinition) def).getPropertyDefinitions(), depth + 1, sb); } else if (def instanceof ComplexCmsPropertyDefinition) { printPropertyDefinitions(((ComplexCmsPropertyDefinition) def).getChildCmsPropertyDefinitions(), depth + 1, sb); } } } } private String generateTabs(int depth) { StringBuilder tabs = new StringBuilder(); for (int i = 0; i < depth; i++) { tabs.append("\t"); } return tabs.toString(); } private void printPropertyDefinitions(Map<String, CmsPropertyDefinition> cmsPropertyDefinitions, int depth, StringBuilder sb) { String tabs = generateTabs(depth); if (MapUtils.isNotEmpty(cmsPropertyDefinitions)) { for (CmsPropertyDefinition def : cmsPropertyDefinitions.values()) { sb.append(tabs).append(def.getName()).append(", instance ").append(System.identityHashCode(def)); if (def instanceof ContentObjectTypeDefinition) { printPropertyDefinitions(((ContentObjectTypeDefinition) def).getPropertyDefinitions(), depth + 1, sb); } else if (def instanceof ComplexCmsPropertyDefinition) { if (def.getName().equals(def.getParentDefinition().getName())) { //Child definition is the same. Detected a recursion sb.append(tabs).append("\t Detecting recursion "); } else { printPropertyDefinitions( ((ComplexCmsPropertyDefinition) def).getChildCmsPropertyDefinitions(), depth + 1, sb); } } } } } public void clearAllDefinitionsForRepository(String repositoryId) { if (StringUtils.isNotBlank(repositoryId) && definitionCache.containsKey(repositoryId)) { definitionCache.get(repositoryId).clear(); } } }