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

org.eclipse.sisu.space.WildcardKey Maven / Gradle / Ivy

There is a newer version: 3.0.0-alpha-3
Show newest version
/*******************************************************************************
 * Copyright (c) 2010-present Sonatype, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Stuart McCulloch (Sonatype, Inc.) - initial API and implementation
 *******************************************************************************/
package org.eclipse.sisu.space;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

import javax.inject.Provider;
import javax.inject.Qualifier;

import com.google.inject.Key;
import com.google.inject.TypeLiteral;

/**
 * Binding {@link Key} for implementations that act as "wild-cards", meaning they match against any assignable type.
 * 

* Since the wild-card type is {@link Object} and the associated qualifier may not be unique between implementations, * the qualifier is saved and replaced with a unique (per-implementation) pseudo-qualifier. The original qualifier is * available by casting the pseudo-qualifier to {@link Provider} and calling {@code get()}. */ final class WildcardKey { // ---------------------------------------------------------------------- // Constants // ---------------------------------------------------------------------- private static final TypeLiteral OBJECT_TYPE_LITERAL = TypeLiteral.get( Object.class ); // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- private WildcardKey() { // static utility class, not allowed to create instances } // ---------------------------------------------------------------------- // Utility methods // ---------------------------------------------------------------------- /** * @return Wildcard key for the given implementation type and qualifier */ public static Key get( final Class type, final Annotation qualifier ) { return Key.get( OBJECT_TYPE_LITERAL, new QualifiedImpl( type, qualifier ) ); } // ---------------------------------------------------------------------- // Implementation types // ---------------------------------------------------------------------- /** * {@link Qualifier} that captures a qualified implementation type. */ @Qualifier @Retention( RetentionPolicy.RUNTIME ) private static @interface Qualified { Class value(); } /** * Pseudo-{@link Annotation} that can wrap any implementation type as a {@link Qualifier}. */ private static final class QualifiedImpl implements Qualified, Provider { // ---------------------------------------------------------------------- // Implementation fields // ---------------------------------------------------------------------- private final Class value; private final Annotation qualifier; // ---------------------------------------------------------------------- // Constructors // ---------------------------------------------------------------------- QualifiedImpl( final Class value, final Annotation qualifier ) { this.value = value; this.qualifier = qualifier; } // ---------------------------------------------------------------------- // Public methods // ---------------------------------------------------------------------- public Class value() { return value; } public Annotation get() { return qualifier; } public Class annotationType() { return Qualified.class; } @Override public int hashCode() { return value.hashCode(); // no need to follow strict annotation spec } @Override public boolean equals( final Object rhs ) { if ( this == rhs ) { return true; } if ( rhs instanceof QualifiedImpl ) { return value == ( (QualifiedImpl) rhs ).value; } return false; } @Override public String toString() { return "*"; // let people know this is a "wild-card" qualifier } } }