package act.controller.meta; /*- * #%L * ACT Framework * %% * Copyright (C) 2014 - 2017 ActFramework * %% * 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 act.app.ActionContext; import org.osgl.$; import org.osgl.util.S; /** * Keep all information required to inject {@link ActionContext} * into the controller action handler */ public class ActContextInjection<T> { /** * Define how framework should inject AppContext to the * controller action handler */ public enum InjectType { /** * Inject AppContext into controller instance field. This injection * is used when both of the following requirements are met * <ul> * <li>The controller has a field with type {@link ActionContext}</li> * <li>The action handler method is not {@code static}</li> * </ul> * <p>Framework must instantiate an new instance of the * controller before calling the action handler method</p> */ FIELD, /** * Pass AppContext via controller action method call. This injection * is used when there are parameter of type AppContext in the action * handler method signature */ PARAM, /** * Save AppContext to {@link org.osgl.concurrent.ContextLocal}. If none of * the {@link #FIELD} and {@link #PARAM} can be used to inject the * {@code AppContext}, then framework shall call {@link ActionContext#saveLocal} * method to save the app context instance into thread local variable, such that the * application developer could use {@link ActionContext#current} method to * access the current application context */ LOCAL; public boolean isLocal() { return this == LOCAL; } public boolean isField() { return this == FIELD; } public boolean isParam() { return this == PARAM; } } private InjectType type; protected T v; private ActContextInjection(InjectType type, T v) { this.type = type; this.v = v; } public InjectType injectVia() { return type; } @Override public int hashCode() { return $.hc(type, v); } @Override public boolean equals(Object obj) { if (obj == this) { return true; } if (obj instanceof ActContextInjection) { ActContextInjection that = (ActContextInjection) obj; return that.type == type && $.eq(that.v, v); } return false; } @Override public String toString() { return S.concat("inject[", type.name().toLowerCase(), ", ", S.string(v), "]"); } public static class FieldActContextInjection extends ActContextInjection<String> { public FieldActContextInjection(String fieldName) { super(InjectType.FIELD, fieldName); } public String fieldName() { return v; } } public static class ParamAppContextInjection extends ActContextInjection<Integer> { private int lvLookupIdx; public ParamAppContextInjection(Integer paramIndex) { super(InjectType.PARAM, paramIndex); } public int paramIndex() { return v; } public ParamAppContextInjection lvLookupIdx(int index) { this.lvLookupIdx = index; return this; } public int lvLookupIdx() { return lvLookupIdx; } } public static class LocalAppContextInjection extends ActContextInjection<Void> { public LocalAppContextInjection() { super(InjectType.LOCAL, null); } @Override public String toString() { return "inject[local]"; } } }