001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.ejb.gen;
031:
032: import com.caucho.java.JavaWriter;
033: import com.caucho.util.L10N;
034:
035: import java.io.*;
036: import java.lang.reflect.*;
037: import java.util.*;
038: import javax.annotation.security.*;
039: import javax.ejb.*;
040: import javax.interceptor.*;
041:
042: /**
043: * Represents the security interception
044: */
045: public class SecurityCallChain extends AbstractCallChain {
046: private static final L10N L = new L10N(SecurityCallChain.class);
047:
048: private BusinessMethodGenerator _bizMethod;
049: private EjbCallChain _next;
050:
051: private String[] _roles;
052: private String _roleVar;
053:
054: private String _runAs;
055:
056: public SecurityCallChain(BusinessMethodGenerator bizMethod,
057: EjbCallChain next) {
058: super (next);
059:
060: _bizMethod = bizMethod;
061: _next = next;
062: }
063:
064: /**
065: * Returns true if the business method has any active XA annotation.
066: */
067: public boolean isEnhanced() {
068: if (_roles != null)
069: return true;
070: else if (_runAs != null)
071: return true;
072: else
073: return false;
074: }
075:
076: /**
077: * Sets the transaction type
078: */
079: public void setRoles(ArrayList<String> roles) {
080: _roles = new String[roles.size()];
081:
082: roles.toArray(_roles);
083: }
084:
085: /**
086: * Introspect EJB security annotations:
087: * @RunAs
088: * @RolesAllowed
089: * @PermitAll
090: * @DenyAll
091: */
092: public void introspect(Method apiMethod, Method implMethod) {
093: Class cl = apiMethod.getDeclaringClass();
094:
095: RunAs runAs = (RunAs) cl.getAnnotation(RunAs.class);
096:
097: if (runAs != null)
098: _runAs = runAs.value();
099:
100: RolesAllowed rolesAllowed = (RolesAllowed) cl
101: .getAnnotation(RolesAllowed.class);
102:
103: if (rolesAllowed != null)
104: _roles = rolesAllowed.value();
105:
106: PermitAll permitAll = (PermitAll) cl
107: .getAnnotation(PermitAll.class);
108:
109: if (permitAll != null)
110: _roles = null;
111:
112: DenyAll denyAll = (DenyAll) cl.getAnnotation(DenyAll.class);
113:
114: if (denyAll != null)
115: _roles = new String[0];
116:
117: //
118:
119: rolesAllowed = apiMethod.getAnnotation(RolesAllowed.class);
120:
121: if (rolesAllowed != null)
122: _roles = rolesAllowed.value();
123:
124: permitAll = (PermitAll) apiMethod
125: .getAnnotation(PermitAll.class);
126:
127: if (permitAll != null)
128: _roles = null;
129:
130: denyAll = (DenyAll) apiMethod.getAnnotation(DenyAll.class);
131:
132: if (denyAll != null)
133: _roles = new String[0];
134: }
135:
136: /**
137: * Generates the static class prologue
138: */
139: public void generatePrologue(JavaWriter out, HashMap map)
140: throws IOException {
141: if (_roles != null) {
142: _roleVar = "_role_" + out.generateId();
143:
144: out.print("private static String []" + _roleVar
145: + " = new String[] {");
146:
147: for (int i = 0; i < _roles.length; i++) {
148: if (i != 0)
149: out.print(", ");
150:
151: out.print("\"");
152: out.printJavaString(_roles[i]);
153: out.print("\"");
154: }
155:
156: out.println("};");
157: }
158:
159: _next.generatePrologue(out, map);
160: }
161:
162: /**
163: * Generates the method interceptor code
164: */
165: public void generateCall(JavaWriter out) throws IOException {
166: if (_roleVar != null) {
167: out
168: .println("com.caucho.security.SecurityContext.checkUserInRole("
169: + _roleVar + ");");
170: out.println();
171: }
172:
173: if (_runAs != null) {
174: out.print("String oldRunAs ="
175: + " com.caucho.security.SecurityContext.runAs(\"");
176: out.printJavaString(_runAs);
177: out.println("\");");
178:
179: out.println("try {");
180: out.pushDepth();
181: }
182:
183: _next.generateCall(out);
184:
185: if (_runAs != null) {
186: out.popDepth();
187: out.println("} finally {");
188: out
189: .println(" com.caucho.security.SecurityContext.runAs(oldRunAs);");
190: out.println("}");
191: }
192: }
193: }
|