001: /*
002: * Copyright 2006 Google Inc.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License"); you may not
005: * use this file except in compliance with the License. You may obtain a copy of
006: * the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
012: * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
013: * License for the specific language governing permissions and limitations under
014: * the License.
015: */
016: package com.google.gwt.dev.shell;
017:
018: import com.google.gwt.util.tools.Utility;
019:
020: import org.eclipse.swt.graphics.Image;
021:
022: import java.io.File;
023: import java.io.IOException;
024: import java.io.InputStream;
025: import java.lang.reflect.Field;
026:
027: /**
028: * Various cross-platform low-level helper methods.
029: */
030: public class LowLevel {
031:
032: public static final String PACKAGE_PATH = LowLevel.class
033: .getPackage().getName().replace('.', '/').concat("/");
034:
035: private static boolean sInitialized = false;
036:
037: /**
038: * Clobbers a field on an object to which we do not have access.
039: */
040: public static void clobberFieldObjectValue(Class<?> victimClass,
041: Object victimObject, String fieldName, Object value) {
042: Throwable rethrow = null;
043: try {
044: Field victimField = victimClass.getDeclaredField(fieldName);
045: victimField.setAccessible(true);
046: victimField.set(victimObject, value);
047: return;
048: } catch (IllegalArgumentException e) {
049: rethrow = e;
050: } catch (SecurityException e) {
051: rethrow = e;
052: } catch (IllegalAccessException e) {
053: rethrow = e;
054: } catch (NoSuchFieldException e) {
055: rethrow = e;
056: }
057: throw new RuntimeException("Unable to clobber field '"
058: + fieldName + "' from class " + victimClass.getName(),
059: rethrow);
060: }
061:
062: /**
063: * Clobbers a field on an object to which we do not have access.
064: */
065: public static void clobberFieldObjectValue(Object victim,
066: String fieldName, Object value) {
067: if (victim != null) {
068: clobberFieldObjectValue(victim.getClass(), victim,
069: fieldName, value);
070: } else {
071: throw new NullPointerException("victim must not be null");
072: }
073: }
074:
075: /**
076: * Deletes a global ref on the specified object, invalidating its handle.
077: */
078: public static void deleteGlobalRefInt(int globalRef) {
079: _deleteGlobalRefInt(globalRef);
080: }
081:
082: /**
083: * Gets an environment variable. This is to replace the deprecated
084: * {@link System#getenv(java.lang.String)}.
085: */
086: public static String getEnv(String key) {
087: return _getEnv(key);
088: }
089:
090: public static synchronized void init() {
091: if (!sInitialized) {
092: String libName = "gwt-ll";
093: try {
094: String installPath = Utility.getInstallPath();
095: try {
096: // try to make absolute
097: installPath = new File(installPath)
098: .getCanonicalPath();
099: } catch (IOException e) {
100: // ignore problems, failures will occur when the libs try to load
101: }
102: System.load(installPath + '/'
103: + System.mapLibraryName(libName));
104: } catch (UnsatisfiedLinkError e) {
105: StringBuffer sb = new StringBuffer();
106: sb.append("Unable to load required native library '"
107: + libName + "'. Detailed error:\n");
108: sb.append(e.getMessage() + ")\n\n");
109: sb.append("Your GWT installation may be corrupt");
110: System.err.println(sb.toString());
111: throw new UnsatisfiedLinkError(sb.toString());
112: }
113: sInitialized = true;
114: }
115: }
116:
117: /**
118: * Loads an image from the classpath.
119: */
120: public static Image loadImage(String name) {
121: ClassLoader cl = LowLevel.class.getClassLoader();
122: InputStream is = cl.getResourceAsStream(LowLevel.PACKAGE_PATH
123: + name);
124: if (is != null) {
125: try {
126: Image image = new Image(null, is);
127: return image;
128: } finally {
129: try {
130: is.close();
131: } catch (IOException e) {
132: }
133: }
134: } else {
135: // Bad image.
136: //
137: return new Image(null, 1, 1);
138: }
139: }
140:
141: /**
142: * Creates a global ref on the specified object, returning its int handle.
143: */
144: public static int newGlobalRefInt(Object o) {
145: return _newGlobalRefInt(o);
146: }
147:
148: /**
149: * Converts a global ref handle from {@link #newGlobalRefInt(Object)} into an
150: * Object. Use at your own risk.
151: */
152: public static Object objFromGlobalRefInt(int globalRef) {
153: return _objFromGlobalRefInt(globalRef);
154: }
155:
156: /**
157: * Snatches a field from an object to which we do not have access.
158: */
159: public static Object snatchFieldObjectValue(Class<?> victimClass,
160: Object victimObject, String fieldName) {
161: Throwable rethrow = null;
162: try {
163: Field victimField = victimClass.getDeclaredField(fieldName);
164: victimField.setAccessible(true);
165: return victimField.get(victimObject);
166: } catch (IllegalArgumentException e) {
167: rethrow = e;
168: } catch (SecurityException e) {
169: rethrow = e;
170: } catch (IllegalAccessException e) {
171: rethrow = e;
172: } catch (NoSuchFieldException e) {
173: rethrow = e;
174: }
175: throw new RuntimeException("Unable to snatch field '"
176: + fieldName + "' from class " + victimClass.getName(),
177: rethrow);
178: }
179:
180: /**
181: * Snatches a field from an object to which we do not have access.
182: */
183: public static Object snatchFieldObjectValue(Object victim,
184: String fieldName) {
185: if (victim != null) {
186: return snatchFieldObjectValue(victim.getClass(), victim,
187: fieldName);
188: } else {
189: throw new NullPointerException("victim must not be null");
190: }
191: }
192:
193: // CHECKSTYLE_NAMING_OFF
194: private static native void _deleteGlobalRefInt(int globalRef);
195:
196: private static native String _getEnv(String key);
197:
198: private static native int _newGlobalRefInt(Object o);
199:
200: private static native Object _objFromGlobalRefInt(int globalRef);
201:
202: // CHECKSTYLE_NAMING_ON
203:
204: /**
205: * This class is not instantiable.
206: */
207: private LowLevel() {
208: }
209:
210: }
|