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.policy.drools.utils;
23 import java.util.Collections;
24 import java.util.Comparator;
25 import java.util.HashMap;
26 import java.util.LinkedList;
27 import java.util.List;
28 import java.util.ServiceLoader;
31 * This class is a template for building a sorted list of service instances,
32 * which are discovered and created using 'ServiceLoader'.
34 public class OrderedServiceImpl<T extends OrderedService>
36 // sorted list of instances implementing the service
37 private List<T> implementers = null;
39 // 'ServiceLoader' that is used to discover and create the services
40 private ServiceLoader<T> serviceLoader = null; //ServiceLoader.load(T.class);
43 * Constructor - create the 'ServiceLoader' instance
45 * @param clazz the class object associated with 'T' (I supposed it could
46 * be a subclass, but I'm not sure this is useful)
48 public OrderedServiceImpl(Class clazz)
50 // This constructor wouldn't be needed if 'T.class' was legal
51 serviceLoader = ServiceLoader.load(clazz);
55 * @return the sorted list of services implementing interface 'T' discovered
58 public synchronized List<T> getList()
60 if (implementers == null)
68 * This method is called by 'getList', but could also be called directly if
69 * we were running with a 'ClassLoader' that supported the dynamic addition
70 * of JAR files. In this case, it could be invoked in order to discover any
71 * new services implementing interface 'T'. This is probably a relatively
72 * expensive operation in terms of CPU and elapsed time, so it is best if it
73 * isn't invoked too frequently.
75 * @return the sorted list of services implementing interface 'T' discovered
78 public synchronized List<T> rebuildList()
80 // build a list of all of the current implementors
81 List<T> tmp = new LinkedList<T>();
82 for (T service : serviceLoader)
84 tmp.add((T)getSingleton(service));
87 // Sort the list according to sequence number, and then alphabetically
88 // according to full class name.
89 Collections.sort(tmp, new Comparator<T>()
91 public int compare(T o1, T o2)
93 int s1 = o1.getSequenceNumber();
94 int s2 = o2.getSequenceNumber();
106 rval = o1.getClass().getName().compareTo
107 (o2.getClass().getName());
113 // create an unmodifiable version of this list
114 implementers = Collections.unmodifiableList(tmp);
115 System.out.println("***** OrderedServiceImpl implementers:\n" + implementers);
116 return(implementers);
119 // use this to ensure that we only use one unique instance of each class
120 static private HashMap<Class,OrderedService> classToSingleton =
124 * If a service implements multiple APIs managed by 'ServiceLoader', a
125 * separate instance is created for each API. This method ensures that
126 * the first instance is used in all of the lists.
128 * @param service this is the object created by ServiceLoader
129 * @return the object to use in place of 'service'. If 'service' is the first
130 * object of this class created by ServiceLoader, it is returned. If not,
131 * the object of this class that was initially created is returned
134 static private synchronized OrderedService
135 getSingleton(OrderedService service)
137 // see if we already have an instance of this class
138 OrderedService rval = classToSingleton.get(service.getClass());
141 // No previous instance of this class exists -- use the supplied
142 // instance, and place it in the table.
144 classToSingleton.put(service.getClass(), service);