gt:         HttpURLConnection hc = (HttpURLConnection)c;
context: /*
   * File    : FileSystem.java
   * Created : 20-jun-2000 9:45
   * By      : fbusquets
   *
   * JClic - Authoring and playing system for educational activities
   *
   * Copyright (C) 2000 - 2018 Francesc Busquets & Departament
   * d'Educacio de la Generalitat de Catalunya
   *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation; either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   * GNU General Public License for more details (see the LICENSE file).
   */
  package edu.xtec.jclic.fileSystem;
  
  import edu.xtec.jclic.misc.Utils;
  import edu.xtec.util.*;
  import java.awt.Component;
  import java.awt.Image;
  import java.awt.Toolkit;
  import java.io.*;
  import java.net.*;
  import java.util.Enumeration;
  import java.util.List;
  import java.util.zip.ZipEntry;
  import java.util.zip.ZipFile;
  import javax.swing.JFileChooser;
  
  /**
   * Base class for Clic filesystems.
   *
   * @author Francesc Busquets (fbusquets@xtec.cat)
   * @version 13.09.10
   */
  public class FileSystem extends Object {
  
    public static final String FS = "/", WINFS = "\\";
    public static final char FSCH = '/', WINFSCH = '\\';
    protected static FileChooserForFiles fileChooser;
    private static final String FS_BAK = FS + "..";
    public static java.util.HashMap<String, String> altFileNames = new java.util.HashMap<String, String>();
  
    public String root;
    protected boolean isURL = false;
    protected Boolean ISURL = isURL;
    protected ResourceBridge rb = null;
  
    public FileSystem(ResourceBridge rb) {
      root = "";
      this.rb = rb;
    }
  
    public FileSystem(String rootPath, ResourceBridge rb) {
      root = stdFn(rootPath);
      this.rb = rb;
      if (root == null) {
        root = "";
      }
      if (root.length() > 0) {
        if (isStrUrl(root)) {
          isURL = true;
          ISURL = isURL;
          if (!root.endsWith(FS)) {
            root = root + FS;
          }
          root = getCanonicalNameOf(root);
        } else {
          File f = new File(sysFn(root));
          String saveRoot = root;
          try {
            root = stdFn(f.getCanonicalPath());
          } catch (Exception e) {
            root = saveRoot;
          }
          if (!root.endsWith(FS)) {
            root = root + FS;
          }
        }
      }
    }
  
    public FileSystem duplicate() throws Exception {
      return createFileSystem(root, rb);
    }
  
    protected void changeBase(String newRoot, String newFileName) throws Exception {
      File f = new File(sysFn(newRoot));
      String saveRoot = root;
      try {
        root = stdFn(f.getCanonicalPath());
      } catch (Exception e) {
        root = saveRoot;
      }
      if (!root.endsWith(FS)) {
        root = root + FS;
      }
    }
  
    public static String stdFn(String s) {
      return s == null ? s : s.replace(WINFSCH, FSCH);
    }
  
    public static String sysFn(String s) {
      String result = s;
      if (result != null) {
        result = stdFn(result).replace(FSCH, File.separatorChar);
        if (result.indexOf("%20") >= 0) {
          result = StrUtils.replace(result, "%20", " ");
        }
      }
      return result;
    }
  
    public static FileSystem createFileSystem(String rootPath, String fileName, ResourceBridge rb) throws Exception {
      if (fileName == null) {
        return new FileSystem(rootPath, rb);
      } else if (fileName.endsWith(".pcc")) {
        return PCCFileSystem.createPCCFileSystem(rootPath, fileName, rb);
      } else if (fileName.endsWith(".zip")) {
        return ZipFileSystem.createZipFileSystem(rootPath, fileName, rb);
      } else {
        throw new Exception("unknown format " + fileName);
      }
    }
  
    public static FileSystem createFileSystem(String fullPath, ResourceBridge rb) throws Exception {
      fullPath = getCanonicalNameOf(fullPath, null);
      String fileName = null;
      String rootPath = getPathPartOf(fullPath);
      if (fullPath.endsWith(".pcc") || fullPath.endsWith(".zip")) {
        fileName = getFileNameOf(fullPath);
      }
      return createFileSystem(rootPath, fileName, rb);
    }
  
    public String getFullFileNamePath(String fName) {
      if (fName == null || fName.length() == 0) {
        return root.length() > 0 ? root.substring(0, root.length() - 1) : root;
      }
      String result = getCanonicalNameOf(fName);
      if (!isURL) {
        File f = new File(sysFn(result));
        if (!f.isAbsolute()) {
          result = getCanonicalNameOf(root + result);
        }
      } else {
        if (!isStrUrl(result)) {
          result = getCanonicalNameOf(root + result);
        }
      }
      return result;
    }
  
    public String getRelativeFileNamePath(String fName) {
      String s = stdFn(fName);
      if (s == null || s.length() < root.length() || !s.substring(0, root.length()).equalsIgnoreCase(root)) {
        return s;
      } else {
        return s.substring(root.length());
      }
    }
  
    public String getFullRoot() {
      return root;
    }
  
    public boolean isUrlBased() {
      return isURL;
    }
  
    public static boolean isStrUrl(String s) {
      return s != null
              && (s.startsWith("http:") || s.startsWith("https:") || s.startsWith("ftp:") || s.startsWith("mailto:"));
    }
  
    public String getUrl(String fileName) {
      String s = stdFn(fileName);
      if (s == null || isStrUrl(s) || s.startsWith("file:")) {
        return s;
      }
  
      if (!(s.charAt(1) == ':') && !s.startsWith(FS)) {
        s = getFullFileNamePath(s);
      }
  
      if (isURL) {
        return getCanonicalNameOf(s, ISURL);
      } else {
        return "file://" + sysFn(getCanonicalNameOf(s, ISURL));
      }
    }
  
    public String getCanonicalNameOf(String fileName) {
      return getCanonicalNameOf(fileName, ISURL);
    }
  
    public static String getCanonicalNameOf(String fileName, Boolean isUrl) {
  
      String fn = stdFn(fileName);
      boolean flagUrl = (isUrl != null ? isUrl.booleanValue() : isStrUrl(fn));
  
      String prefix = "";
      int cut = -1;
  
      if (fn.startsWith("file:")) {
        fn = fn.substring(5);
      }
  
      if (isStrUrl(fn)) {
        int k = fn.indexOf('@');
        if (k < 0) {
          k = 7;
        }
        cut = fn.indexOf(FSCH, k);
      } else if (fn.length() > 2 && fn.charAt(1) == ':') {
        cut = (fn.charAt(2) == FSCH ? 2 : 1);
      } else if (fn.startsWith("//")) {
        int i = fn.indexOf(FSCH, 2);
        cut = fn.indexOf(FSCH, i + 1);
      } else if (fn.startsWith(FS)) {
        cut = 0;
      }
  
      if (cut >= 0) {
        prefix = fn.substring(0, cut + 1);
        fn = fn.substring(cut + 1);
      }
  
      // intercept '\...'
      int r;
      while ((r = fn.indexOf(FS_BAK)) >= 0) {
        int p;
        for (p = r - 1; p >= 0; p--) {
          if (fn.charAt(p) == FSCH) {
            break;
          }
        }
        StringBuilder newfn = new StringBuilder();
        if (p >= 0) {
          newfn.append(fn.substring(0, p + 1));
        }
        if (r + 4 < fn.length()) {
          newfn.append(fn.substring(r + 4));
        }
        fn = newfn.substring(0);
      }
  
      return prefix + fn;
    }
  
    public static String getPathPartOf(String fullPath) {
      String s = stdFn(fullPath);
      int i = s.lastIndexOf(FS);
      return i < 0 ? "" : s.substring(0, i + 1);
    }
  
    public static String getFileNameOf(String fullPath) {
      String s = stdFn(fullPath);
      int i = s.lastIndexOf(FS);
      return i < 0 ? s : s.substring(i + 1);
    }
  
    public byte[] getBytes(String fileName) throws IOException {
      return StreamIO.readInputStream(getInputStream(fileName));
    }
  
    public Image getImageFile(String fName) throws Exception {
      return Toolkit.getDefaultToolkit().createImage(getBytes(fName));
    }
  
    public long getFileLength(String fName) throws IOException {
      long length;
      if (isURL) {
        // Updated 04-Aug-2014 to solve GitHub issue #5
        // https://github.com/projectestac/jclic/issues/5
        URL url = new URL(getFullFileNamePath(fName).replace(" ", "%20"));
        URLConnection c = url.openConnection();
        length = c.getContentLength();
      } else {
        File f = new File(sysFn(getFullFileNamePath(fName)));
        length = f.length();
      }
      return length;
    }
  
    public boolean fileExists(String fName) {
      boolean result;
      try {
        if (isURL) {
          // Updated 04-Aug-2014 to solve GitHub issue #5
          // https://github.com/projectestac/jclic/issues/5
          URL url = new URL(getFullFileNamePath(fName).replace(" ", "%20"));
          URLConnection c = url.openConnection();
          result = (c.getContentLength() > 0);
        } else {
          File f = new File(sysFn(getFullFileNamePath(fName)));
          result = f.exists();
        }
      } catch (Exception ex) {
        // eat exception
        result = false;
      }
      return result;
    }
  
    public boolean realFileExists(String fName) {
      return fileExists(fName);
    }
  
    public InputStream getInputStream(String fName) throws IOException {
      InputStream result;
      int length;
      if (isURL) {
        // Updated 04-Aug-2014 to solve GitHub issue #5
        // https://github.com/projectestac/jclic/issues/5
        URL url = new URL(getFullFileNamePath(fName).replace(" ", "%20"));
        URLConnection c = url.openConnection();
        if(c instanceof HttpURLConnection) {
  