/*
* 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.cloudstack.spring.lifecycle.registry;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.PostConstruct;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.BeanNameAware;
import org.apache.cloudstack.framework.config.ConfigKey;
import org.apache.cloudstack.framework.config.Configurable;
import com.cloud.utils.component.Registry;
public class ExtensionRegistry implements Registry<Object>, Configurable, BeanNameAware {
private static final Logger log = LoggerFactory.getLogger(ExtensionRegistry.class);
String name;
String beanName;
String orderConfigKey;
String orderConfigDefault;
ConfigKey<String> orderConfigKeyObj;
String excludeKey;
String excludeDefault;
ConfigKey<String> excludeKeyObj;
String configComponentName;
List<Object> preRegistered;
List<Object> registered = new CopyOnWriteArrayList<Object>();
List<Object> readOnly = Collections.unmodifiableList(registered);
@Override
public boolean register(Object item) {
if (registered.contains(item))
return false;
String[] order = new String[] {};
Set<String> exclude = new HashSet<String>();
if (orderConfigKeyObj != null) {
Object value = orderConfigKeyObj.value();
if (value != null && value.toString().trim().length() > 0) {
order = value.toString().trim().split("\\s*,\\s*");
}
}
if (excludeKeyObj != null) {
Object value = excludeKeyObj.value();
if (value != null && value.toString().trim().length() > 0) {
for (String e : value.toString().trim().split("\\s*,\\s*")) {
exclude.add(e);
}
}
}
String name = RegistryUtils.getName(item);
if (name != null && exclude.size() > 0 && exclude.contains(name)) {
return false;
}
if (name == null && order.length > 0) {
throw new RuntimeException("getName() is null for [" + item + "]");
}
int i = 0;
for (String orderTest : order) {
if (orderTest.equals(name)) {
registered.add(i, item);
i = -1;
break;
}
if (registered.size() <= i) {
break;
}
if (RegistryUtils.getName(registered.get(i)).equals(orderTest)) {
i++;
}
}
if (i != -1) {
registered.add(item);
}
log.debug("Registering extension [{}] in [{}]", name, this.name);
return true;
}
@Override
public void unregister(Object type) {
registered.remove(type);
}
@Override
public List<Object> getRegistered() {
return readOnly;
}
@Override
public String getConfigComponentName() {
return configComponentName == null ? this.getClass().getSimpleName() : configComponentName;
}
@Override
public ConfigKey<?>[] getConfigKeys() {
List<ConfigKey<String>> result = new ArrayList<ConfigKey<String>>();
if (orderConfigKey != null && orderConfigKeyObj == null) {
orderConfigKeyObj = new ConfigKey<String>("Advanced", String.class, orderConfigKey, orderConfigDefault, "The order of precedence for the extensions", false);
}
if (orderConfigKeyObj != null)
result.add(orderConfigKeyObj);
if (excludeKey != null && excludeKeyObj == null) {
excludeKeyObj = new ConfigKey<String>("Advanced", String.class, excludeKey, excludeDefault, "Extensions to exclude from being registered", false);
}
if (excludeKeyObj != null) {
result.add(excludeKeyObj);
}
return result.toArray(new ConfigKey[result.size()]);
}
@PostConstruct
public void init() {
if (name == null) {
for (String part : beanName.replaceAll("([A-Z])", " $1").split("\\s+")) {
part = StringUtils.capitalize(part.toLowerCase());
name = name == null ? part : name + " " + part;
}
}
if (preRegistered != null) {
for (Object o : preRegistered) {
register(o);
}
}
}
public String getOrderConfigKey() {
return orderConfigKey;
}
public void setOrderConfigKey(String orderConfigKey) {
this.orderConfigKey = orderConfigKey;
}
public void setConfigComponentName(String configComponentName) {
this.configComponentName = configComponentName;
}
public String getOrderConfigDefault() {
return orderConfigDefault;
}
public void setOrderConfigDefault(String orderConfigDefault) {
this.orderConfigDefault = orderConfigDefault;
}
public String getExcludeKey() {
return excludeKey;
}
public void setExcludeKey(String excludeKey) {
this.excludeKey = excludeKey;
}
public String getExcludeDefault() {
return excludeDefault;
}
public void setExcludeDefault(String excludeDefault) {
this.excludeDefault = excludeDefault;
}
@Override
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void setBeanName(String name) {
beanName = name;
}
public List<Object> getPreRegistered() {
return preRegistered;
}
public void setPreRegistered(List<Object> preRegistered) {
this.preRegistered = preRegistered;
}
}