001/* 002 * (C) Copyright 2017 Nuxeo (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 * Florent Guillaume 018 */ 019package org.nuxeo.ecm.core.storage.kv; 020 021import java.util.Map; 022import java.util.concurrent.ConcurrentHashMap; 023 024import org.apache.commons.logging.Log; 025import org.apache.commons.logging.LogFactory; 026import org.nuxeo.ecm.core.api.NuxeoException; 027import org.nuxeo.runtime.model.ComponentInstance; 028import org.nuxeo.runtime.model.DefaultComponent; 029 030/** 031 * Implementation for the Key/Value Service. 032 * 033 * @since 9.1 034 */ 035public class KeyValueServiceImpl extends DefaultComponent implements KeyValueService { 036 037 private static final Log log = LogFactory.getLog(KeyValueServiceImpl.class); 038 039 public static final String CONFIG_XP = "configuration"; 040 041 public static final String DEFAULT_STORE_ID = "default"; 042 043 protected final KeyValueStoreRegistry registry = new KeyValueStoreRegistry(); 044 045 protected Map<String, KeyValueStoreProvider> providers = new ConcurrentHashMap<>(); 046 047 protected KeyValueStore defaultStore = new MemKeyValueStore(); 048 049 @Override 050 public void registerContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 051 switch (extensionPoint) { 052 case CONFIG_XP: 053 registerKeyValueStore((KeyValueStoreDescriptor) contribution); 054 break; 055 default: 056 throw new NuxeoException("Unknown extension point: " + extensionPoint); 057 } 058 } 059 060 @Override 061 public void unregisterContribution(Object contribution, String extensionPoint, ComponentInstance contributor) { 062 switch (extensionPoint) { 063 case CONFIG_XP: 064 unregisterKeyValueStore((KeyValueStoreDescriptor) contribution); 065 break; 066 } 067 } 068 069 public void registerKeyValueStore(KeyValueStoreDescriptor descriptor) { 070 registry.addContribution(descriptor); 071 descriptorChanged(descriptor.name); 072 log.info("Registered key/value store: " + descriptor.name); 073 } 074 075 public void unregisterKeyValueStore(KeyValueStoreDescriptor descriptor) { 076 registry.removeContribution(descriptor); 077 descriptorChanged(descriptor.name); 078 log.info("Unregistered key/value store: " + descriptor.name); 079 } 080 081 // ===== KeyValueService ===== 082 083 @Override 084 public synchronized KeyValueStore getKeyValueStore(String name) { 085 KeyValueStoreProvider provider = providers.get(name); 086 if (provider == null) { 087 KeyValueStoreDescriptor descriptor = registry.getKeyValueStoreDescriptor(name); 088 if (descriptor == null) { 089 descriptor = registry.getKeyValueStoreDescriptor(DEFAULT_STORE_ID); 090 if (descriptor == null) { 091 return defaultStore; 092 } 093 } 094 try { 095 provider = descriptor.getKlass().newInstance(); 096 provider.initialize(descriptor.getProperties()); 097 } catch (ReflectiveOperationException e) { 098 throw new NuxeoException(e); 099 } 100 providers.put(name, provider); 101 } 102 return provider; 103 } 104 105 /* Close previous provider if we're overwriting it. */ 106 protected synchronized void descriptorChanged(String name) { 107 KeyValueStoreProvider provider = providers.remove(name); 108 if (provider != null) { 109 provider.close(); 110 } 111 } 112 113}