PageRenderTime 91ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/carrot-jdk6-jnlp-macosx/src/plugin/share/classes/sun/plugin/AppletViewer.java

https://github.com/carrot-garden/carrot-jnlper
Java | 2576 lines | 1659 code | 385 blank | 532 comment | 383 complexity | 21f51583474bb70d955370f9727c809a MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * @(#)AppletViewer.java 1.249 10/03/24
  3. *
  4. * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
  5. * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package sun.plugin;
  8. /*
  9. * A recipient to show a Java Applet or a JavaBeans component in.
  10. * This class implements all platform independent behaviour of showing
  11. * an applet in one version of the Java Activator.
  12. *
  13. * @version 1.3
  14. *
  15. */
  16. import java.applet.Applet;
  17. import java.applet.AppletContext;
  18. import java.awt.Frame;
  19. import java.awt.Color;
  20. import java.awt.Component;
  21. import java.awt.Container;
  22. import java.awt.Dimension;
  23. import java.awt.Font;
  24. import java.awt.FontMetrics;
  25. import java.awt.Graphics;
  26. import java.awt.Graphics2D;
  27. import java.awt.Image;
  28. import java.awt.PopupMenu;
  29. import java.awt.MenuItem;
  30. import java.awt.RenderingHints;
  31. import java.awt.Point;
  32. import java.awt.event.ActionEvent;
  33. import java.awt.event.ActionListener;
  34. import java.awt.event.WindowEvent;
  35. import java.awt.event.WindowListener;
  36. import java.awt.event.MouseEvent;
  37. import java.awt.event.MouseListener;
  38. import java.io.BufferedInputStream;
  39. import java.io.File;
  40. import java.io.FilenameFilter;
  41. import java.io.FileInputStream;
  42. import java.io.IOException;
  43. import java.io.InputStream;
  44. import java.io.OutputStream;
  45. import java.io.ObjectInputStream;
  46. import java.lang.reflect.Method;
  47. import java.net.URL;
  48. import java.net.MalformedURLException;
  49. import java.text.MessageFormat;
  50. import java.util.ArrayList;
  51. import java.util.Enumeration;
  52. import java.util.Iterator;
  53. import java.util.Properties;
  54. import java.util.StringTokenizer;
  55. import java.util.HashMap;
  56. import java.util.Set;
  57. import java.security.AccessController;
  58. import java.security.PrivilegedAction;
  59. import java.security.Provider;
  60. import java.security.Security;
  61. import netscape.javascript.JSObject;
  62. import netscape.javascript.JSException;
  63. import sun.applet.AppletEvent;
  64. import sun.applet.AppletListener;
  65. import sun.applet.AppletPanel;
  66. import sun.applet.AppletClassLoader;
  67. import sun.applet.AppletThreadGroup;
  68. import sun.awt.AppContext;
  69. import sun.plugin.viewer.context.PluginAppletContext;
  70. import sun.plugin.javascript.JSContext;
  71. import sun.plugin.cache.JarCacheUtil;
  72. import sun.plugin.cache.JarCacheVersionException;
  73. import sun.plugin.cache.CacheUpdateHelper;
  74. import com.sun.deploy.net.proxy.DynamicProxyManager;
  75. import sun.plugin.security.PluginClassLoader;
  76. import sun.plugin.services.BrowserService;
  77. import sun.plugin.perf.PluginRollup;
  78. import sun.plugin.util.UserProfile;
  79. import sun.plugin.util.PluginSysUtil;
  80. import sun.plugin.util.ErrorDelegate;
  81. import sun.plugin.util.GrayBoxPainter;
  82. import sun.net.www.protocol.jar.URLJarFile;
  83. import com.sun.java.browser.net.ProxyService;
  84. import com.sun.java.browser.net.ProxyServiceProvider;
  85. import com.sun.deploy.config.Config;
  86. import com.sun.deploy.perf.DeployPerfUtil;
  87. import com.sun.deploy.ui.UIFactory;
  88. import com.sun.deploy.util.ConsoleHelper;
  89. import com.sun.deploy.util.UpdateCheck;
  90. import com.sun.deploy.util.URLUtil;
  91. import com.sun.deploy.cache.Cache;
  92. import com.sun.deploy.cache.MemoryCache;
  93. import com.sun.deploy.util.DeployAWTUtil;
  94. import com.sun.deploy.util.DeploySysRun;
  95. import com.sun.deploy.util.DeploySysAction;
  96. import com.sun.deploy.util.Trace;
  97. import com.sun.deploy.util.TraceLevel;
  98. import com.sun.deploy.resources.ResourceManager;
  99. public class AppletViewer extends AppletPanel implements WindowListener
  100. {
  101. private GrayBoxPainter grayBoxPainter = new GrayBoxPainter(this);
  102. private GrayBoxListener grayBoxListener = null;
  103. private String customBoxMessage = null;
  104. private boolean dumpPerf = false;
  105. private boolean loading_first_time=true;
  106. private boolean preloading = false;
  107. private volatile boolean stopped = false;
  108. private volatile boolean stopLoadJar = false;
  109. private static Frame dummyFrame = new Frame();
  110. private static String APPCONTEXT_APPLETCONTEXT_KEY = "AppletContextKey";
  111. /*
  112. * are we initialized
  113. */
  114. private static boolean initialized = false;
  115. /**
  116. * Some constants...
  117. */
  118. public static String theVersion = "1.1";
  119. private URL documentURL = null;
  120. private String documentURLString = null;
  121. protected URL baseURL = null;
  122. // Parameters handler
  123. protected java.util.HashMap atts = new java.util.HashMap();
  124. private ClassLoaderInfo cli = null;
  125. // Exception dialogboxes enable/disable status
  126. private static boolean fShowException = false;
  127. public static void loadPropertiesFiles()
  128. {
  129. DeployPerfUtil.put("START - Java - JVM - AppletViewer.loadPropertiesFiles");
  130. try
  131. {
  132. File temp = new File(UserProfile.getPropertyFile());
  133. // ensure the props folder can be made
  134. temp.getParentFile().mkdirs();
  135. }
  136. catch (Throwable e)
  137. {
  138. Trace.printException(e);
  139. }
  140. DeployPerfUtil.put("END - Java - JVM - AppletViewer.loadPropertiesFiles");
  141. }
  142. /**
  143. * activex control load time is recorded for
  144. * performance analysis
  145. */
  146. public static void setStartTime(long time) {
  147. String perfProp = System.getProperty("sun.perflog");
  148. //set the startup time if the performance logger is enabled
  149. if(perfProp != null ) {
  150. try {
  151. Class perfLogger = Class.forName("sun.misc.PerformanceLogger");
  152. if (perfLogger != null) {
  153. Class [] params = new Class[2];
  154. params[0] = String.class;
  155. params[1] = Long.TYPE;
  156. Method setMethod = perfLogger.getMethod("setStartTime", params);
  157. if(setMethod != null) {
  158. Object [] args = new Object[2];
  159. args[0] = "Java Plug-in load time";
  160. args[1] = new Long(time);
  161. setMethod.invoke(null, args);
  162. }
  163. }
  164. } catch(Exception exc) {
  165. //exc.printStackTrace();
  166. //Ignore exceptions
  167. }
  168. }
  169. }
  170. /**
  171. * Prepare the enviroment for executing applets.
  172. */
  173. public static void initEnvironment(int browserType, long startTime){
  174. if (initialized)
  175. return;
  176. setStartTime(startTime);
  177. initEnvironment(browserType);
  178. }
  179. /**
  180. * Prepare the enviroment for executing applets.
  181. */
  182. public static void initEnvironment(int browserType)
  183. {
  184. // if we are already initialized, just return
  185. if (initialized)
  186. return;
  187. initialized=true;
  188. DeployPerfUtil.put("START - Java - ENV - AppletViewer.initEnvironment");
  189. // to make sure plugin thread group is child of main thread group
  190. DeployPerfUtil.put("START - Java - ENV - " +
  191. "AppletViewer.initEnvironment - PluginSysUtil.getPluginThreadGroup");
  192. PluginSysUtil.getPluginThreadGroup();
  193. DeployPerfUtil.put("END - Java - ENV - " +
  194. "AppletViewer.initEnvironment - PluginSysUtil.getPluginThreadGroup");
  195. DeployPerfUtil.put("START - Java - ENV - " +
  196. "AppletViewer.initEnvironment - ServiceManager.setService");
  197. com.sun.deploy.services.ServiceManager.setService(browserType);
  198. DeployPerfUtil.put("END - Java - ENV - " +
  199. "AppletViewer.initEnvironment - ServiceManager.setService");
  200. // This is a hack to fix the memory leak problem in Swing.
  201. // Apparently, when these classes are loaded, it will create
  202. // Component objects that are stored in static variables.
  203. // However, each Component object bound to the caller's
  204. // AppContext. Thus, if these classes are first used by
  205. // any applet, the applet's AppContext will never be freed.
  206. // We fix this by loading these classes in the main
  207. // AppContext, so we won't leak anything.
  208. //
  209. try
  210. {
  211. Class a = javax.swing.ImageIcon.class;
  212. }
  213. catch (Throwable e)
  214. {
  215. }
  216. try
  217. {
  218. // Initialize the ClassFileTransformer for JDK 1.1
  219. // class file.
  220. DeployPerfUtil.put("START - Java - ENV - " +
  221. "AppletViewer.initEnvironment - JDK11ClassFileTransformer.init");
  222. sun.plugin.security.JDK11ClassFileTransformer.init();
  223. DeployPerfUtil.put("END - Java - ENV - " +
  224. "AppletViewer.initEnvironment - JDK11ClassFileTransformer.init");
  225. }
  226. catch (Throwable e)
  227. {
  228. e.printStackTrace();
  229. }
  230. DeployPerfUtil.put("START - Java - ENV - AppletViewer.initEnvironment - load deploy.properties");
  231. // Load deployment configuration properties
  232. Properties configProps = Config.getProperties();
  233. // Load System props (includes deployment props now)
  234. Properties props = new Properties(System.getProperties());
  235. // Define a number of standard properties
  236. props.put("acl.read", "+");
  237. props.put("acl.read.default", "");
  238. props.put("acl.write", "+");
  239. props.put("acl.write.default", "");
  240. // Standard browser properties
  241. props.put("browser.version", theVersion);
  242. props.put("browser.vendor", "Sun Microsystems, Inc.");
  243. // Set HTTP User-Agent
  244. props.put("http.agent", "Mozilla/4.0 (" + System.getProperty("os.name") + " " + System.getProperty("os.version") + ")");
  245. // turn on error stream buffering
  246. props.put("sun.net.http.errorstream.enableBuffering", "true");
  247. // Define which packages can NOT be accessed by applets
  248. props.put("package.restrict.access.sun", "true");
  249. props.put("package.restrict.access.com.sun.deploy", "true");
  250. // Define which JSS packages can NOT be accessed by applets
  251. props.put("package.restrict.access.org.mozilla.jss", "true");
  252. //
  253. // This is important to set the netscape package access to "false".
  254. // Some applets running in IE and NS will access
  255. // netscape.javascript.JSObject sometimes. If we set this
  256. // restriction to "true", these applets will not run at all.
  257. // However, if we set it to "false", the applet may continue
  258. // to run by catching an exception.
  259. props.put("package.restrict.access.netscape", "false");
  260. // Define which packages can NOT be extended by applets
  261. props.put("package.restrict.definition.java", "true");
  262. props.put("package.restrict.definition.sun", "true");
  263. props.put("package.restrict.definition.netscape", "true");
  264. props.put("package.restrict.definition.com.sun.deploy", "true");
  265. // Define which JSS packages can NOT be extended by applets
  266. props.put("package.restrict.definition.org.mozilla.jss", "true");
  267. // Define which properties can be read by applets.
  268. // A property named by "key" can be read only when its twin
  269. // property "key.applet" is true. The following ten properties
  270. // are open by default. Any other property can be explicitly
  271. // opened up by the browser user setting key.applet=true in
  272. // ~/.java/properties. Or vice versa, any of the following can
  273. // be overridden by the user's properties.
  274. props.put("java.version.applet", "true");
  275. props.put("java.vendor.applet", "true");
  276. props.put("java.vendor.url.applet", "true");
  277. props.put("java.class.version.applet", "true");
  278. props.put("os.name.applet", "true");
  279. props.put("os.version.applet", "true");
  280. props.put("os.arch.applet", "true");
  281. props.put("file.separator.applet", "true");
  282. props.put("path.separator.applet", "true");
  283. props.put("line.separator.applet", "true");
  284. // Install new protocol handler
  285. String pkgs = (String) props.getProperty("java.protocol.handler.pkgs");
  286. if (pkgs != null)
  287. props.put("java.protocol.handler.pkgs", pkgs + "|sun.plugin.net.protocol|com.sun.deploy.net.protocol");
  288. else
  289. props.put("java.protocol.handler.pkgs", "sun.plugin.net.protocol|com.sun.deploy.net.protocol");
  290. // Set allow default user interaction in HTTP/HTTPS
  291. DeployPerfUtil.put("START - Java - ENV - " +
  292. "AppletViewer.initEnvironment - URLConnection.setDefaultAllowUserInteraction");
  293. java.net.URLConnection.setDefaultAllowUserInteraction(true);
  294. DeployPerfUtil.put("END - Java - ENV - " +
  295. "AppletViewer.initEnvironment - URLConnection.setDefaultAllowUserInteraction");
  296. // Set default SSL handshaking protocols to SSLv3 and SSLv2Hello
  297. // because some servers may not be able to handle TLS. #46268654.
  298. //
  299. // Set only if users hasn't set it manually.
  300. //
  301. // Added options to enable/disable SSLv2/SSLv3/TLSv1 in Control Panel.
  302. //
  303. if (props.get("https.protocols") == null){
  304. StringBuffer protocolsStr = new StringBuffer();
  305. if (Config.getBooleanProperty(Config.SEC_TLS_KEY)){
  306. protocolsStr.append("TLSv1");
  307. }
  308. if (Config.getBooleanProperty(Config.SEC_SSLv3_KEY)){
  309. if (protocolsStr.length() != 0){
  310. protocolsStr.append(",");
  311. }
  312. protocolsStr.append("SSLv3");
  313. }
  314. if (Config.getBooleanProperty(Config.SEC_SSLv2_KEY)){
  315. if (protocolsStr.length() != 0){
  316. protocolsStr.append(",");
  317. }
  318. protocolsStr.append("SSLv2Hello");
  319. }
  320. props.put("https.protocols", protocolsStr.toString());
  321. }
  322. // Add new system property for proxy authentication
  323. props.put("http.auth.serializeRequests", "true");
  324. // Initialize tracing environment
  325. DeployPerfUtil.put("START - Java - ENV - " +
  326. "AppletViewer.initEnvironment - JavaRunTime.initTraceEnvironment");
  327. sun.plugin.JavaRunTime.initTraceEnvironment();
  328. DeployPerfUtil.put("END - Java - ENV - " +
  329. "AppletViewer.initEnvironment - JavaRunTime.initTraceEnvironment");
  330. // Look in the user choices if we should open the Java Console
  331. String consoleStartup = Config.getProperty(Config.CONSOLE_MODE_KEY);
  332. DeployPerfUtil.put("START - Java - ENV - " +
  333. "AppletViewer.initEnvironment - display JavaConsole");
  334. if( (Config.CONSOLE_MODE_SHOW).equalsIgnoreCase(consoleStartup))
  335. {
  336. //This is when we want full size Java Console.
  337. sun.plugin.JavaRunTime.showJavaConsole(true);
  338. }
  339. else if( (Config.CONSOLE_MODE_DISABLED).equalsIgnoreCase(consoleStartup))
  340. {
  341. // We do not want the Console at all, so don't start it!
  342. }
  343. else
  344. {
  345. // Hide Java Console
  346. BrowserService service = (BrowserService) com.sun.deploy.services.ServiceManager.getService();
  347. // Start console in hidden state if console cannot be
  348. // accessible through browser menu. Otherwise, delay
  349. // console loading until users access the menu
  350. //
  351. if (service.isConsoleIconifiedOnClose())
  352. {
  353. // Start console in hidden/iconified state
  354. sun.plugin.JavaRunTime.showJavaConsole(false);
  355. }
  356. }
  357. sun.plugin.JavaRunTime.installConsoleTraceListener();
  358. DeployPerfUtil.put("END - Java - ENV - " +
  359. "AppletViewer.initEnvironment - display JavaConsole");
  360. //Check whether the exception dialogboxes are allowed
  361. if ("true".equalsIgnoreCase(props.getProperty(Config.SHOW_EXCEPTIONS_KEY, "false"))) {
  362. fShowException = true;
  363. }
  364. // Set the default connection timeout value
  365. // to 120 seconds (2 minutes)
  366. String timeout = (String) props.getProperty("sun.net.client.defaultConnectTimeout", "120000");
  367. // Connection timeout not already set, so set it
  368. props.put("sun.net.client.defaultConnectTimeout", timeout);
  369. DeployPerfUtil.put("START - Java - ENV - " +
  370. "AppletViewer.initEnvironment - install extension package");
  371. try {
  372. Class c = Class.forName("sun.misc.ExtensionDependency");
  373. if (c != null) {
  374. Class[] parms = new Class[1];
  375. parms[0] = Class.forName("sun.misc.ExtensionInstallationProvider");
  376. java.lang.reflect.Method m = c.getMethod("addExtensionInstallationProvider", parms);
  377. if (m != null) {
  378. Object[] args = new Object[1];
  379. args[0] = new sun.plugin.extension.ExtensionInstallationImpl();
  380. m.invoke(null, args);
  381. } else {
  382. Trace.msgPrintln("optpkg.install.error.nomethod");
  383. }
  384. } else {
  385. Trace.msgPrintln("optpkg.install.error.noclass");
  386. }
  387. } catch(Throwable e) {
  388. Trace.printException(e);
  389. }
  390. DeployPerfUtil.put("END - Java - ENV - " +
  391. "AppletViewer.initEnvironment - install extension package");
  392. // Remove Proxy Host & Port
  393. props.remove("proxyHost");
  394. props.remove("proxyPort");
  395. props.remove("http.proxyHost");
  396. props.remove("http.proxyPort");
  397. props.remove("https.proxyHost");
  398. props.remove("https.proxyPort");
  399. props.remove("ftpProxyHost");
  400. props.remove("ftpProxyPort");
  401. props.remove("ftpProxySet");
  402. props.remove("gopherProxyHost");
  403. props.remove("gopherProxyPort");
  404. props.remove("gopherProxySet");
  405. props.remove("socksProxyHost");
  406. props.remove("socksProxyPort");
  407. // Enable proxy/web server authentication
  408. if ("true".equalsIgnoreCase(props.getProperty("javaplugin.proxy.authentication",
  409. "true"))) {
  410. DeployPerfUtil.put("START - Java - ENV - " +
  411. "AppletViewer.initEnvironment - enable proxy/web server authentication");
  412. java.net.Authenticator.setDefault(new com.sun.deploy.security.DeployAuthenticator());
  413. DeployPerfUtil.put("END - Java - ENV - " +
  414. "AppletViewer.initEnvironment - enable proxy/web server authentication");
  415. }
  416. // Install a property list.
  417. System.setProperties(props);
  418. DeployPerfUtil.put("END - Java - ENV - AppletViewer.initEnvironment - load deploy.properties");
  419. System.out.println("");
  420. // Reset proxy selector
  421. DeployPerfUtil.put("START - Java - ENV - " +
  422. "AppletViewer.initEnvironment - DeployProxySelector.reset");
  423. com.sun.deploy.net.proxy.DeployProxySelector.reset();
  424. DeployPerfUtil.put("END - Java - ENV - " +
  425. "AppletViewer.initEnvironment - DeployProxySelector.reset");
  426. // Reset cookie selector
  427. DeployPerfUtil.put("START - Java - ENV - " +
  428. "AppletViewer.initEnvironment - DeployCookieSelector.reset");
  429. com.sun.deploy.net.cookie.DeployCookieSelector.reset();
  430. DeployPerfUtil.put("END - Java - ENV - " +
  431. "AppletViewer.initEnvironment - DeployCookieSelector.reset");
  432. // Reset offline manager
  433. DeployPerfUtil.put("START - Java - ENV - " +
  434. "AppletViewer.initEnvironment - DeployOfflineManager.reset");
  435. com.sun.deploy.net.offline.DeployOfflineManager.reset();
  436. DeployPerfUtil.put("END - Java - ENV - " +
  437. "AppletViewer.initEnvironment - DeployOfflineManager.reset");
  438. System.out.println("");
  439. // init cache
  440. // this is to make sure the static block of com.sun.deploy.cache.Cache
  441. // gets executed in the correct thread group; so that the cache
  442. // clean-up thread will get created in the correct thread group
  443. DeployPerfUtil.put("START - Java - ENV - " +
  444. "AppletViewer.initEnvironment - DeployCacheHandler.reset");
  445. Class cache = com.sun.deploy.cache.Cache.class;
  446. // Set deploy cache handler
  447. com.sun.deploy.cache.DeployCacheHandler.reset();
  448. DeployPerfUtil.put("END - Java - ENV - " +
  449. "AppletViewer.initEnvironment - DeployCacheHandler.reset");
  450. System.out.println("");
  451. // Install progress monitor for progress bar support
  452. DeployPerfUtil.put("START - Java - ENV - " +
  453. "AppletViewer.initEnvironment - ProgressMonitor.setDefault");
  454. sun.net.ProgressMonitor.setDefault(new sun.plugin.util.ProgressMonitor());
  455. DeployPerfUtil.put("END - Java - ENV - " +
  456. "AppletViewer.initEnvironment - ProgressMonitor.setDefault");
  457. // Install security manager, so everyone feels
  458. // warm and fuzzy. Hold me, the way I need to be held.
  459. DeployPerfUtil.put("START - Java - ENV - " +
  460. "AppletViewer.initEnvironment - install security manager");
  461. sun.plugin.security.ActivatorSecurityManager security = new sun.plugin.security.ActivatorSecurityManager();
  462. System.setSecurityManager(security);
  463. DeployPerfUtil.put("END - Java - ENV - " +
  464. "AppletViewer.initEnvironment - install security manager");
  465. // REMIND: Create and install a socket factory!
  466. // All initialization is done, show help information in Java Console.
  467. DeployPerfUtil.put("START - Java - ENV - " +
  468. "AppletViewer.initEnvironment - ConsoleHelper.displayHelp");
  469. System.out.println(ConsoleHelper.displayHelp());
  470. DeployPerfUtil.put("END - Java - ENV - " +
  471. "AppletViewer.initEnvironment - ConsoleHelper.displayHelp");
  472. // validate system cache directory
  473. DeployPerfUtil.put("START - Java - ENV - " +
  474. "AppletViewer.initEnvironment - Config.validateSystemCacheDirectory");
  475. Config.validateSystemCacheDirectory();
  476. DeployPerfUtil.put("END - Java - ENV - " +
  477. "AppletViewer.initEnvironment - Config.validateSystemCacheDirectory");
  478. // Set the interface to call back to plugin.
  479. DeployPerfUtil.put("START - Java - ENV - " +
  480. "AppletViewer.initEnvironment - URLJarFile.setCallBack");
  481. URLJarFile.setCallBack(new PluginURLJarFileCallBack());
  482. DeployPerfUtil.put("END - Java - ENV - " +
  483. "AppletViewer.initEnvironment - URLJarFile.setCallBack");
  484. // Prompt User for JavaUpdate Enabling, if Windows platform
  485. if (System.getProperty("os.name").indexOf("Windows") != -1)
  486. {
  487. DeployPerfUtil.put("START - Java - ENV - " +
  488. "AppletViewer.initEnvironment - show update message");
  489. UpdateCheck.showDialog();
  490. DeployPerfUtil.put("END - Java - ENV - " +
  491. "AppletViewer.initEnvironment - show update message");
  492. }
  493. // Upgrade old (1.4.2/5.0) plugin cache to 6.0 format
  494. // this needs to be run in the plugin system thread group, because
  495. // it will show the cache upgrade progress dialog
  496. DeployPerfUtil.put("START - Java - ENV - " +
  497. "AppletViewer.initEnvironment - upgrade cache");
  498. try {
  499. DeploySysRun.executePrivileged(new DeploySysAction() {
  500. public Object execute() {
  501. if (Config.getBooleanProperty(Config.JAVAPI_UPDATE_KEY)) {
  502. if (CacheUpdateHelper.updateCache()) {
  503. Config.setBooleanProperty(Config.JAVAPI_UPDATE_KEY, false);
  504. Config.storeIfDirty();
  505. }
  506. }
  507. return null;
  508. }
  509. }, null);
  510. } catch (Exception e) {
  511. Trace.printException(e);
  512. }
  513. DeployPerfUtil.put("END - Java - ENV - " +
  514. "AppletViewer.initEnvironment - upgrade cache");
  515. try {
  516. sun.awt.DesktopBrowse.setInstance(new sun.awt.DesktopBrowse() {
  517. public void browse(URL url) {
  518. AppletContext ac = (AppletContext) (
  519. AppContext.getAppContext().get(
  520. APPCONTEXT_APPLETCONTEXT_KEY));
  521. if (ac != null) {
  522. ac.showDocument(url);
  523. }
  524. }
  525. });
  526. } catch (Throwable t) {
  527. com.sun.deploy.util.Trace.ignored(t);
  528. }
  529. DeployPerfUtil.put("END - Java - ENV - AppletViewer.initEnvironment");
  530. }
  531. /**
  532. * Construct a new applet viewer.
  533. * Restricted to subclasses for security reasons,
  534. */
  535. public AppletViewer()
  536. {
  537. // Don't set it to light gray! User could specify color, then gray will blink in
  538. //the beginning - not pretty.
  539. //setBackground(Color.lightGray);
  540. }
  541. private static class AppletEventListener implements AppletListener
  542. {
  543. public void appletStateChanged(AppletEvent evt) {
  544. AppletViewer src = (AppletViewer) evt.getSource();
  545. switch (evt.getID()) {
  546. case AppletPanel.APPLET_RESIZE: {
  547. if(src != null)
  548. {
  549. Object obj = src.getViewedObject();
  550. if (obj instanceof Component)
  551. {
  552. src.setSize(src.getSize());
  553. ((Component)obj).setSize(src.getSize());
  554. src.validate();
  555. }
  556. }
  557. break;
  558. }
  559. case AppletPanel.APPLET_LOADING_COMPLETED: {
  560. src.notifyLoadingDone();
  561. break;
  562. }
  563. }
  564. }
  565. }
  566. private AppletEventListener appletEventListener = new AppletEventListener();
  567. private Object syncInit = new Object();
  568. private boolean bInit = false;
  569. /**
  570. * Init the applet, called once to start the download of the applet
  571. */
  572. public void appletInit()
  573. {
  574. if (! Config.isConfigValid()) {
  575. UIFactory.showErrorDialog(null,
  576. ResourceManager.getString("launcherrordialog.brief.message.applet"),
  577. ResourceManager.getString("enterprize.cfg.mandatory.applet",
  578. Config.getEnterprizeString()),
  579. ResourceManager.getString("error.default.title.applet"));
  580. //notify loading is aborted
  581. notifyLoadingDone();
  582. return;
  583. }
  584. //Do not initialize applet if classloader creation fails because of
  585. //not able to get codebase
  586. if(createClassLoader()) {
  587. initApplet();
  588. } else {
  589. assert (status == AppletPanel.APPLET_DISPOSE
  590. || status == AppletPanel.APPLET_ERROR
  591. || status == AppletPanel.APPLET_QUIT);
  592. notifyLoadingDone();
  593. }
  594. }
  595. private final static String VERSION_TAG = "version=";
  596. private HashMap jarVersionMap = new HashMap();
  597. private HashMap preloadJarMap = new HashMap();
  598. private ArrayList newStyleJarList = new ArrayList();
  599. private final static String PRELOAD = "preload";
  600. /*
  601. * initialize the jar version/preload map
  602. *
  603. */
  604. private void initJarVersionMap() {
  605. int i = 1;
  606. String archive_tag_value = getParameter("archive_" + i);
  607. String tokenString;
  608. if (archive_tag_value != null) {
  609. // process new style tags
  610. while (archive_tag_value != null) {
  611. // process the archive tag string
  612. // parse the string and extract tokens separated by comma
  613. StringTokenizer archiveTok = new StringTokenizer(archive_tag_value, ",", false);
  614. String jarName = null;
  615. String version = null;
  616. boolean preloadJar = false;
  617. while(archiveTok.hasMoreTokens()){
  618. tokenString = archiveTok.nextToken().trim();
  619. // first argument must be jar name
  620. if (jarName == null) {
  621. jarName = tokenString;
  622. } else if (tokenString.toLowerCase().startsWith(VERSION_TAG)) {
  623. version = tokenString.substring(VERSION_TAG.length());
  624. } else if (tokenString.toLowerCase().equals(PRELOAD)) {
  625. preloadJar = true;
  626. }
  627. }
  628. if (jarName != null) {
  629. if (preloadJar) {
  630. preloadJarMap.put(jarName, version);
  631. }
  632. jarVersionMap.put(jarName, version);
  633. newStyleJarList.add(jarName);
  634. }
  635. i++;
  636. archive_tag_value = getParameter("archive_" + i);
  637. }
  638. } else {
  639. // process old style tags
  640. String jpi_archive = getParameter("cache_archive");
  641. String jpi_version = getParameter("cache_version");
  642. String jpi_archive_ex = getParameter("cache_archive_ex");
  643. try {
  644. // use old style tags, cache_archive, cache_version and cache_archive_ex
  645. jarVersionMap = JarCacheUtil.getJarsWithVersion(jpi_archive, jpi_version,
  646. jpi_archive_ex);
  647. } catch (Exception ex) {
  648. Trace.printException(ex, ResourceManager.getMessage("cache.error.text"),
  649. ResourceManager.getMessage("cache.error.caption"));
  650. }
  651. // Figure out which JAR files still need to be loaded.
  652. if (jpi_archive_ex != null) {
  653. StringTokenizer jarTok = new StringTokenizer(jpi_archive_ex, ",", false);
  654. while (jarTok.hasMoreTokens()) {
  655. String elem = jarTok.nextToken().trim();
  656. int optionIndex = elem.indexOf(';');
  657. if(optionIndex != -1) {
  658. String optionString = elem.substring(optionIndex);
  659. if(optionString.toLowerCase().indexOf(PRELOAD) != -1) {
  660. String jarFileName = elem.substring(0, optionIndex);
  661. preloadJarMap.put(jarFileName, null);
  662. }
  663. }
  664. }
  665. }
  666. }
  667. }
  668. private void storeJarVersionMapInAppContext() {
  669. // iterate the jarVesrionMap and store into Applet AppContext
  670. Iterator iter = jarVersionMap.keySet().iterator();
  671. while(iter.hasNext()) {
  672. String jarName = (String)iter.next();
  673. String jarVersion = (String)jarVersionMap.get(jarName);
  674. URL url = null;
  675. try {
  676. // this will resolve a/abc/../ to a/ in the url
  677. url = new URL(getCodeBase(), jarName);
  678. } catch (MalformedURLException mue) {
  679. // should not happen
  680. com.sun.deploy.util.Trace.ignoredException(mue);
  681. }
  682. if (url != null) {
  683. AppContext.getAppContext().put(Config.getAppContextKeyPrefix() +
  684. url.toString(), jarVersion);
  685. }
  686. }
  687. }
  688. /**
  689. * Create ClassLoader, ThreadGroup and AppContext
  690. * This method is used to get or create ClassLoader
  691. * for an applet codebase and increament ClassLoaderInfo's
  692. * references count
  693. *
  694. * This method is called early in creating embedded frame
  695. *
  696. * @return AppletClassLoader
  697. *
  698. */
  699. public AppletClassLoader getAppletClassLoader() {
  700. AppletClassLoader loader = null;
  701. URL cbUrl = getCodeBase();
  702. if (cbUrl == null) {
  703. System.err.println("ERROR: unexpectedly couldn't get the codebase");
  704. return null;
  705. }
  706. //Create the applet class loader and force it to create its thread group
  707. ClassLoaderInfo info =
  708. ClassLoaderInfo.find(cbUrl, getClassLoaderCacheKey());
  709. if (info == null) {
  710. System.err.println("ERROR: unexpectedly couldn't get the ClassLoaderInfo for the codebase/cache key");
  711. } else {
  712. //set AppletViewer's field cli
  713. cli = info;
  714. //create or get class loader, threadgroup, AppContext
  715. //and addReference() in ClassloaderInfo
  716. loader = info.grabClassLoader();
  717. URL documentBase = getDocumentBase();
  718. if (documentBase == null ||
  719. documentBase.getProtocol().equalsIgnoreCase("file") == false ||
  720. URLUtil.isUNCFileURL(documentBase)) {
  721. // do not allow recursive codebase direcotry read if:
  722. // 1. documentBase is null
  723. // 2. documentBase is not file protocol url
  724. // 3. documentBase url is UNC file url
  725. loader.disableRecursiveDirectoryRead();
  726. }
  727. }
  728. return loader;
  729. }
  730. /**
  731. * Create the classloader and threadgroup if they have not been
  732. * created.
  733. *
  734. * Create Applet thread
  735. */
  736. public boolean createClassLoader()
  737. {
  738. DeployPerfUtil.put("START - Java - ENV - AppletViewer.createClassLoader");
  739. // Add applet event listener
  740. addAppletListener(appletEventListener);
  741. initJarVersionMap();
  742. URL cbUrl = getCodeBase();
  743. if(cbUrl == null) {
  744. return false;
  745. }
  746. try{
  747. if(!jarVersionMap.isEmpty())
  748. verifyJarVersions(cbUrl, getClassLoaderCacheKey(), jarVersionMap);
  749. } catch(Exception ex) {
  750. Trace.printException(ex, ResourceManager.getMessage("cache.error.text"),
  751. ResourceManager.getMessage("cache.error.caption"));
  752. }
  753. // Add applet into AppletContext
  754. appletContext.addAppletPanelInContext(this);
  755. // We must synchronized the class because
  756. // super.init() will create classloader -
  757. // and we need the creation to be synchronized
  758. //
  759. synchronized(AppletViewer.class)
  760. {
  761. super.init();
  762. }
  763. DeployPerfUtil.put("END - Java - ENV - AppletViewer.createClassLoader");
  764. return true;
  765. }
  766. private void verifyJarVersions(URL codeBase, String key, HashMap jarFileVersionMap)
  767. throws IOException, JarCacheVersionException {
  768. boolean markClassLoader = false;
  769. //If versions are specified for all the jar files, try to mark
  770. //the cached files
  771. Iterator iter = jarFileVersionMap.keySet().iterator();
  772. while(iter.hasNext()) {
  773. String jarFileName = (String)iter.next();
  774. String jarFileVersion = (String)jarFileVersionMap.get(jarFileName);
  775. URL url = new URL(codeBase, jarFileName);
  776. Trace.msgNetPrintln("cache.version_checking", new Object[] {jarFileName, jarFileVersion});
  777. // only check versioned resource
  778. if (jarFileVersion != null) {
  779. String cacheVersion = Cache.getCacheEntryVersion(url, null);
  780. // if there's a cached jar file, check if the version of the cached jar satisfies the required version
  781. if (cacheVersion != null && cacheVersion.compareTo(jarFileVersion) < 0) {
  782. // there is no cached jar that matches the required
  783. // version
  784. markClassLoader = true;
  785. }
  786. }
  787. }
  788. //If one of the jar file has been modified, clear the classloader since
  789. //it is no longer correct to use it.
  790. if(markClassLoader == true) {
  791. ClassLoaderInfo.markNotCachable(codeBase, key);
  792. }
  793. }
  794. /*
  795. * Override super class createAppletThread to not grab the class loader
  796. * reference since we now grab it when creating embedded frame
  797. */
  798. protected synchronized void createAppletThread() {
  799. String nm = "applet-" + getCode();
  800. //get the threadgroup for this applet panel
  801. //the threadgroup was created when create the embedded frame
  802. ThreadGroup appletGroup = loader.getThreadGroup();
  803. handler = new Thread(appletGroup, this, "thread " + nm);
  804. // set the context class loader for this thread
  805. AccessController.doPrivileged(new PrivilegedAction() {
  806. public Object run() {
  807. handler.setContextClassLoader(loader);
  808. return null;
  809. }
  810. });
  811. handler.start();
  812. }
  813. /*
  814. * Helper method to set the AppletClassLoader in the super class.
  815. */
  816. public void setLoader(AppletClassLoader acl) {
  817. loader = acl;
  818. }
  819. /**
  820. * Load & Initialize the applet
  821. */
  822. public void initApplet()
  823. {
  824. DeployPerfUtil.put("START - Java - ENV - AppletViewer.initApplet");
  825. // After super.init() is called, applet handler thread is
  826. // created. Added applet thread group into tracing.
  827. //
  828. Thread t = getAppletHandlerThread();
  829. // Setup animation in graybox (only the first time)
  830. if (!bInit) {
  831. // Set up the error delegate
  832. grayBoxPainter.setErrorDelegate(new ErrorDelegate() {
  833. public void handleReloadApplet() {
  834. ClassLoaderInfo.clearClassLoaderCache();
  835. getAppletContext().showDocument(getDocumentBase());
  836. }
  837. public String getCodeBase() {
  838. return AppletViewer.this.getCodeBase().toString();
  839. }
  840. public void addJarFilesToSet(Set/*<String>*/ jarSet) {
  841. String jars = getJarFiles();
  842. if (jars != null){
  843. // Jar files are separated by ","
  844. StringTokenizer jarTok =
  845. new StringTokenizer(jars, ",", false);
  846. int jarCount = jarTok.countTokens();
  847. for(int i=0; i<jarCount; i++) {
  848. String jarFileName = jarTok.nextToken().trim();
  849. jarSet.add(jarFileName);
  850. }
  851. }
  852. }
  853. });
  854. // See if user specified special image to be shown
  855. String user_image = getParameter("image");
  856. if (user_image != null) {
  857. try {
  858. URL customImageURL = new URL(getCodeBase(), user_image);
  859. boolean centerImage = Boolean.valueOf(getParameter("centerimage")).booleanValue();
  860. grayBoxPainter.setBoxBorder(getParameter("boxborder"));
  861. grayBoxPainter.setCustomImageURL(customImageURL, centerImage);
  862. } catch (MalformedURLException e) {
  863. e.printStackTrace();
  864. }
  865. }
  866. // Get a list of jar files
  867. grayBoxPainter.setProgressFilter(getCodeBase(), getJarFiles());
  868. grayBoxPainter.beginPainting(t.getThreadGroup());
  869. // Add mouse listener
  870. grayBoxListener = new GrayBoxListener(this, customBoxMessage);
  871. addMouseListener(grayBoxListener);
  872. } else {
  873. grayBoxPainter.resumePainting();
  874. }
  875. Trace.msgPrintln("applet.progress.load");
  876. sendEvent(sun.applet.AppletPanel.APPLET_LOAD);
  877. }
  878. public void sendAppletInit() {
  879. Trace.msgPrintln("applet.progress.init");
  880. sendEvent(sun.applet.AppletPanel.APPLET_INIT);
  881. // Mark viewer as initialized
  882. synchronized(syncInit)
  883. {
  884. bInit = true;
  885. }
  886. DeployPerfUtil.put("END - Java - ENV - AppletViewer.initApplet");
  887. }
  888. /**
  889. * Tell loader thread to stop loading
  890. * Override
  891. */
  892. public void stopLoading() {
  893. stopLoadJar = true;
  894. if (status == APPLET_LOAD) {
  895. Trace.msgPrintln("applet.progress.stoploading");
  896. super.stopLoading();
  897. }
  898. }
  899. /**
  900. * Start the applet.
  901. */
  902. public void appletStart()
  903. {
  904. // Do nothing if viewer hasn't been initialized
  905. synchronized(syncInit)
  906. {
  907. if (bInit == false)
  908. return;
  909. }
  910. if (stopped) {
  911. // when we first start, we need to wait till showAppletStatus()
  912. // to turn off animation. On a restart, we will never get
  913. // to showAppletStatus with (status >= APPLET_START)
  914. // so we suspend here.
  915. final GrayBoxPainter gbp = grayBoxPainter;
  916. suspendGrayBoxPainting(gbp);
  917. stopped = false;
  918. }
  919. Trace.msgPrintln("applet.progress.start");
  920. try {
  921. DeployPerfUtil.write(new PluginRollup(), false);
  922. Trace.println("completed perf rollup", TraceLevel.BASIC);
  923. dumpPerf = true;
  924. }
  925. catch (IOException ioe) {
  926. // ignore exception
  927. }
  928. sendEvent(sun.applet.AppletPanel.APPLET_START);
  929. }
  930. /**
  931. * Stop the applet.
  932. */
  933. public void appletStop()
  934. {
  935. stopped = true;
  936. // Do nothing if viewer hasn't been initialized
  937. synchronized(syncInit)
  938. {
  939. if (bInit == false)
  940. return;
  941. }
  942. if (grayBoxPainter != null)
  943. {
  944. //may be called on main thread in Netscape plugin
  945. final GrayBoxPainter gbp = grayBoxPainter;
  946. suspendGrayBoxPainting(gbp);
  947. }
  948. if (status==APPLET_LOAD)
  949. {
  950. stopLoading();
  951. }
  952. Trace.msgPrintln("applet.progress.stop");
  953. sendEvent(sun.applet.AppletPanel.APPLET_STOP);
  954. }
  955. private void suspendGrayBoxPainting(final GrayBoxPainter gbp) {
  956. //suspendPainting need get Awt Treelock
  957. //it may block the main thread. Use invokeLater
  958. //let's look for the tartget component
  959. Component target = null;
  960. if (getApplet() != null) {
  961. //use applet
  962. target = (Component)getApplet();
  963. } else {
  964. if (getParent() != null) {
  965. //panel has added to frame. use frame
  966. target = (Component)getParent();
  967. } else {
  968. //use panel. AppContext is main
  969. target = (Component) this;
  970. }
  971. }
  972. DeployAWTUtil.invokeLater(target,
  973. new Runnable() {
  974. public void run() {
  975. gbp.suspendPainting();
  976. }
  977. }
  978. );
  979. }
  980. /* used for sync loader and main thread
  981. */
  982. private boolean loadingDone = false;
  983. private final Object syncLoading = new Object();
  984. public void notifyLoadingDone() {
  985. synchronized (syncLoading) {
  986. loadingDone = true;
  987. syncLoading.notify();
  988. }
  989. }
  990. public void waitForLoadingDone(long timeout) {
  991. try {
  992. synchronized (syncLoading) {
  993. while (!loadingDone) {
  994. syncLoading.wait(timeout);
  995. }
  996. }
  997. } catch (InterruptedException e) {
  998. //Trace.printException(e);
  999. } catch (Exception e) {
  1000. Trace.printException(e);
  1001. }
  1002. }
  1003. /**
  1004. * Notification that the applet is being closed
  1005. *
  1006. */
  1007. public void appletDestroy()
  1008. {
  1009. stopped = true;
  1010. // Destroy gray box painter
  1011. if (grayBoxPainter != null)
  1012. {
  1013. //this is called on the shutdown thread
  1014. //it is ok to not use invokeLater
  1015. grayBoxPainter.finishPainting();
  1016. grayBoxPainter = null;
  1017. }
  1018. // Remove graybox listener
  1019. if (grayBoxListener != null)
  1020. {
  1021. removeMouseListener(grayBoxListener);
  1022. grayBoxListener = null;
  1023. }
  1024. Trace.msgPrintln("applet.progress.destroy");
  1025. sendEvent(APPLET_DESTROY);
  1026. Trace.msgPrintln("applet.progress.dispose");
  1027. sendEvent(APPLET_DISPOSE);
  1028. }
  1029. //cleanup when plugin object is not initialized
  1030. //Applet panel has not add reference to classloaderinfo
  1031. //and has not created applet thread
  1032. public void miniCleanup() {
  1033. // Remove applet event listeners
  1034. removeAppletListener(appletEventListener);
  1035. appletEventListener = null;
  1036. // Remove applet from the context first, so it won't be called
  1037. if (appletContext != null) {
  1038. appletContext.removeAppletPanelFromContext(this);
  1039. appletContext = null;
  1040. }
  1041. }
  1042. public void cleanup() {
  1043. miniCleanup();
  1044. Trace.msgPrintln("applet.progress.joining");
  1045. joinAppletThread();
  1046. Trace.msgPrintln("applet.progress.joined");
  1047. }
  1048. public void joinAppletThread() {
  1049. Thread appletThread = getAppletHandlerThread();
  1050. if (appletThread != null) {
  1051. try {
  1052. appletThread.join(1000);
  1053. } catch (Exception e) {
  1054. Trace.printException(e);
  1055. }
  1056. //if the applet thread is still alive after timeout, interrupt it
  1057. if (appletThread.isAlive()) {
  1058. appletThread.interrupt();
  1059. }
  1060. }
  1061. }
  1062. public void release() {
  1063. if (cli == null ) {
  1064. cli = ClassLoaderInfo.find(getCodeBase(), getClassLoaderCacheKey());
  1065. }
  1066. AppletClassLoader loader = cli.getLoader();
  1067. ThreadGroup group = (loader == null)? null : loader.getThreadGroup();
  1068. PluginClassLoader pcl = null;
  1069. AppContext context = null;
  1070. // Additional synchronization on ClassLoaderInfo needed
  1071. // to prevent reference count from being incremented in
  1072. // e.g. ClassLoaderInfo.grabClassLoader() during
  1073. // PluginClassLoader.resetAppContext() because the method may
  1074. // mark ClassLoader's AppContext and ThreadGroup to be destroyed
  1075. synchronized (cli) {
  1076. // Release classloader reference
  1077. Trace.msgPrintln("applet.progress.findinfo.0");
  1078. int refCount = cli.removeReference();
  1079. Trace.msgPrintln("applet.progress.findinfo.1");
  1080. if (refCount > 0) {
  1081. //do nothing
  1082. return;
  1083. }
  1084. if (loader != null && loader instanceof PluginClassLoader) {
  1085. pcl = (PluginClassLoader)loader;
  1086. Trace.msgPrintln("applet.progress.quit");
  1087. context = pcl.resetAppContext();
  1088. }
  1089. }
  1090. //dispose AppContext outside the synchronized block
  1091. pcl.release(context);
  1092. long startTime = System.currentTimeMillis();
  1093. while (group != null && group.activeCount() > 0
  1094. && System.currentTimeMillis() - startTime < 5000) {
  1095. group.stop();
  1096. try {
  1097. Thread.sleep(10);
  1098. } catch (InterruptedException e) { }
  1099. }
  1100. cli = null;
  1101. }
  1102. /**
  1103. * Pre-refresh the applet
  1104. */
  1105. public void preRefresh()
  1106. {
  1107. // Clear cache files and jars in memory
  1108. MemoryCache.clearLoadedResources();
  1109. // Mark the classloader as non-cachable
  1110. if (cli != null)
  1111. {
  1112. cli.markNotCachable(getCodeBase(), getClassLoaderCacheKey());
  1113. }
  1114. }
  1115. /**
  1116. * Get an applet parameter.
  1117. */
  1118. public String getParameter(String name) {
  1119. name = name.toLowerCase(java.util.Locale.ENGLISH);
  1120. synchronized(atts)
  1121. {
  1122. String value = (String) atts.get(name);
  1123. if (value != null)
  1124. value = trimWhiteSpaces(value);
  1125. return value;
  1126. }
  1127. }
  1128. /**
  1129. * Set an applet parameter.
  1130. */
  1131. public void setParameter(String name, Object value) {
  1132. name = name.toLowerCase(java.util.Locale.ENGLISH);
  1133. synchronized(atts)
  1134. {
  1135. atts.put(name, trimWhiteSpaces(value.toString()));
  1136. }
  1137. }
  1138. /**
  1139. * Trim whitespaces
  1140. */
  1141. private String trimWhiteSpaces(String str)
  1142. {
  1143. if (str == null)
  1144. return str;
  1145. StringBuffer buffer = new StringBuffer();
  1146. for (int i=0; i < str.length(); i++)
  1147. {
  1148. char c = str.charAt(i);
  1149. // Skip over whitespaces
  1150. if (c == '\n' || c == '\f' || c == '\r' || c == '\t')
  1151. continue;
  1152. else
  1153. buffer.append(c);
  1154. }
  1155. // Trim whitespaces on both ends of the strings
  1156. return buffer.toString().trim();
  1157. }
  1158. private boolean docbaseInit = false;
  1159. private Object docBaseSyncObj = new Object();
  1160. /**
  1161. * Get the document url.
  1162. */
  1163. public void setDocumentBase(String url)
  1164. {
  1165. if (docbaseInit == false)
  1166. {
  1167. // Canonicalize URL if necessary
  1168. String urlString = URLUtil.canonicalize(url);
  1169. // delay constructing the URL -
  1170. // URL constructed later in geDocumentBase
  1171. documentURLString = canonicalizeDocumentURL(urlString);
  1172. docbaseInit = true;
  1173. // Notify all the pending getDocumentBase() calls
  1174. synchronized(docBaseSyncObj)
  1175. {
  1176. docBaseSyncObj.notifyAll();
  1177. }
  1178. }
  1179. }
  1180. /**
  1181. * Canonicalize URL.
  1182. */
  1183. public String canonicalizeDocumentURL(String url) {
  1184. int fromIndex=-1,lastIndex;
  1185. // Strip off "#" and "?" from URL
  1186. int fragmentIndex = url.indexOf('#');
  1187. int queryIndex = url.indexOf('?');
  1188. if(queryIndex != -1 && fragmentIndex != -1)
  1189. {
  1190. fromIndex = Math.min(fragmentIndex, queryIndex);
  1191. }
  1192. else if(fragmentIndex != -1)
  1193. {
  1194. fromIndex = fragmentIndex;
  1195. }
  1196. else if(queryIndex != -1)
  1197. {
  1198. fromIndex = queryIndex;
  1199. }
  1200. // Strip off the end of the URL
  1201. String strippedURL;
  1202. if (fromIndex == -1)
  1203. strippedURL = url;
  1204. else
  1205. strippedURL = url.substring(0, fromIndex);
  1206. // Replace "|" character with ":"
  1207. StringBuffer urlBuffer = new StringBuffer(strippedURL);
  1208. int index = urlBuffer.toString().indexOf("|");
  1209. if (index >= 0)
  1210. {
  1211. urlBuffer.setCharAt(index, ':');
  1212. }
  1213. if (fromIndex != -1)
  1214. urlBuffer.append(url.substring(fromIndex));
  1215. return urlBuffer.toString();
  1216. }
  1217. /**
  1218. * Get the doc…

Large files files are truncated, but you can click here to view the full file