All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jvnet.hk2.component.ContractLocatorImpl Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2011-2012 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package org.jvnet.hk2.component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.sun.hk2.component.InhabitantsFile;
import com.sun.hk2.component.ScopedInhabitant;
import org.glassfish.hk2.Provider;
import org.glassfish.hk2.ContractLocator;
import org.glassfish.hk2.Scope;
import org.glassfish.hk2.TypeLiteral;

/**
 * Implementation of the {@link ContractLocator} interface.
 * 
 * 

* This is used for location byType or byContract. * * @author Jerome Dochez * @author Jeff Trent */ //TODO: support scope for byContract & byType //TODO: support name for byType //TODO: support annotation for byContract & byType //TODO: support metadata for byContract & byType public class ContractLocatorImpl implements ContractLocator { private static final Logger logger = Logger.getLogger(ContractLocatorImpl.class.getName()); private final SimpleServiceLocator habitat; private String name; private Type type=null; private String typeName=null; private Collection> qualifiers = new ArrayList>(); private Scope scope; // byContract, else byType private final boolean byContract; public ContractLocatorImpl(SimpleServiceLocator habitat, Type clazz, boolean byContract) { this.habitat = habitat; this.byContract = byContract; this.type=clazz; } ContractLocatorImpl(SimpleServiceLocator habitat, String clazzName, boolean byContract) { this.habitat = habitat; this.byContract = byContract; this.typeName=clazzName; } private void warnOnUsage() { logger.log(Level.WARNING, "name and scope are currently only appropriate for byContract usage; (name: {0}; type: {1})", new Object[] {name, getTypeName()}); } public String getTypeName() { if (null == type) { return typeName; } return TypeLiteral.getRawType(type).getName(); } @Override public ContractLocator named(String name) { this.name = name; if (null != name && !name.isEmpty() && !byContract) { warnOnUsage(); } return this; } @Override public ContractLocator in(Scope scope) { this.scope = scope; return this; } @Override public ContractLocator annotatedWith(Class annotation) { qualifiers.add(annotation); return this; } @Override public T get() { Provider provider = getProvider(); return provider == null ? null : provider.get(); } @Override public U getByType(Class type) { Provider provider = getProvider(); return provider == null ? null : (U) (type == null ? provider.get() : provider.getByType(org.jvnet.tiger_types.Types.erasure(type))); } @Override public Provider getProvider() { Collection> providers = all(true); return (providers.isEmpty()?null:providers.iterator().next()); } @Override public Collection> all() { return all(false); } public Collection> all(boolean stopAtFirstMatch) { Set> providers = new HashSet>(); if (qualifiers.isEmpty()) { return getNonQualifiedInhabitants(stopAtFirstMatch); } else { List tmpQualifiers = new ArrayList(); for (Class annotation : qualifiers) { tmpQualifiers.add(annotation.getName()); } for (Inhabitant inh : inhabitants()) { List declaredQualifiers = inh.metadata().get(InhabitantsFile.QUALIFIER_KEY); for (String declaredQualifier : declaredQualifiers) { // todo : we need to look at the instances of the Annotations // rather than the type on both the injection target and the // candidate so we can ensure that annotation attribute matching is performed tmpQualifiers.remove(declaredQualifier); } // if the injection point qualifiers are all satisfied, stop the query if (tmpQualifiers.isEmpty()) { // check if the scope is fine. if (scope==null) { providers.add(inh); } else { if ((inh instanceof ScopedInhabitant) && ((ScopedInhabitant) inh).getScope().equals(scope)) { providers.add(inh); } } if (!providers.isEmpty() && stopAtFirstMatch) return providers; } } } return providers; } private Inhabitant getNonQualifiedInhabitant() { if (name!=null && !name.isEmpty()) { return provider(); } Inhabitant inh = provider(); if (inh==null) return null; if (inh.metadata().get(InhabitantsFile.QUALIFIER_KEY).isEmpty()) { return inh; } // we should find the inhabitant with no qualifier. for (Inhabitant inhabitant : inhabitants()) { if (inhabitant.metadata().get(InhabitantsFile.QUALIFIER_KEY).isEmpty()) { return inhabitant; } } return null; } private Collection> getNonQualifiedInhabitants(boolean stopOnFirst) { Set> inhabitants = new HashSet>(); if (name!=null && !name.isEmpty()) { Inhabitant provider = provider(); if (provider!=null) { inhabitants.add(provider); if (stopOnFirst) return inhabitants; } } Inhabitant inh = provider(); if (inh==null) return inhabitants; if (inh.metadata().get(InhabitantsFile.QUALIFIER_KEY).isEmpty()) { inhabitants.add(inh); if (stopOnFirst) return inhabitants; } // we should find the inhabitant with no qualifier. for (Inhabitant inhabitant : inhabitants()) { if (inhabitant.metadata().get(InhabitantsFile.QUALIFIER_KEY).isEmpty()) { if (inhabitant.getDescriptor().getNames().isEmpty()) { inhabitants.add(inhabitant); if (stopOnFirst) return inhabitants; } } } return inhabitants; } private Inhabitant provider() { if (type!=null) { return habitat.getProvider(type, name); } else { return habitat.getProvider(typeName, name); } } private Collection> inhabitants() { if (type!=null) { if (byContract) { return habitat.getInhabitantsByContract(type); } else { Class classType = org.jvnet.tiger_types.Types.erasure(type); return habitat.getInhabitantsByType(classType); } } else { if (byContract) { return habitat.getInhabitantsByContract(typeName); } else { return habitat.getInhabitantsByType(typeName); } } } }