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;
23 import static org.openecomp.core.utilities.CommonMethods.isEmpty;
24 import static org.openecomp.core.utilities.CommonMethods.newInstance;
26 import org.openecomp.sdc.common.errors.CoreException;
27 import org.openecomp.sdc.common.errors.ErrorCategory;
28 import org.openecomp.sdc.common.errors.ErrorCode;
31 import java.util.Collection;
33 import java.util.concurrent.ConcurrentHashMap;
36 * The type Abstract factory base.
38 public abstract class AbstractFactoryBase {
41 * Temporary registry of default implementations. The map keeps class names rather then class
42 * types to allow unloading of those classes from memory by garbage collector if
43 * factory is not actually used.
45 private static Map<String, String> registry = new ConcurrentHashMap<String, String>();
48 * Cached factory instances.
50 private static Map<String, AbstractFactoryBase> factoryMap =
51 new ConcurrentHashMap<String, AbstractFactoryBase>();
54 * Registers implementor for an abstract factory. The method accepts Java classes rather
55 * then class names to ensure type safety at compilation time.
57 * @param <I> Java interface type instantiated by abstract factory
58 * @param <F> Type specific abstract factory for concrete Java interface
59 * @param factory Java class of a type specific abstract factory
60 * @param impl Java class of type specific factory implementor
62 public static <I, F extends AbstractFactoryBase> void registerFactory(Class<F> factory,
63 Class<? extends F> impl) {
64 if (factory == null) {
65 throw new CoreException(
66 new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input factory.")
67 .withCategory(ErrorCategory.SYSTEM).build());
71 throw new CoreException(
72 new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input impl.")
73 .withCategory(ErrorCategory.SYSTEM).build());
75 if (factoryMap != null && factoryMap.containsKey(factory.getName())) {
76 factoryMap.remove(factory.getName());
78 registry.put(factory.getName(), impl.getName());
84 * @param factoryName the factory name
85 * @param implName the impl name
88 protected static void registerFactory(String factoryName, String implName) {
89 registry.put(factoryName, implName);
95 * @param <F> the type parameter
96 * @param factory the factory
98 public static <F extends AbstractFactoryBase> void unregisterFactory(Class<F> factory) {
99 if (factory == null) {
100 throw new CoreException(
101 new ErrorCode.ErrorCodeBuilder().withId("E0001").withMessage("Mandatory input factory.")
102 .withCategory(ErrorCategory.SYSTEM).build());
104 if (factoryMap != null) {
105 factoryMap.remove(factory.getName());
110 * Instantiates the configured implementation of an abstract factory.
112 * @param <I> Java interface type instantiated by abstract factory
113 * @param <F> Type specific abstract factory for concrete Java interface
114 * @param factoryType Java class of type specific abstract factory
115 * @return Instance of implementation class
117 @SuppressWarnings("unchecked")
118 public static <I, F extends AbstractFactoryBase> F getInstance(Class<F> factoryType) {
119 if (factoryType == null) {
120 throw new CoreException(
121 new ErrorCode.ErrorCodeBuilder().withId("E0001")
122 .withMessage("Mandatory input factory type.").withCategory(ErrorCategory.SYSTEM)
126 // Pick up factory instance from cache
127 F factory = (F) factoryMap.get(factoryType.getName());
128 // Check for the first time access
129 if (factory == null) {
130 // Synchronize factory instantiation
131 synchronized (factoryType) {
132 // Re-check the factory instance
133 factory = (F) factoryMap.get(factoryType.getName());
134 if (factory == null) {
135 // Get the implementation class name
136 String implName = registry.get(factoryType.getName());
138 if (isEmpty(implName)) {
139 throw new CoreException(
140 new ErrorCode.ErrorCodeBuilder().withId("E0001")
141 .withMessage("Mandatory input factory implementation.")
142 .withCategory(ErrorCategory.SYSTEM).build());
145 factory = newInstance(implName, factoryType);
149 // Cache the instantiated singleton
150 factoryMap.put(factoryType.getName(), factory);
161 * Is factory registered boolean.
163 * @param <F> the type parameter
164 * @param factoryType the factory type
165 * @return the boolean
167 public static <F extends AbstractFactoryBase> boolean isFactoryRegistered(Class<F> factoryType) {
168 boolean isFactoryRegistered = false;
169 if (factoryType == null) {
170 throw new CoreException(
171 new ErrorCode.ErrorCodeBuilder().withId("E0001")
172 .withMessage("Mandatory input factory type.").withCategory(ErrorCategory.SYSTEM)
175 // Pick up factory instance from cache
176 F factory = (F) factoryMap.get(factoryType.getName());
177 // Check for the first time access
178 if (factory != null) {
179 isFactoryRegistered = true;
181 // Get the implementation class name
182 String implName = registry.get(factoryType.getName());
183 if (!isEmpty(implName)) {
184 isFactoryRegistered = true;
187 return isFactoryRegistered;
193 public static void stopAll() {
194 Collection<AbstractFactoryBase> factorylist = factoryMap.values();
195 for (AbstractFactoryBase factory : factorylist) {
203 protected void init() {
209 protected void stop() {