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

org.javabits.yar.guice.Matchers Maven / Gradle / Ivy

There is a newer version: 3.0.1.RELEASE
Show newest version
/*
 * Copyright 2013 Romain Gilles
 *
 *    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 org.javabits.yar.guice;

import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;
import org.javabits.yar.Id;
import org.javabits.yar.Ids;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.javabits.yar.guice.Reflections.getUniqueParameterType;
import static org.javabits.yar.guice.Reflections.isParameterizedType;

/**
 * TODO comment
 * Date: 3/17/13
 * Time: 10:01 PM
 *
 * @author Romain Gilles
 */
public final class Matchers {

    private static final String KEY_MATCHER_SIGNATURE = "Matcher>";
    private static final String MATCHER_PARAMETER_TYPE_ERROR = "The matcher type must be implementation of " + KEY_MATCHER_SIGNATURE;

    @SuppressWarnings("unchecked")
    public static  Id getId(Matcher> matcher) {
        return (Id)Ids.newId(getTargetType(matcher));
    }

    public static  Key getKey(Matcher> matcher) {
        return Key.get(getTargetTypeLiteral(matcher));
    }

    public static  TypeLiteral getTargetTypeLiteral(Matcher> matcher) {
        Type keyTargetType = getTargetType(matcher);
        return getTypeLiteral(keyTargetType);
    }

    @SuppressWarnings("unchecked")
    private static  TypeLiteral getTypeLiteral(Type keyTargetType) {
        return (TypeLiteral) TypeLiteral.get(keyTargetType);
    }

    private static  Type getTargetType(Matcher> matcher) {
        if (matcher instanceof KeyProvider) {
            @SuppressWarnings("unchecked")
            KeyProvider keyProvider = (KeyProvider) matcher;
            return keyProvider.get().getTypeLiteral().getType();
        }
        Type matcherTargetType = getUniqueParameterType(matcher.getClass(), Matcher.class, KEY_MATCHER_SIGNATURE);
        if (isParameterizedType(matcherTargetType) && Key.class.isAssignableFrom(Reflections.getRawType(matcherTargetType))) {
            return getUniqueParameterType((ParameterizedType) matcherTargetType, "Key");
        } else {
            throw new IllegalArgumentException(MATCHER_PARAMETER_TYPE_ERROR);
        }
    }

    public static  Matcher> newKeyMatcher(final Key key) {
        return new KeyMatcher<>(key);
    }

    public static  Matcher> newKeyMatcher(final Class type) {
        return new KeyMatcher<>(Key.get(type));
    }

    public static  Matcher> newKeyTypeMatcher(final Key key) {
        return new KeyTypeMatcher<>(key);
    }

    public static  Matcher> newKeyTypeMatcher(final Class type) {
        return new KeyTypeMatcher<>(Key.get(type));
    }

    public static Matcher> subclassesOf(final Class superclass) {
        return new SubClassesOf(superclass);
    }

    static class KeyMatcher extends AbstractMatcher> implements KeyProvider {

        private final Key key;

        public KeyMatcher(Key key) {
            this.key = key;
        }

        @Override
        public boolean matches(Key other) {
            return key.equals(other);
        }

        @Override
        public Key get() {
            return key;
        }
    }

    static class KeyTypeMatcher extends AbstractMatcher> implements KeyProvider {

        private final Key key;

        public KeyTypeMatcher(Key key) {
            this.key = key;
        }

        @Override
        public boolean matches(Key other) {
            return key.getTypeLiteral().equals(other.getTypeLiteral());
//            return true; //always true ;)
        }

        @Override
        public Key get() {
            return key;
        }
    }

    private static class SubClassesOf extends AbstractMatcher> {

        private final Class superclass;

        public SubClassesOf(Class superclass) {
            this.superclass = checkNotNull(superclass);
        }

        @Override
        public boolean matches(TypeLiteral o) {
            return superclass.isAssignableFrom(o.getRawType());
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy