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() {