/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.sling.commons.cache.impl; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import org.apache.commons.io.IOUtils; import org.apache.sling.commons.cache.api.Cache; import org.apache.sling.commons.cache.api.CacheManagerService; import org.apache.sling.commons.cache.api.CacheScope; /** * The <code>AbstractCacheManagerService</code> */ public abstract class AbstractCacheManagerService implements CacheManagerService { private ThreadLocalCacheMap requestCacheMapHolder = new ThreadLocalCacheMap(); private ThreadLocalCacheMap threadCacheMapHolder = new ThreadLocalCacheMap(); public AbstractCacheManagerService() throws IOException { } /** * {@inheritDoc} * * @see org.apache.sling.commons.cache.api.CacheManagerService#getCache(java.lang.String) */ public <V> Cache<V> getCache(String name, CacheScope scope) { switch (scope) { case INSTANCE: return getInstanceCache(name); case CLUSTERINVALIDATED: return getInstanceCache(name); case CLUSTERREPLICATED: return getInstanceCache(name); case REQUEST: return getRequestCache(name); case THREAD: return getThreadCache(name); default: return getInstanceCache(name); } } /** * Generate a cache bound to the thread. * * @param name * @return */ @SuppressWarnings("unchecked") protected <V> Cache<V> getThreadCache(String name) { Map<String, Cache<?>> threadCacheMap = threadCacheMapHolder.get(); Cache<V> threadCache = (Cache<V>) threadCacheMap.get(name); if (threadCache == null) { threadCache = new MapCacheImpl<V>(); threadCacheMap.put(name, threadCache); } return threadCache; } /** * Generate a cache bound to the request * * @param name * @return */ @SuppressWarnings("unchecked") protected <V> Cache<V> getRequestCache(String name) { Map<String, Cache<?>> requestCacheMap = requestCacheMapHolder.get(); Cache<V> requestCache = (Cache<V>) requestCacheMap.get(name); if (requestCache == null) { requestCache = new MapCacheImpl<V>(); requestCacheMap.put(name, requestCache); } return requestCache; } /** * @param name * @return */ protected abstract <V> Cache<V> getInstanceCache(String name); /** * {@inheritDoc} * * @see org.apache.sling.commons.cache.api.CacheManagerService#unbind(org.apache.sling.commons.cache.api.CacheScope) */ public void unbind(CacheScope scope) { switch (scope) { case REQUEST: unbindRequest(); break; case THREAD: unbindThread(); break; default: break; } } /** * */ private void unbindThread() { Map<String, Cache<?>> threadCache = threadCacheMapHolder.get(); for (Cache<?> cache : threadCache.values()) { cache.clear(); } threadCacheMapHolder.remove(); } /** * */ private void unbindRequest() { Map<String, Cache<?>> requestCache = requestCacheMapHolder.get(); for (Cache<?> cache : requestCache.values()) { cache.clear(); } requestCacheMapHolder.remove(); } protected String toString(Object object, String defaultValue) { if (object == null) { return defaultValue; } return String.valueOf(object); } protected InputStream processConfig(InputStream in, Map<String, Object> properties) throws IOException { if (in == null) { return null; } StringBuilder config = new StringBuilder(IOUtils.toString(in, "UTF-8")); in.close(); int pos = 0; for (;;) { int start = config.indexOf("${", pos); if (start < 0) { break; } int end = config.indexOf("}", start); if (end < 0) { throw new IllegalArgumentException( "Config file malformed, unterminated variable " + config.substring(start, Math.min(start + 10, config.length()))); } String key = config.substring(start + 2, end); if (properties.containsKey(key)) { String replacement = (String) properties.get(key); config.replace(start, end + 1, replacement); pos = start + replacement.length(); } else { throw new IllegalArgumentException( "Missing replacement property " + key); } } return new ByteArrayInputStream(config.toString().getBytes("UTF-8")); } }