/* * Copyright 2014-2016 Squarespace, Inc. * * Licensed 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 com.squarespace.jersey2.guice; import java.util.Collection; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicReference; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.extension.ServiceLocatorGenerator; import org.jvnet.hk2.external.generator.ServiceLocatorGeneratorImpl; class GuiceServiceLocatorGenerator implements ServiceLocatorGenerator { private final ServiceLocatorGenerator generator = new ServiceLocatorGeneratorImpl(); private final ConcurrentMap<String, ServiceLocator> locators = new ConcurrentHashMap<>(); private final AtomicReference<ServiceLocatorGenerator> delegateRef = new AtomicReference<>(); public void delegate(ServiceLocatorGenerator delegate) { delegateRef.set(delegate); } public void add(ServiceLocator locator) { String name = locator.getName(); if (locators.putIfAbsent(name, locator) != null) { throw new IllegalStateException("Duplicate name: " + name); } } public Collection<ServiceLocator> locators() { return locators.values(); } public void reset() { locators.clear(); delegateRef.set(null); } @Override public ServiceLocator create(String name, ServiceLocator parent) { // Using remove() to transfer ownership of the ServiceLocator from // this object to the caller. Something is really wrong if the caller // uses the same name again! ServiceLocator locator = locators.remove(name); if (locator != null) { return locator; } // This is mostly needed for testing. ServiceLocatorGenerator delegate = delegateRef.get(); if (delegate != null) { locator = delegate.create(name, parent); if (locator != null) { return locator; } } return generator.create(name, parent); } }