001: /*
002: * JFox - The most lightweight Java EE Application Server!
003: * more details please visit http://www.huihoo.org/jfox or http://www.jfox.org.cn.
004: *
005: * JFox is licenced and re-distributable under GNU LGPL.
006: */
007: package org.jfox.ejb3;
008:
009: import java.lang.reflect.Method;
010: import java.security.Principal;
011: import java.security.acl.Group;
012: import java.util.ArrayList;
013: import java.util.Collection;
014: import java.util.Collections;
015: import java.util.List;
016: import javax.annotation.security.RunAs;
017: import javax.security.auth.Subject;
018: import javax.transaction.TransactionManager;
019:
020: import org.jfox.ejb3.interceptor.BusinessInterceptorMethod;
021: import org.jfox.ejb3.interceptor.InterceptorMethod;
022: import org.jfox.ejb3.security.SecurityContext;
023: import org.jfox.mvc.SessionContext;
024:
025: /**
026: * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
027: */
028: public class EJBInvocation {
029:
030: static ThreadLocal<EJBInvocation> currentThreadEJBInvocation = new ThreadLocal<EJBInvocation>();
031:
032: private EJBObjectId ejbObjectId;
033:
034: private EJBBucket bucket;
035:
036: private Object target = null;
037: private Method interfaceMethod;
038: private Method concreteMethod;
039: private Object[] params;
040:
041: private TransactionManager tm;
042:
043: private SessionContext sessionContext;
044:
045: /**
046: * 方法是�有 @RunAS
047: */
048: private boolean runAS = false;
049:
050: public static void setCurrent(EJBInvocation ejbInvocation) {
051: currentThreadEJBInvocation.set(ejbInvocation);
052: }
053:
054: public static EJBInvocation current() {
055: return currentThreadEJBInvocation.get();
056: }
057:
058: public static void remove() {
059: currentThreadEJBInvocation.remove();
060: }
061:
062: public EJBInvocation(EJBObjectId ejbObjectId, EJBBucket bucket,
063: Object target, Method interfaceMethod,
064: Method concreteMethod, Object[] params,
065: SessionContext securityContext) {
066: this .ejbObjectId = ejbObjectId;
067: this .bucket = bucket;
068: this .target = target;
069: this .interfaceMethod = interfaceMethod;
070: this .concreteMethod = concreteMethod;
071: this .params = params;
072: this .sessionContext = securityContext;
073: }
074:
075: public TransactionManager getTransactionManager() {
076: return tm;
077: }
078:
079: void setTransactionManager(TransactionManager tm) {
080: this .tm = tm;
081: }
082:
083: public Collection<InterceptorMethod> getInterceptorMethods() {
084: final List<InterceptorMethod> interceptorMethods = new ArrayList<InterceptorMethod>();
085: // class level interceptor
086: interceptorMethods.addAll(getBucket()
087: .getClassInterceptorMethods());
088: // method level interceptor, 用 getConcreteMethod �key
089: interceptorMethods.addAll(getBucket()
090: .getMethodInterceptorMethods(getConcreteMethod()));
091: // @AroundInvoke in Bean class
092: interceptorMethods.addAll(getBucket()
093: .getBeanInterceptorMethods());
094: // create BusinessInterceptorMethod for invoke method
095: interceptorMethods.add(new BusinessInterceptorMethod(
096: getConcreteMethod()));
097: return Collections.unmodifiableList(interceptorMethods);
098: }
099:
100: public EJBObjectId getEJBObjectId() {
101: return ejbObjectId;
102: }
103:
104: private EJBBucket getBucket() {
105: return bucket;
106: }
107:
108: public ClassLoader getClassLoader() {
109: return bucket.getModule().getModuleClassLoader();
110: }
111:
112: public Object getTarget() {
113: return target;
114: }
115:
116: public boolean isStateful() {
117: return bucket.isStateful();
118: }
119:
120: public Method getInterfaceMethod() {
121: return interfaceMethod;
122: }
123:
124: /**
125: * å??射调用的方法,这是接å?£çš„æ–¹æ³•ï¼Œæ— æ³•å¾—åˆ° annotation
126: * �得到 annotation,必须使用 getInvocationMethod
127: */
128: public Method getConcreteMethod() {
129: return concreteMethod;
130: }
131:
132: /**
133: * 给 InvocationContext.setParameters 用
134: *
135: * @param args args
136: */
137: public void setArgs(Object[] args) {
138: this .params = args;
139: }
140:
141: public Object[] getArgs() {
142: return params;
143: }
144:
145: protected SessionContext getSessionContext() {
146: return sessionContext;
147: }
148:
149: /**
150: * 获� Http Session 数�
151: * @param attribute session key
152: */
153: public Object getSessionAttribute(String attribute) {
154: return getSessionContext().getAttribute(attribute);
155: }
156:
157: public SecurityContext getSecurityContext() {
158: return getSessionContext().getSecurityContext();
159: }
160:
161: public Group getCallerGroup() {
162: RunAs runAs = getBucket().getBeanClass().getAnnotation(
163: RunAs.class);
164: Subject subject = getSecurityContext().getSubject();
165: if (runAs != null) {
166: String runAsRole = runAs.value();
167: String username = getSecurityContext().getPrincipalName();
168: subject = SecurityContext.buildSubject(username, runAsRole);
169: }
170: if (subject == null) {
171: return null;
172: }
173: return getSecurityContext().getCallerGroup(subject);
174: }
175:
176: // 如果是 @RunAs Method,则需è¦?æ ¹æ?® RunAs æŒ‡å®šçš„å€¼æž„é€ Subject
177: public List<? extends Principal> getCallerRolesList() {
178: Group group = getCallerGroup();
179: if (group != null) {
180: return Collections.list(group.members());
181: } else {
182: return new ArrayList<Principal>(0);
183: }
184: }
185:
186: public String toString() {
187: return "EJBInvocation{EJB="
188: + getBucket().getBeanClass().getName() + ", method="
189: + getInterfaceMethod().getName() + "}";
190: }
191: }
|