001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.metadata;
023:
024: import java.util.ArrayList;
025: import java.util.Iterator;
026: import java.util.Set;
027: import java.util.HashSet;
028:
029: import org.w3c.dom.Element;
030:
031: import org.jboss.deployment.DeploymentException;
032: import org.jboss.invocation.InvocationType;
033:
034: /** The combination of the method-permission, container-transaction
035: *
036: * <p>
037: * The method-permission element specifies that one or more security
038: * roles are allowed to invoke one or more enterprise bean methods. The
039: * method-permission element consists of an optional description, a list
040: * of security role names, or an indicator to specify that the methods
041: * are not to be checked for authorization, and a list of method elements.
042: * The security roles used in the method-permission element must be
043: * defined in the security-role element of the deployment descriptor,
044: * and the methods must be methods defined in the enterprise bean’s component
045: * and/or home interfaces.
046: * </p>
047: * <p>
048: * The container-transaction element specifies how the container must
049: * manage transaction scopes for the enterprise bean’s method invocations.
050: * The element consists of an optional description, a list of
051: * method elements, and a transaction attribute. The transaction
052: * attribute is to be applied to all the specified methods.
053: * </p>
054: *
055: * @author <a href="mailto:sebastien.alborini@m4x.org">Sebastien Alborini</a>
056: * @author <a href="mailto:Scott.Stark@jboss.org">Scott Stark</a>.
057: * @version $Revision: 57209 $
058: */
059: public class MethodMetaData extends MetaData {
060: // Constants -----------------------------------------------------
061: // These method interface contstants are compatible with the Invocation.XXX values
062: public static final int ANY_METHOD = -1;
063: public static String HOME_TYPE = "Home";
064: public static String LOCAL_HOME_TYPE = "LocalHome";
065: public static String REMOTE_TYPE = "Remote";
066: public static String LOCAL_TYPE = "Local";
067: public static String SERVICE_ENDPOINT_TYPE = "ServiceEndpoint";
068:
069: private static final ArrayList EMPTY_PARAM_LIST = new ArrayList();
070:
071: // Attributes ----------------------------------------------------
072: /** The method-name element contains a name of an enterprise bean method,
073: * or the asterisk (*) character. The asterisk is used when the element
074: * denotes all the methods of an enterprise bean’s component and home
075: * interfaces.
076: */
077: private String methodName;
078: /** The ejb-name value the method applies to.
079: */
080: private String ejbName;
081:
082: /** The method-intf element allows a method element to differentiate
083: * between the methods with the same name and signature that are multiply
084: * defined across the home and component interfaces (e.g., in both an
085: * enterprise bean’s remote and local interfaces, or in both an enter-prise
086: * bean’s home and remote interfaces, etc.)
087: * The method-intf element must be one of the following:
088: * <method-intf>Home</method-intf>
089: * <method-intf>Remote</method-intf>
090: * <method-intf>LocalHome</method-intf>
091: * <method-intf>Local</method-intf>
092: * <method-intf>ServiceEndpoint</method-intf>
093: */
094: private boolean intf = false;
095: /** One of: InvocationType
096: */
097: private InvocationType methodType = null;
098: private boolean param = false;
099: /** The unchecked element specifies that a method is not checked for
100: * authorization by the container prior to invocation of the method.
101: * Used in: method-permission
102: */
103: private boolean unchecked = false;
104: /** The exclude-list element defines a set of methods which the Assembler
105: * marks to be uncallable. It contains one or more methods. If the method
106: * permission relation contains methods that are in the exclude list, the
107: * Deployer should consider those methods to be uncallable.
108: */
109: private boolean excluded = false;
110: /** The method-params element contains a list of the fully-qualified Java
111: * type names of the method parameters.
112: */
113: private ArrayList paramList = EMPTY_PARAM_LIST;
114: /** The trans-attribute element specifies how the container must manage
115: * the transaction boundaries when delegating a method invocation to an
116: * enterprise bean’s business method.
117: * The value of trans-attribute must be one of the following:
118: * <trans-attribute>NotSupported</trans-attribute>
119: * <trans-attribute>Supports</trans-attribute>
120: * <trans-attribute>Required</trans-attribute>
121: * <trans-attribute>RequiresNew</trans-attribute>
122: * <trans-attribute>Mandatory</trans-attribute>
123: * <trans-attribute>Never</trans-attribute>
124: */
125: private byte transactionType;
126: /** Set<String> of the allowed role names */
127: private Set roles = new HashSet();
128:
129: // Static --------------------------------------------------------
130:
131: // Constructors --------------------------------------------------
132: public MethodMetaData() {
133: }
134:
135: // Public --------------------------------------------------------
136:
137: public String getMethodName() {
138: return methodName;
139: }
140:
141: public String getEjbName() {
142: return ejbName;
143: }
144:
145: public boolean isHomeMethod() {
146: return methodType == InvocationType.HOME;
147: }
148:
149: public boolean isRemoteMethod() {
150: return methodType == InvocationType.REMOTE;
151: }
152:
153: public boolean isLocalHomeMethod() {
154: return methodType == InvocationType.LOCALHOME;
155: }
156:
157: public boolean isLocalMethod() {
158: return methodType == InvocationType.LOCAL;
159: }
160:
161: public boolean isServiceEndpointMethod() {
162: return methodType == InvocationType.SERVICE_ENDPOINT;
163: }
164:
165: /** Return the interface type name.
166: *
167: * @return one of "Home", "LocalHome", "Remote", "Local", "ServiceEndpoint",
168: * or null if no interface was specified.
169: */
170: public String getInterfaceType() {
171: String type = null;
172: if (isHomeMethod())
173: type = HOME_TYPE;
174: if (isLocalHomeMethod())
175: type = LOCAL_HOME_TYPE;
176: if (isRemoteMethod())
177: type = REMOTE_TYPE;
178: if (isLocalMethod())
179: type = LOCAL_TYPE;
180: if (isServiceEndpointMethod())
181: type = SERVICE_ENDPOINT_TYPE;
182: return type;
183: }
184:
185: public boolean isUnchecked() {
186: return unchecked;
187: }
188:
189: public boolean isExcluded() {
190: return excluded;
191: }
192:
193: public boolean isIntfGiven() {
194: return intf;
195: }
196:
197: public boolean isParamGiven() {
198: return param;
199: }
200:
201: /** The method param type names.
202: * @return
203: */
204: public Iterator getParams() {
205: return paramList.iterator();
206: }
207:
208: /** The
209: *
210: * @return An array of the method parameter type names
211: */
212: public String[] getMethodParams() {
213: String[] params = new String[paramList.size()];
214: paramList.toArray(params);
215: return params;
216: }
217:
218: public byte getTransactionType() {
219: return transactionType;
220: }
221:
222: public void setTransactionType(byte type) {
223: transactionType = type;
224: }
225:
226: public Set getRoles() {
227: return roles;
228: }
229:
230: public void setRoles(Set perm) {
231: roles = perm;
232: }
233:
234: public void setUnchecked() {
235: unchecked = true;
236: }
237:
238: public void setExcluded() {
239: excluded = true;
240: }
241:
242: public boolean patternMatches(String name, Class[] arg,
243: InvocationType iface) {
244: return patternMatches(name, getClassNames(arg), iface);
245: }
246:
247: public boolean patternMatches(String name, String[] arg,
248: InvocationType iface) {
249: // the wildcard matches everything
250: if (getMethodName().equals("*")) {
251: if (methodType != null && methodType != iface)
252: return false;
253: return true;
254: }
255:
256: if (getMethodName().equals(name) == false) {
257: // different names -> no
258: return false;
259: } else {
260: // we have the same name, next check the interface type
261: if (methodType != null && methodType != iface)
262: return false;
263:
264: if (isParamGiven() == false) {
265: // no param given in descriptor -> ok
266: return true;
267: } else {
268: // we *have* to check the parameters
269: return sameParams(arg);
270: }
271: }
272: }
273:
274: /**
275: * @param a method element
276: */
277: public void importEjbJarXml(Element element)
278: throws DeploymentException {
279: methodName = getElementContent(getUniqueChild(element,
280: "method-name"));
281: ejbName = getElementContent(getUniqueChild(element, "ejb-name"));
282:
283: Element intfElement = getOptionalChild(element, "method-intf");
284: if (intfElement != null) {
285: intf = true;
286: String methodIntf = getElementContent(intfElement);
287: if (methodIntf.equals("Home")) {
288: methodType = InvocationType.HOME;
289: } else if (methodIntf.equals("Remote")) {
290: methodType = InvocationType.REMOTE;
291: } else if (methodIntf.equals("LocalHome")) {
292: methodType = InvocationType.LOCALHOME;
293: } else if (methodIntf.equals("Local")) {
294: methodType = InvocationType.LOCAL;
295: } else if (methodIntf.equals("ServiceEndpoint")) {
296: methodType = InvocationType.SERVICE_ENDPOINT;
297: } else {
298: throw new DeploymentException(
299: "method-intf tag should be one of: 'Home', 'Remote', 'LocalHome', 'Local', 'ServiceEndpoint'");
300: }
301: }
302:
303: Element paramsElement = getOptionalChild(element,
304: "method-params");
305: if (paramsElement != null) {
306: param = true;
307: paramList = new ArrayList();
308: Iterator paramsIterator = getChildrenByTagName(
309: paramsElement, "method-param");
310: while (paramsIterator.hasNext()) {
311: paramList
312: .add(getElementContent((Element) paramsIterator
313: .next()));
314: }
315: }
316: }
317:
318: // Package protected ---------------------------------------------
319:
320: // Protected -----------------------------------------------------
321:
322: // Private -------------------------------------------------------
323: private static String[] getClassNames(Class[] source) {
324: String out[] = new String[source.length];
325: for (int i = 0; i < out.length; i++) {
326: String brackets = "";
327: Class cls = source[i];
328: while (cls.isArray()) {
329: brackets += "[]";
330: cls = cls.getComponentType();
331: }
332: out[i] = cls.getName() + brackets;
333: }
334: return out;
335: }
336:
337: private boolean sameParams(String[] arg) {
338: if (arg.length != paramList.size())
339: return false;
340: for (int i = 0; i < arg.length; i++)
341: if (!arg[i].equals(paramList.get(i)))
342: return false;
343: return true;
344: }
345:
346: // Inner classes -------------------------------------------------
347: }
|