Package com.intellij.ide

Source Code of com.intellij.ide.BrowserUtil

/*
* Copyright 2000-2007 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide;

import com.intellij.CommonBundle;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.vfs.VfsUtil;
import org.jetbrains.annotations.NonNls;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.URL;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class BrowserUtil {

  // The pattern for 'scheme' mainly according to RFC1738.
  // We have to violate the RFC since we need to distinguish
  // real schemes from local Windows paths; The only difference
  // with RFC is that we do not allow schemes with length=1 (in other case
  // local paths like "C:/temp/index.html" whould be erroneously interpreted as
  // external URLs.)
  @NonNls private static Pattern ourExternalPrefix = Pattern.compile("^[\\w\\+\\.\\-]{2,}:");
  private static Pattern ourAnchorsuffix = Pattern.compile("#(.*)$");

  private BrowserUtil() {
  }

  public static boolean isAbsoluteURL(String url) {
    return ourExternalPrefix.matcher(url.toLowerCase()).find();
  }

  public static String getDocURL(String url) {
    Matcher anchorMatcher = ourAnchorsuffix.matcher(url);

    if (anchorMatcher.find()) {
      return anchorMatcher.reset().replaceAll("");
    }

    return url;
  }

  public static URL getURL(String url) throws java.net.MalformedURLException {
    if (!isAbsoluteURL(url)) {
      return new URL("file", "", url);
    }

    return VfsUtil.convertToURL(url);
  }

  private static void launchBrowser(final String url, String[] command) {
    try {
      URL curl = BrowserUtil.getURL(url);

      if (curl != null) {
        final String urlString = curl.toString();
        String[] commandLine;
        if (SystemInfo.isWindows && isUseDefaultBrowser()) {
          commandLine = new String[command.length + 2];
          System.arraycopy(command, 0, commandLine, 0, command.length);
          commandLine[commandLine.length - 2] = "\"\"";
          commandLine[commandLine.length - 1] = "\"" + redirectUrl(url, urlString) + "\"";
        }
        else {
          commandLine = new String[command.length + 1];
          System.arraycopy(command, 0, commandLine, 0, command.length);
          if (SystemInfo.isWindows) {
            commandLine[commandLine.length - 1] = "\"" + urlString + "\"";
          }
          else {
            commandLine[commandLine.length - 1] = urlString.replaceAll(" ", "%20");
          }
        }
        Runtime.getRuntime().exec(commandLine);
      }
      else {
        showErrorMessage(IdeBundle.message("error.malformed.url", url), CommonBundle.getErrorTitle());
      }
    }
    catch (final IOException e) {
      showErrorMessage(IdeBundle.message("error.cannot.start.browser", e.getMessage()),
                       CommonBundle.getErrorTitle());
    }
  }

  /**
   * This method works around Windows 'start' command behaivor of dropping anchors from the url for local urls.
   */
  private static String redirectUrl(String url, @NonNls String urlString) throws IOException {
    if (url.indexOf('&') == -1 && (!urlString.startsWith("file:") || urlString.indexOf("#") == -1)) return urlString;

    File redirect = File.createTempFile("redirect", ".html");
    redirect.deleteOnExit();
    FileWriter writer = new FileWriter(redirect);
    writer.write("<html><head></head><body><script type=\"text/javascript\">window.location=\"" + url + "\";</script></body></html>");
    writer.close();
    return VfsUtil.pathToUrl(redirect.getAbsolutePath());
  }

  private static boolean isUseDefaultBrowser() {
    Application application = ApplicationManager.getApplication();
    if (application == null) {
      return true;
    }
    else {
      return GeneralSettings.getInstance().isUseDefaultBrowser();
    }
  }

  private static void showErrorMessage(final String message, final String title) {
    final Application app = ApplicationManager.getApplication();
    if (app == null) {
      return; // Not started yet. Not able to show message up. (Could happen in License panel under Linux).
    }

    Runnable runnable = new Runnable() {
      public void run() {
        Messages.showMessageDialog(message,
                                   title,
                                   Messages.getErrorIcon());
      }
    };

    if (app.isDispatchThread()) {
      runnable.run();
    }
    else {
      app.invokeLater(runnable, ModalityState.NON_MODAL);
    }
  }

  private static void launchBrowserUsingStandardWay(final String url) {
    String[] command;
    try {
      String browserPath = GeneralSettings.getInstance().getBrowserPath();
      if (browserPath == null || browserPath.trim().length() == 0) {
        showErrorMessage(IdeBundle.message("error.please.specify.path.to.web.browser"),
                         IdeBundle.message("title.browser.not.found"));
        return;
      }

      command = new String[]{browserPath};
    }
    catch (NullPointerException e) {
      // todo: fix the possible problem on startup, see SCR #35066
      command = getDefaultBrowserCommand(null);
      if (command == null) {
        showErrorMessage(IdeBundle.message("error.please.open.url.manually", url, ApplicationNamesInfo.getInstance().getProductName()),
                         IdeBundle.message("title.browser.path.not.found"));
        return;
      }

    }
    // We do not need to check browserPath under Win32

    launchBrowser(url, command);
  }


  public static void launchBrowser(final String url, String name) {
    //noinspection HardCodedStringLiteral
    if (url.startsWith("jar:")) {
      showErrorMessage(IdeBundle.message("error.cannot.show.in.external.browser", url),
                       IdeBundle.message("title.cannot.start.browser"));
      return;
    }
    if (canStartDefaultBrowser() && isUseDefaultBrowser()) {
      launchBrowser(url, getDefaultBrowserCommand(name));
    }
    else {
      launchBrowserUsingStandardWay(url);
    }
  }

  public static void launchBrowser(@NonNls final String url) {
    launchBrowser(url, (String)null);
  }

  @NonNls private static String[] getDefaultBrowserCommand(String name) {
    if (SystemInfo.isWindows9x) {
      return new String[]{"command.com", "/c", "start"};
    }
    else if (SystemInfo.isWindows) {
      return new String[]{"cmd.exe", "/c", "start"};
    }
    else if (SystemInfo.isMac) {
      return new String[]{"open"};
    }
    else if (SystemInfo.isUnix) {
      return new String[]{"mozilla"};
    }
    else {
      return null;
    }

  }

  public static boolean canStartDefaultBrowser() {
    if (SystemInfo.isMac) {
      return true;
    }

    if (SystemInfo.isWindows) {
      return true;
    }

    return false;
  }
}
TOP

Related Classes of com.intellij.ide.BrowserUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.