001: /*=============================================================================
002: * Copyright Texas Instruments 2000-2004. All Rights Reserved.
003: *
004: * This program is free software; you can redistribute it and/or
005: * modify it under the terms of the GNU Lesser General Public
006: * License as published by the Free Software Foundation; either
007: * version 2 of the License, or (at your option) any later version.
008: *
009: * This program is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public
015: * License along with this library; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: * $ProjectHeader: OSCRIPT 0.155 Fri, 20 Dec 2002 18:34:22 -0800 rclark $
019: */
020:
021: package oscript.data;
022:
023: import oscript.exceptions.*;
024:
025: /**
026: * A wrapper for a java package.
027: *
028: * @author Rob Clark (rob@ti.com)
029: */
030: public final class JavaPackageWrapper extends OObject {
031: /**
032: * The java package this is a wrapper for.
033: */
034: private String javaPackageName;
035:
036: /**
037: * The type object for an instance of ExactNumber.
038: */
039: public final static Value TYPE = BuiltinType
040: .makeBuiltinType("oscript.data.JavaPackageWrapper");
041: public final static String PARENT_TYPE_NAME = "oscript.data.OObject";
042: public final static String TYPE_NAME = "JavaPackage";
043: public final static String[] MEMBER_NAMES = new String[] {
044: "castToString", "getMember", };
045:
046: private static java.util.Set declaredPackageSet = new java.util.HashSet();
047:
048: /*=======================================================================*/
049: /**
050: * Used to declare the existance of a java package. A hack to work around
051: * the fact that the java vm cannot always tell us what packages exist.
052: *
053: * @param javaPackageName the java package name
054: */
055: public static void declarePackage(String javaPackageName) {
056: int idx;
057: while ((idx = javaPackageName.lastIndexOf('.')) > 0) {
058: declaredPackageSet.add(javaPackageName);
059: javaPackageName = javaPackageName.substring(0, idx);
060: }
061: }
062:
063: /*=======================================================================*/
064: /**
065: * Factory method for package-wrappers.
066: *
067: * @param javaPackageName the java package name
068: * @return the package wrapper, or <code>null</code> if no such package
069: */
070: public static Value getPackageWrapper(String javaPackageName) {
071: // XXX should packages be intern'd?
072:
073: if ((Package.getPackage(javaPackageName) != null)
074: || declaredPackageSet.contains(javaPackageName))
075: return new JavaPackageWrapper(javaPackageName);
076: return null;
077: }
078:
079: /*=======================================================================*/
080: /**
081: * Class Constructor.
082: *
083: * @param javaPackage the java package this is a wrapper for
084: */
085: private JavaPackageWrapper(String javaPackageName) {
086: super ();
087:
088: this .javaPackageName = javaPackageName;
089: }
090:
091: /*=======================================================================*/
092: /**
093: * Class Constructor.
094: *
095: * @param args arguments to this constructor
096: * @throws PackagedScriptObjectException(Exception) if wrong number of args
097: */
098: public JavaPackageWrapper(oscript.util.MemberTable args) {
099: super ();
100:
101: if (args.length() != 1)
102: throw PackagedScriptObjectException
103: .makeExceptionWrapper(new OIllegalArgumentException(
104: "wrong number of args!"));
105:
106: javaPackageName = args.referenceAt(0).castToString();
107: }
108:
109: /*=======================================================================*/
110: /**
111: * Get the type of this object. The returned type doesn't have to take
112: * into account the possibility of a script type extending a built-in
113: * type, since that is handled by {@link #getType}.
114: *
115: * @return the object's type
116: */
117: protected Value getTypeImpl() {
118: return TYPE;
119: }
120:
121: /*=======================================================================*/
122: /**
123: * Convert this object to a native java <code>String</code> value.
124: *
125: * @return a String value
126: * @throws PackagedScriptObjectException(NoSuchMethodException)
127: */
128: public String castToString() throws PackagedScriptObjectException {
129: return "[package: " + javaPackageName + "]";
130: }
131:
132: /*=======================================================================*/
133: /**
134: * Get a member of this object.
135: *
136: * @param id the id of the symbol that maps to the member
137: * @param exception whether an exception should be thrown if the
138: * member object is not resolved
139: * @return a reference to the member
140: * @throws PackagedScriptObjectException(NoSuchMethodException)
141: */
142: public Value getMember(int id, boolean exception)
143: throws PackagedScriptObjectException {
144: Integer iid = new Integer(id);
145: Object val = memberCache.get(iid);
146:
147: if (val == null) {
148: String path = javaPackageName + "."
149: + Symbol.getSymbol(id).castToString();
150: try {
151: // first see if it is a class:
152: val = JavaClassWrapper.getClassWrapper(path);
153: } catch (ClassNotFoundException e) {
154: // if not a class, try and load as package:
155: val = getPackageWrapper(path);
156: }
157:
158: memberCache.put(iid, (val != null) ? val
159: : (val = Boolean.FALSE));
160: }
161:
162: if (val == Boolean.FALSE)
163: return super .getMember(id, exception);
164:
165: return (Value) val;
166: }
167:
168: /*=======================================================================*/
169: /**
170: * Derived classes that implement {@link #getMember} should also
171: * implement this.
172: *
173: * @param s the set to populate
174: * @param debugger <code>true</code> if being used by debugger, in
175: * which case both public and private/protected field names should
176: * be returned
177: * @see #getMember
178: */
179: protected void populateMemberSet(java.util.Set s, boolean debugger) {
180: // only list what is alreay in the member-cache... a bit lame but I
181: // don't see a better way of doing this:
182: for (java.util.Iterator itr = memberCache.keySet().iterator(); itr
183: .hasNext();) {
184: Integer iid = (Integer) (itr.next());
185: if (memberCache.get(iid) != Boolean.FALSE)
186: s.add(Symbol.getSymbol(iid.intValue()));
187: }
188: }
189:
190: private final java.util.Hashtable memberCache = new java.util.Hashtable();
191: }
192:
193: /*
194: * Local Variables:
195: * tab-width: 2
196: * indent-tabs-mode: nil
197: * mode: java
198: * c-indentation-style: java
199: * c-basic-offset: 2
200: * eval: (c-set-offset 'substatement-open '0)
201: * End:
202: */
|