/*
* (C) Copyright 2014-2016 Nuxeo SA (http://nuxeo.com/) and others.
*
* 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.
*
* Contributors:
* Maxime Hilaire
* Thierry Martins
*
*/
package org.nuxeo.ecm.core.cache;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.nuxeo.runtime.api.Framework;
import org.nuxeo.runtime.model.ComponentContext;
import org.nuxeo.runtime.model.ComponentInstance;
import org.nuxeo.runtime.model.ComponentName;
import org.nuxeo.runtime.model.DefaultComponent;
import org.nuxeo.runtime.model.Extension;
/**
* Cache service implementation to manage nuxeo cache
*
* @since 6.0
*/
public class CacheServiceImpl extends DefaultComponent implements CacheService {
/**
* @since 8.2
*/
public static final String DEFAULT_CACHE_ID = "default-cache";
public static final ComponentName NAME = new ComponentName(CacheServiceImpl.class.getName());
private static final Log log = LogFactory.getLog(CacheServiceImpl.class);
protected final CacheRegistry cacheRegistry = new CacheRegistry();
/**
* Contains the names of all caches which have not been registered from an extension
*/
protected final List<String> autoregisteredCacheNames = new ArrayList<String>();
@Override
public Cache getCache(String name) {
return cacheRegistry.getCache(name);
}
@Override
public void deactivate(ComponentContext context) {
if (cacheRegistry.caches.size() > 0) {
Map<String, CacheDescriptor> descriptors = new HashMap<String, CacheDescriptor>(cacheRegistry.caches);
for (CacheDescriptor desc : descriptors.values()) {
cacheRegistry.contributionRemoved(desc.name, desc);
if (!autoregisteredCacheNames.remove(desc.name)) {
log.warn("Unregistery leaked contribution " + desc.name);
}
}
}
}
@Override
public int getApplicationStartedOrder() {
ComponentInstance repositoryComponent = Framework.getRuntime().getComponentInstance(
"org.nuxeo.ecm.core.repository.RepositoryServiceComponent");
if (repositoryComponent == null || repositoryComponent.getInstance() == null) {
return super.getApplicationStartedOrder();
}
return ((DefaultComponent) repositoryComponent.getInstance()).getApplicationStartedOrder() - 5;
}
@Override
public void applicationStarted(ComponentContext context) {
cacheRegistry.start();
}
@Override
public void applicationStopped(ComponentContext context, Instant deadline) {
cacheRegistry.stop();
}
@Override
public void registerExtension(Extension extension) {
Object[] contribs = extension.getContributions();
for (Object contrib : contribs) {
CacheDescriptor descriptor = (CacheDescriptor) contrib;
registerCache(descriptor);
}
}
public void registerCache(CacheDescriptor descriptor) {
cacheRegistry.addContribution(descriptor);
}
@Override
public void registerCache(String name, int maxSize, int timeout) {
CacheDescriptor desc;
if (cacheRegistry.caches.get(DEFAULT_CACHE_ID) != null) {
desc = new CacheDescriptor(cacheRegistry.caches.get(DEFAULT_CACHE_ID));
} else {
desc = new CacheDescriptor();
}
desc.name = name;
desc.ttl = timeout;
desc.options.put("maxSize", String.valueOf(maxSize));
if (cacheRegistry.caches.get(name) == null) {
registerCache(desc);
autoregisteredCacheNames.add(name);
} else {
CacheDescriptor oldDesc = cacheRegistry.caches.get(name);
cacheRegistry.merge(oldDesc, desc);
}
}
@Override
public void unregisterExtension(Extension extension) throws RuntimeException {
Object[] contribs = extension.getContributions();
for (Object contrib : contribs) {
CacheDescriptor descriptor = (CacheDescriptor) contrib;
cacheRegistry.removeContribution(descriptor);
}
}
public void unregisterCache(CacheDescriptor descriptor) {
cacheRegistry.removeContribution(descriptor);
}
@Override
public <T> T getAdapter(Class<T> adapter) {
if (adapter.isAssignableFrom(CacheRegistry.class)) {
return adapter.cast(cacheRegistry);
}
return super.getAdapter(adapter);
}
}