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

com.lonepulse.icklebot.injector.Injector Maven / Gradle / Ivy

package com.lonepulse.icklebot.injector;

/*
 * #%L
 * IckleBot
 * %%
 * Copyright (C) 2013 Lonepulse
 * %%
 * 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.
 * #L%
 */

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import android.app.Activity;
import android.app.Fragment;
import android.content.Context;

import com.lonepulse.icklebot.annotation.inject.InjectAll;
import com.lonepulse.icklebot.event.resolver.EventCategory;
import com.lonepulse.icklebot.injector.resolver.InjectionCategory;
import com.lonepulse.icklebot.injector.resolver.InjectionResolver;
import com.lonepulse.icklebot.injector.resolver.InjectionResolvers;
import com.lonepulse.icklebot.util.ContextUtils;

/**
 * 

This is the common contract which all injectors must implement.

* * @version 1.3.0 *

* @author Lahiru Sahan Jayasinghe */ public interface Injector { /** *

Stores information about the injection process; such as the * context which has requested injection and the target {@link Field}s * in this context grouped into their categories by {@link InjectionCategory}.

* * @version 1.1.0 *

* @author Lahiru Sahan Jayasinghe */ public static final class Configuration { /** *

The mode of injection identified by * {@link InjectionMode}.

* * @since 1.1.0 */ private final InjectionMode injectionMode; /** *

The context which has requested dependency injection.

* * @since 1.2.0 */ private final Object context; /** *

The target {@link Field}s in the {@link #context} grouped into their * categories by {@link InjectionCategory}.

* * @since 1.1.0 */ private final Map> injectionTargets; /** *

Creates a new instance of {@link Injector.Configuration} * using the passed context.

* *

This is to be used in an instantiated context.

* * @param context * the {@link Context} which has requested dependency injection *

* @return a new instance of {@link Injector.Configuration} *

* @throws InjectionException * if the supplied context is {@code null} *

* @throws IllegalContextException * if the given context is not of type {@link Activity} or {@link Fragment} *

* @since 1.1.0 */ public static Configuration newInstance(Object context) { if(context == null) throw new InjectionException(new IllegalArgumentException("A context must be supplied.")); if(!ContextUtils.isActivity(context) && !ContextUtils.isFragment(context) && !ContextUtils.isSupportFragment(context)) { Set> applicableContexts = new HashSet>(); applicableContexts.add(Activity.class); applicableContexts.add(Fragment.class); applicableContexts.add(android.support.v4.app.Fragment.class); throw new IllegalContextException(context, applicableContexts); } return new Configuration(context); } /** *

Constructor visibility restricted to prevent instantiation. * Please use the factory method {@link #newInstance(Object)}.

* *

Initializes {@link #injectionTargets} to an empty {@link Map}.

* * @since 1.1.0 */ private Configuration(Object context) { this.context = context; this.injectionTargets = new HashMap>(); for (InjectionCategory injectionCategory : InjectionCategory.values()) this.injectionTargets.put(injectionCategory, new HashSet()); if(context.getClass().isAnnotationPresent(InjectAll.class)) this.injectionMode = InjectionMode.IMPLICIT; else this.injectionMode = InjectionMode.EXPLICIT; Field[] fields = context.getClass().getDeclaredFields(); InjectionResolver injectionResolver = (this.injectionMode == InjectionMode.EXPLICIT)? InjectionResolvers.EXPLICIT :InjectionResolvers.IMPLICIT; for (Field field : fields) { InjectionCategory injectionCategory = injectionResolver.resolve(context, field); injectionTargets.get(injectionCategory).add(field); } } /** *

Accessor for {@link #injectionMode}.

* * @return {@link #injectionMode} *

* @since 1.1.0 */ public InjectionMode getInjectionMode() { return injectionMode; } /** *

Accessor for {@link #context}.

* * @return {@link #context} *

* @since 1.1.0 */ public Object getContext() { return context; } /** *

Accessor for {@link #injectionTargets}.

* * @return {@link #injectionTargets} *

* @since 1.1.0 */ public Map> getInjectionTargets() { return Collections.unmodifiableMap(injectionTargets); } /** *

Takes an {@link EventCategory} and retrieves * the {@link Set} of {@link Field}s under that category * as mapped in {@link #injectionTargets}.

* * @param injectionCategory * the fields are to be retrieved for this * {@link EventCategory} *

* @return the {@link Set} of {@link Field}s under * the category, else an empty {@link Set} *

* @since 1.1.0 */ public Set getInjectionTargets(InjectionCategory injectionCategory) { return Collections.unmodifiableSet(injectionTargets.get(injectionCategory)); } } /** *

Specifies the contract for performing injection related to a * particular {@link InjectionCategory} over the given set of {@link Field}s. * * @version 1.1.0 *

* @author Lahiru Sahan Jayasinghe */ public static interface InjectionStrategy { /** *

Performs injection over the given set of {@link Field}s in * the target {@link Context}. * * @param config * the {@link Injector.Configuration} associated with the * injection operation * * @return the value which is to be injected * * @since 1.1.0 */ public abstract void run(Injector.Configuration config); } /** *

Takes an {@link Injector.Configuration} and injects the resources * which this injector is responsible for.

* * @param config * the {@link Injector.Configuration} which for this injector *

* @throws InjectionException * if the injection operation failed *

* @since 1.1.0 */ public abstract void inject(final Injector.Configuration config) throws InjectionException; }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy