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