001/* 002 * (C) Copyright 2014-2016 Nuxeo SA (http://nuxeo.com/) and others. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 * 016 * Contributors: 017 * Maxime Hilaire 018 * Thierry Martins 019 * 020 */ 021 022package org.nuxeo.ecm.core.cache; 023 024import java.util.ArrayList; 025import java.util.HashMap; 026import java.util.List; 027import java.util.Map; 028 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.nuxeo.runtime.RuntimeServiceEvent; 032import org.nuxeo.runtime.RuntimeServiceListener; 033import org.nuxeo.runtime.api.Framework; 034import org.nuxeo.runtime.model.ComponentContext; 035import org.nuxeo.runtime.model.ComponentInstance; 036import org.nuxeo.runtime.model.ComponentName; 037import org.nuxeo.runtime.model.DefaultComponent; 038import org.nuxeo.runtime.model.Extension; 039 040/** 041 * Cache service implementation to manage nuxeo cache 042 * 043 * @since 6.0 044 */ 045public class CacheServiceImpl extends DefaultComponent implements CacheService { 046 047 /** 048 * @since 8.2 049 */ 050 public static final String DEFAULT_CACHE_ID = "default-cache"; 051 052 public static final ComponentName NAME = new ComponentName(CacheServiceImpl.class.getName()); 053 054 private static final Log log = LogFactory.getLog(CacheServiceImpl.class); 055 056 protected final CacheRegistry cacheRegistry = new CacheRegistry(); 057 058 /** 059 * Contains the names of all caches which have not been registered from an extension 060 */ 061 protected final List<String> autoregisteredCacheNames = new ArrayList<String>(); 062 063 064 @Override 065 public CacheAttributesChecker getCache(String name) { 066 return cacheRegistry.getCache(name); 067 } 068 069 @Override 070 public void deactivate(ComponentContext context) { 071 if (cacheRegistry.caches.size() > 0) { 072 Map<String, CacheDescriptor> descriptors = new HashMap<String, CacheDescriptor>(cacheRegistry.caches); 073 for (CacheDescriptor desc : descriptors.values()) { 074 cacheRegistry.contributionRemoved(desc.name, desc); 075 if (!autoregisteredCacheNames.remove(desc.name)) { 076 log.warn("Unregistery leaked contribution " + desc.name); 077 } 078 } 079 } 080 } 081 082 @Override 083 public int getApplicationStartedOrder() { 084 ComponentInstance repositoryComponent = (ComponentInstance) Framework.getRuntime().getComponentInstance( 085 "org.nuxeo.ecm.core.repository.RepositoryServiceComponent"); 086 if (repositoryComponent == null) { 087 return super.getApplicationStartedOrder(); 088 } 089 return ((DefaultComponent) repositoryComponent.getInstance()).getApplicationStartedOrder() - 5; 090 } 091 092 @Override 093 public void applicationStarted(ComponentContext context) { 094 Framework.addListener(new RuntimeServiceListener() { 095 096 @Override 097 public void handleEvent(RuntimeServiceEvent event) { 098 if (RuntimeServiceEvent.RUNTIME_ABOUT_TO_START != event.id) { 099 return; 100 } 101 Framework.removeListener(this); 102 cacheRegistry.stop(); 103 } 104 }); 105 cacheRegistry.start(); 106 } 107 108 @Override 109 public void registerExtension(Extension extension) { 110 Object[] contribs = extension.getContributions(); 111 for (Object contrib : contribs) { 112 CacheDescriptor descriptor = (CacheDescriptor) contrib; 113 registerCache(descriptor); 114 } 115 } 116 117 public void registerCache(CacheDescriptor descriptor) { 118 cacheRegistry.addContribution(descriptor); 119 } 120 121 @Override 122 public void registerCache(String name, int maxSize, int timeout) { 123 CacheDescriptor desc; 124 if (cacheRegistry.caches.get(DEFAULT_CACHE_ID) != null) { 125 desc = new CacheDescriptor(cacheRegistry.caches.get(DEFAULT_CACHE_ID)); 126 } else { 127 desc = new CacheDescriptor(); 128 } 129 desc.name = name; 130 desc.ttl = timeout; 131 desc.options.put("maxSize", String.valueOf(maxSize)); 132 if (cacheRegistry.caches.get(name) == null) { 133 registerCache(desc); 134 autoregisteredCacheNames.add(name); 135 } else { 136 CacheDescriptor oldDesc = cacheRegistry.caches.get(name); 137 cacheRegistry.merge(oldDesc, desc); 138 } 139 } 140 141 @Override 142 public void unregisterExtension(Extension extension) throws RuntimeException { 143 Object[] contribs = extension.getContributions(); 144 for (Object contrib : contribs) { 145 CacheDescriptor descriptor = (CacheDescriptor) contrib; 146 cacheRegistry.removeContribution(descriptor); 147 } 148 } 149 150 public void unregisterCache(CacheDescriptor descriptor) { 151 cacheRegistry.removeContribution(descriptor); 152 } 153 154 155 @Override 156 public <T> T getAdapter(Class<T> adapter) { 157 if (adapter.isAssignableFrom(CacheRegistry.class)) { 158 return adapter.cast(cacheRegistry); 159 } 160 return super.getAdapter(adapter); 161 } 162}