001: /*
002: * <copyright>
003: *
004: * Copyright 1997-2004 BBNT Solutions, LLC
005: * under sponsorship of the Defense Advanced Research Projects
006: * Agency (DARPA).
007: *
008: * You can redistribute this software and/or modify it under the
009: * terms of the Cougaar Open Source License as published on the
010: * Cougaar Open Source Website (www.cougaar.org).
011: *
012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
023: *
024: * </copyright>
025: */
026:
027: package org.cougaar.lib.contract.lang.cache;
028:
029: import java.util.*;
030: import java.lang.reflect.*;
031:
032: import org.cougaar.lib.contract.lang.*;
033:
034: /**
035: * Method lookup cache.
036: * <p>
037: * Currently no cache -- add MRU cache here.
038: **/
039: public final class MethodCache {
040:
041: /**
042: * <tt>IS_STATIC_EXPLICIT</tt> is used to prevent <tt>lookup</tt> from
043: * returning STATIC <code>Method</code>s when (<tt>isStatic</tt> == false).
044: * <p>
045: * In other words, one can find STATIC methods when looking for a
046: * non-static method. Should one take the STATIC, even though the
047: * (<tt>isStatic</tt> == false)? In Java this is allowed, e.g.
048: * <pre><code>
049: * Integer i = new Integer(2);
050: * int maxi = i.MAX_VALUE; // reference STATIC via INSTANCE
051: * </code></pre>
052: * v.s.
053: * <pre><code>
054: * int maxi = Integer.MAX_VALUE; // reference STATIC via CLASS
055: * </code></pre>
056: * <p>
057: * <tt>IS_STATIC_EXPLICIT</tt> will force the <tt>isStatic</tt> --
058: * it will disallow the "i.MAX_VALUE".
059: */
060: public static final boolean IS_STATIC_EXPLICIT = true;
061:
062: /**
063: * Find <code>Method</code> "name" in <code>Class<code> "c".
064: * @param c Class instance
065: * @param name Method name
066: * @param isStatic Method static/nonstatic -- see IS_STATIC_EXPLICIT
067: * <p>
068: * @see #IS_STATIC_EXPLICIT
069: **/
070: public static final Object lookup(final Class c, final String name,
071: final boolean isStatic) {
072: Object ret = null;
073: Method[] allMeths = c.getMethods();
074: for (int i = allMeths.length - 1; i >= 0; i--) {
075: Method m = allMeths[i];
076: // must have same name
077: if (name.equals(m.getName())) {
078: int mmods = m.getModifiers();
079: // must be PUBLIC, and must meet STATIC/NON_STATIC requirements
080: if (((mmods & Modifier.PUBLIC) != 0)
081: && (IS_STATIC_EXPLICIT ? (isStatic == ((mmods & Modifier.STATIC) != 0))
082: : (isStatic ? ((mmods & Modifier.STATIC) != 0)
083: : true))) {
084: // found method
085: if (ret == null) {
086: // found first matching Method
087: ret = m;
088: } else if (ret instanceof Method) {
089: // two possible Methods
090: List l = new ArrayList(2);
091: l.add(ret);
092: l.add(m);
093: ret = l;
094: } else {
095: // one of many possible Methods
096: ((List) ret).add(m);
097: }
098: }
099: }
100: }
101: return ret;
102: }
103:
104: /**
105: * Find <code>Method</code> "name" with <code>Class[]</code> "params"
106: * in <code>Class<code> "c".
107: * @param c Class instance
108: * @param name Method name
109: * @param params Class[] of Method arguments
110: * @param isStatic Method static/nonstatic -- see IS_STATIC_EXPLICIT
111: * <p>
112: * @see #IS_STATIC_EXPLICIT
113: **/
114: public static final Object lookup(final Class c, final String name,
115: final Class[] params, final boolean isStatic) {
116: int nparams = params.length;
117: Method[] allMeths = c.getMethods();
118: for (int i = allMeths.length - 1; i >= 0; i--) {
119: Method m = allMeths[i];
120: // must have same name
121: if (name.equals(m.getName())) {
122: int mmods = m.getModifiers();
123: // must be PUBLIC, and must meet STATIC/NON_STATIC requirements
124: if (((mmods & Modifier.PUBLIC) != 0)
125: && (IS_STATIC_EXPLICIT ? (isStatic == ((mmods & Modifier.STATIC) != 0))
126: : (isStatic ? ((mmods & Modifier.STATIC) != 0)
127: : true))) {
128: // found possible method -- check args
129: Class[] mps = m.getParameterTypes();
130: if (mps.length == nparams) {
131: for (int j = 0;; j++) {
132: if (j >= nparams) {
133: // found method
134: return m;
135: }
136: if (!(mps[j].isAssignableFrom(params[j]))) {
137: // params don't match. try next method.
138: break;
139: }
140: }
141: }
142: }
143: }
144: }
145: // no match found
146: return null;
147: }
148: }
|