2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.openecomp.core.factory.impl;
 
  24 import org.openecomp.sdc.common.errors.CoreException;
 
  25 import org.openecomp.sdc.common.errors.ErrorCategory;
 
  26 import org.openecomp.sdc.common.errors.ErrorCode;
 
  28 import java.util.Collection;
 
  30 import java.util.concurrent.ConcurrentHashMap;
 
  32 import static org.openecomp.core.utilities.CommonMethods.isEmpty;
 
  33 import static org.openecomp.core.utilities.CommonMethods.newInstance;
 
  35 public abstract class AbstractFactoryBase {
 
  38    * Temporary registry of default implementations. The map keeps class names rather then class
 
  39    * types to allow unloading of those classes from memory by garbage collector if factory is not
 
  42   private static Map<String, String> registry = new ConcurrentHashMap<String, String>();
 
  45    * Cached factory instances.
 
  47   private static Map<String, AbstractFactoryBase> factoryMap =
 
  48       new ConcurrentHashMap<String, AbstractFactoryBase>();
 
  51    * Registers implementor for an abstract factory. The method accepts Java classes rather then
 
  52    * class names to ensure type safety at compilation time.
 
  54    * @param <I>     Java interface type instantiated by abstract factory
 
  55    * @param <F>     Type specific abstract factory for concrete Java interface
 
  56    * @param factory Java class of a type specific abstract factory
 
  57    * @param impl    Java class of type specific factory implementor
 
  59   public static <I, F extends AbstractFactoryBase> void registerFactory(Class<F> factory,
 
  60                                                                         Class<? extends F> impl) {
 
  61     if (factory == null) {
 
  62       throw new CoreException(
 
  63           new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input factory.")
 
  64               .withCategory(ErrorCategory.SYSTEM).build());
 
  68       throw new CoreException(
 
  69           new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input impl.")
 
  70               .withCategory(ErrorCategory.SYSTEM).build());
 
  72     if (factoryMap != null && factoryMap.containsKey(factory.getName())) {
 
  73       factoryMap.remove(factory.getName());
 
  75     registry.put(factory.getName(), impl.getName());
 
  79   protected static void registerFactory(String factoryName, String implName) {
 
  80     registry.put(factoryName, implName);
 
  86    * @param <F>     the type parameter
 
  87    * @param factory the factory
 
  89   public static <F extends AbstractFactoryBase> void unregisterFactory(Class<F> factory) {
 
  90     if (factory == null) {
 
  91       throw new CoreException(
 
  92           new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input factory.")
 
  93               .withCategory(ErrorCategory.SYSTEM).build());
 
  95     if (factoryMap != null) {
 
  96       factoryMap.remove(factory.getName());
 
 101    * Instantiates the configured implementation of an abstract factory.
 
 103    * @param <I>         Java interface type instantiated by abstract factory
 
 104    * @param <F>         Type specific abstract factory for concrete Java interface
 
 105    * @param factoryType Java class of type specific abstract factory
 
 106    * @return Instance of implementation class
 
 108   @SuppressWarnings("unchecked")
 
 109   public static <I, F extends AbstractFactoryBase> F getInstance(Class<F> factoryType) {
 
 110     if (factoryType == null) {
 
 111       throw new CoreException(
 
 112           new ErrorCode.ErrorCodeBuilder().withId("E0001")
 
 113               .withMessage("Mandatory input factory type.").withCategory(ErrorCategory.SYSTEM)
 
 117     // Pick up factory instance from cache
 
 118     F factory = (F) factoryMap.get(factoryType.getName());
 
 119     // Check for the first time access
 
 120     if (factory == null) {
 
 121       // Synchronize factory instantiation
 
 122       synchronized (factoryType) {
 
 123         // Re-check the factory instance
 
 124         factory = (F) factoryMap.get(factoryType.getName());
 
 125         if (factory == null) {
 
 126           // Get the implementation class name
 
 127           String implName = registry.get(factoryType.getName());
 
 129           if (isEmpty(implName)) {
 
 130             throw new CoreException(
 
 131                 new ErrorCode.ErrorCodeBuilder().withId("E0001")
 
 132                     .withMessage("Mandatory input factory implementation.")
 
 133                     .withCategory(ErrorCategory.SYSTEM).build());
 
 136           factory = newInstance(implName, factoryType);
 
 140           // Cache the instantiated singleton
 
 141           factoryMap.put(factoryType.getName(), factory);
 
 152    * Is factory registered boolean.
 
 154    * @param <F>         the type parameter
 
 155    * @param factoryType the factory type
 
 156    * @return the boolean
 
 158   public static <F extends AbstractFactoryBase> boolean isFactoryRegistered(Class<F> factoryType) {
 
 159     boolean isFactoryRegistered = false;
 
 160     if (factoryType == null) {
 
 161       throw new CoreException(
 
 162           new ErrorCode.ErrorCodeBuilder().withId("E0001")
 
 163               .withMessage("Mandatory input factory type.").withCategory(ErrorCategory.SYSTEM)
 
 166     // Pick up factory instance from cache
 
 167     F factory = (F) factoryMap.get(factoryType.getName());
 
 168     // Check for the first time access
 
 169     if (factory != null) {
 
 170       isFactoryRegistered = true;
 
 172       // Get the implementation class name
 
 173       String implName = registry.get(factoryType.getName());
 
 174       if (!isEmpty(implName)) {
 
 175         isFactoryRegistered = true;
 
 178     return isFactoryRegistered;
 
 184   public static void stopAll() {
 
 185     Collection<AbstractFactoryBase> factorylist = factoryMap.values();
 
 186     for (AbstractFactoryBase factory : factorylist) {
 
 191   protected void init() {
 
 194   protected void stop() {