/**
  * Reads all available data from the input stream of <code>conn</code> and returns it as byte
  * array. If no input data is available the method returns <code>null</code>.
  *
  * @param conn
  * @return
  * @throws IOException
  */
 protected static byte[] loadBodyDataInBuffer(HttpURLConnection conn) throws IOException {
   InputStream input = conn.getInputStream();
   byte[] data = null;
   try {
     if (Thread.currentThread() instanceof MapSourceListener) {
       // We only throttle atlas downloads, not downloads for the preview map
       long bandwidthLimit = Settings.getInstance().getBandwidthLimit();
       if (bandwidthLimit > 0) {
         input = new ThrottledInputStream(input);
       }
     }
     data = Utilities.getInputBytes(input);
   } catch (IOException e) {
     InputStream errorIn = conn.getErrorStream();
     try {
       byte[] errData = Utilities.getInputBytes(errorIn);
       log.trace(
           "Retrieved " + errData.length + " error bytes for a HTTP " + conn.getResponseCode());
     } catch (Exception ee) {
       log.debug("Error retrieving error stream content: " + e);
     } finally {
       Utilities.closeStream(errorIn);
     }
     throw e;
   } finally {
     Utilities.closeStream(input);
   }
   log.trace("Retrieved " + data.length + " bytes for a HTTP " + conn.getResponseCode());
   if (data.length == 0) return null;
   return data;
 }
  public static void load() {
    File mapSourcesDir = Settings.getInstance().getMapSourcesDirectory();
    File mapSourcesProperties = new File(mapSourcesDir, FILENAME);
    if (!mapSourcesProperties.isFile()) return;
    FileInputStream in = null;
    try {
      in = new FileInputStream(mapSourcesProperties);
      PROPERTIES.load(in);
    } catch (IOException e) {
      log.error("Failed to load mapsources.properties", e);
    } finally {
      Utilities.closeStream(in);
    }
    if (!SHUTDOWN_HOOK_REGISTERED) {
      Runtime.getRuntime()
          .addShutdownHook(
              new Thread() {

                @Override
                public void run() {
                  save();
                }
              });
    }
  }
  /**
   * @param updateStoreName name of the tile store to update or <code>null</code> in case of all
   *     tile stores to be updated
   */
  private void updateTileStoreInfoPanel(String updateStoreName) {
    try {
      TileStore tileStore = TileStore.getInstance();

      long totalTileCount = 0;
      long totalTileSize = 0;
      for (final TileSourceInfoComponents info : tileStoreInfoList) {
        String storeName = info.name;
        Utilities.checkForInterruption();
        int count;
        long size;
        if (updateStoreName == null || info.name.equals(updateStoreName)) {
          TileStoreInfo tsi = tileStore.getStoreInfo(storeName);
          count = tsi.getTileCount();
          size = tsi.getStoreSize();
          info.count = count;
          info.size = size;
          final String mapTileCountText = (count < 0) ? "??" : Integer.toString(count);
          final String mapTileSizeText = Utilities.formatBytes(size);
          SwingUtilities.invokeLater(
              new Runnable() {
                public void run() {
                  info.countLabel.setText("<html><b>" + mapTileCountText + "</b></html>");
                  info.sizeLabel.setText("<html><b>" + mapTileSizeText + "</b></html>");
                }
              });
        } else {
          count = info.count;
          size = info.size;
        }
        totalTileCount += count;
        totalTileSize += size;
      }
      final String totalTileCountText = "<html><b>" + Long.toString(totalTileCount) + "</b></html>";
      final String totalTileSizeText =
          "<html><b>" + Utilities.formatBytes(totalTileSize) + "</b></html>";
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              totalTileCountLabel.setText(totalTileCountText);
              totalTileSizeLabel.setText(totalTileSizeText);
            }
          });
    } catch (InterruptedException e) {
      SettingsGUI.log.debug("Tile store information retrieval was canceled");
    }
  }
  private void prepareTileStoreInfoPanel() {

    final GridBagConstraints gbc_mapSource = new GridBagConstraints();
    gbc_mapSource.insets = new Insets(5, 10, 5, 10);
    gbc_mapSource.anchor = GridBagConstraints.WEST;
    final GridBagConstraints gbc_mapTiles = new GridBagConstraints();
    gbc_mapTiles.insets = gbc_mapSource.insets;
    gbc_mapTiles.anchor = GridBagConstraints.EAST;
    final GridBagConstraints gbc_eol = new GridBagConstraints();
    gbc_eol.gridwidth = GridBagConstraints.REMAINDER;

    TileStore tileStore = TileStore.getInstance();
    MapSourcesManager mapSourcesManager = MapSourcesManager.getInstance();

    tileStoreInfoPanel.add(new JLabel("<html><b>Map source</b></html>"), gbc_mapSource);
    tileStoreInfoPanel.add(new JLabel("<html><b>Tiles</b></html>"), gbc_mapTiles);
    tileStoreInfoPanel.add(new JLabel("<html><b>Size</b></html>"), gbc_eol);

    ImageIcon trash = Utilities.loadResourceImageIcon("trash.png");

    for (String name : tileStore.getAllStoreNames()) {
      String mapTileCountText = "  ?  ";
      String mapTileSizeText = "    ?    ";
      MapSource mapSource = mapSourcesManager.getSourceByName(name);
      final JLabel mapSourceNameLabel;
      if (mapSource != null) mapSourceNameLabel = new JLabel(name);
      else mapSourceNameLabel = new JLabel(name + " (unused)");
      final JLabel mapTileCountLabel = new JLabel(mapTileCountText);
      final JLabel mapTileSizeLabel = new JLabel(mapTileSizeText);
      final JButton deleteButton = new JButton(trash);
      TileSourceInfoComponents info = new TileSourceInfoComponents();
      info.name = name;
      info.countLabel = mapTileCountLabel;
      info.sizeLabel = mapTileSizeLabel;
      tileStoreInfoList.add(info);
      deleteButton.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
      deleteButton.setToolTipText("Delete all stored " + name + " tiles.");
      deleteButton.addActionListener(new ClearTileCacheAction(name));

      tileStoreInfoPanel.add(mapSourceNameLabel, gbc_mapSource);
      tileStoreInfoPanel.add(mapTileCountLabel, gbc_mapTiles);
      tileStoreInfoPanel.add(mapTileSizeLabel, gbc_mapTiles);
      tileStoreInfoPanel.add(deleteButton, gbc_eol);
    }
    JSeparator hr = new JSeparator(JSeparator.HORIZONTAL);
    hr.setBorder(BorderFactory.createEtchedBorder(BevelBorder.LOWERED));
    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridwidth = GridBagConstraints.REMAINDER;
    gbc.fill = GridBagConstraints.HORIZONTAL;
    tileStoreInfoPanel.add(hr, gbc);

    JLabel totalMapLabel = new JLabel("<html><b>Total</b></html>");
    totalTileCountLabel = new JLabel("<html><b>??</b></html>");
    totalTileSizeLabel = new JLabel("<html><b>??</b></html>");
    tileStoreInfoPanel.add(totalMapLabel, gbc_mapSource);
    tileStoreInfoPanel.add(totalTileCountLabel, gbc_mapTiles);
    tileStoreInfoPanel.add(totalTileSizeLabel, gbc_mapTiles);
  }
  public static byte[] downloadTileAndUpdateStore(
      int x, int y, int zoom, HttpMapSource mapSource, boolean useTileStore)
      throws UnrecoverableDownloadException, IOException, InterruptedException {

    if (zoom < 0) throw new UnrecoverableDownloadException("Negative zoom!");
    HttpURLConnection conn = mapSource.getTileUrlConnection(zoom, x, y);
    if (conn == null)
      throw new UnrecoverableDownloadException(
          "Tile x="
              + x
              + " y="
              + y
              + " zoom="
              + zoom
              + " is not a valid tile in map source "
              + mapSource);

    log.trace("Downloading " + conn.getURL());

    prepareConnection(conn);
    conn.connect();

    int code = conn.getResponseCode();
    byte[] data = loadBodyDataInBuffer(conn);

    if (code != HttpURLConnection.HTTP_OK) throw new DownloadFailedException(conn, code);

    checkContentType(conn, data);
    checkContentLength(conn, data);

    String eTag = conn.getHeaderField("ETag");
    long timeLastModified = conn.getLastModified();
    long timeExpires = conn.getExpiration();

    Utilities.checkForInterruption();
    TileImageType imageType = Utilities.getImageType(data);
    if (imageType == null)
      throw new UnrecoverableDownloadException("The returned image is of unknown format");
    if (useTileStore) {
      TileStore.getInstance()
          .putTileData(data, x, y, zoom, mapSource, timeLastModified, timeExpires, eTag);
    }
    Utilities.checkForInterruption();
    return data;
  }
Beispiel #6
0
  public String getToolTip() {
    StringWriter sw = new StringWriter(1024);
    sw.write("<html>");
    sw.write("<b>Layer</b><br>");
    sw.write("Map count: " + maps.size() + "<br>");
    sw.write("Maximum tiles to download: " + calculateTilesToDownload() + "<br>");
    sw.write(
        String.format(
            "Area start: %s %s<br>",
            Utilities.prettyPrintLatLon(getMaxLat(), true),
            Utilities.prettyPrintLatLon(getMinLon(), false)));
    sw.write(
        String.format(
            "Area end: %s %s<br>",
            Utilities.prettyPrintLatLon(getMinLat(), true),
            Utilities.prettyPrintLatLon(getMaxLon(), false)));

    sw.write("</html>");
    return sw.toString();
  }
 public static void save() {
   if (PROPERTIES.size() == 0) return;
   File mapSourcesDir = Settings.getInstance().getMapSourcesDirectory();
   File mapSourcesProperties = new File(mapSourcesDir, FILENAME);
   FileOutputStream out = null;
   try {
     out = new FileOutputStream(mapSourcesProperties);
     PROPERTIES.store(out, "");
   } catch (IOException e) {
     log.error("", e);
   } finally {
     Utilities.closeStream(out);
   }
 }
Beispiel #8
0
  public JProfilesPanel(JAtlasTree atlasTree) {
    super(I18nUtils.localizedStringForKey("lp_atlas_profile_title"), new GridBagLayout());

    if (atlasTree == null) throw new NullPointerException();

    // profiles combo box
    profilesCombo = new JProfilesComboBox();
    profilesCombo.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_combo_tips"));
    profilesCombo.addActionListener(new ProfileListListener());

    // delete profile button
    deleteButton =
        new JButton(I18nUtils.localizedStringForKey("lp_atlas_profile_delete_btn_title"));
    deleteButton.addActionListener(new DeleteProfileListener());
    deleteButton.setToolTipText(
        I18nUtils.localizedStringForKey("lp_atlas_profile_delete_btn_tips"));

    // save as profile button
    saveAsButton = new JButton(I18nUtils.localizedStringForKey("lp_atlas_profile_save_btn_title"));
    saveAsButton.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_save_btn_tips"));
    saveAsButton.addActionListener(new SaveAsProfileListener(atlasTree));

    loadButton = new JButton(I18nUtils.localizedStringForKey("lp_atlas_profile_load_btn_title"));
    loadButton.setToolTipText(I18nUtils.localizedStringForKey("lp_atlas_profile_load_btn_tips"));

    GBC gbc = GBC.eol().fill().insets(5, 5, 5, 5);
    reloadButton = new JButton(Utilities.loadResourceImageIcon("refresh.png"));
    reloadButton.setToolTipText(
        I18nUtils.localizedStringForKey("lp_atlas_profile_refresh_btn_tips"));
    reloadButton.addActionListener(new ReloadListener());
    reloadButton.setPreferredSize(new Dimension(24, 0));

    JPanel p = new JPanel(new BorderLayout());
    p.add(profilesCombo, BorderLayout.CENTER);
    p.add(reloadButton, BorderLayout.EAST);

    contentContainer.add(p, gbc);
    contentContainer.add(deleteButton, gbc.toggleEol());
    contentContainer.add(saveAsButton, gbc);
    contentContainer.add(loadButton, gbc.toggleEol());

    saveAsButton.setEnabled(false);
    deleteButton.setEnabled(false);
    loadButton.setEnabled(false);
  }
  public static byte[] updateStoredTile(TileStoreEntry tile, HttpMapSource mapSource)
      throws UnrecoverableDownloadException, IOException, InterruptedException {
    final int x = tile.getX();
    final int y = tile.getY();
    final int zoom = tile.getZoom();
    final HttpMapSource.TileUpdate tileUpdate = mapSource.getTileUpdate();

    switch (tileUpdate) {
      case ETag:
        {
          boolean unchanged = hasTileETag(tile, mapSource);
          if (unchanged) {
            if (log.isTraceEnabled())
              log.trace("Data unchanged on server (eTag): " + mapSource + " " + tile);
            return null;
          }
          break;
        }
      case LastModified:
        {
          boolean isNewer = isTileNewer(tile, mapSource);
          if (!isNewer) {
            if (log.isTraceEnabled())
              log.trace("Data unchanged on server (LastModified): " + mapSource + " " + tile);
            return null;
          }
          break;
        }
    }
    HttpURLConnection conn = mapSource.getTileUrlConnection(zoom, x, y);
    if (conn == null)
      throw new UnrecoverableDownloadException(
          "Tile x="
              + x
              + " y="
              + y
              + " zoom="
              + zoom
              + " is not a valid tile in map source "
              + mapSource);

    if (log.isTraceEnabled()) log.trace(String.format("Checking %s %s", mapSource.getName(), tile));

    prepareConnection(conn);

    boolean conditionalRequest = false;

    switch (tileUpdate) {
      case IfNoneMatch:
        {
          if (tile.geteTag() != null) {
            conn.setRequestProperty("If-None-Match", tile.geteTag());
            conditionalRequest = true;
          }
          break;
        }
      case IfModifiedSince:
        {
          if (tile.getTimeLastModified() > 0) {
            conn.setIfModifiedSince(tile.getTimeLastModified());
            conditionalRequest = true;
          }
          break;
        }
    }

    conn.connect();

    Settings s = Settings.getInstance();

    int code = conn.getResponseCode();

    if (conditionalRequest && code == HttpURLConnection.HTTP_NOT_MODIFIED) {
      // Data unchanged on server
      if (s.tileStoreEnabled) {
        tile.update(conn.getExpiration());
        TileStore.getInstance().putTile(tile, mapSource);
      }
      if (log.isTraceEnabled()) log.trace("Data unchanged on server: " + mapSource + " " + tile);
      return null;
    }
    byte[] data = loadBodyDataInBuffer(conn);

    if (code != HttpURLConnection.HTTP_OK) throw new DownloadFailedException(conn, code);

    checkContentType(conn, data);
    checkContentLength(conn, data);

    String eTag = conn.getHeaderField("ETag");
    long timeLastModified = conn.getLastModified();
    long timeExpires = conn.getExpiration();

    Utilities.checkForInterruption();
    TileImageType imageType = Utilities.getImageType(data);
    if (imageType == null)
      throw new UnrecoverableDownloadException("The returned image is of unknown format");
    if (s.tileStoreEnabled) {
      TileStore.getInstance()
          .putTileData(data, x, y, zoom, mapSource, timeLastModified, timeExpires, eTag);
    }
    Utilities.checkForInterruption();
    return data;
  }
    public void run() {
      synchronized (this) {
        scheduledCounter--;
      }

      if (data.currentMap != null) {
        String text =
            "<html>Processing map <b>"
                + data.currentMap.getName()
                + "</b> "
                + "of layer <b>"
                + data.currentMap.getLayer().getName()
                + "</b> "
                + "from map source <b>"
                + data.currentMap.getMapSource()
                + "</b></html>";
        mapInfoLabel.setText(text);
      }

      // atlas progress
      atlasProgressBar.setMaximum(data.totalNumberOfTiles);
      atlasProgressBar.setValue(data.totalProgress);

      try {
        String statusText = "RUNNING";
        if (aborted) statusText = "ABORTED";
        else if (finished) statusText = "FINISHED";
        else if (downloadController == null) {
          statusText = "UNKNOWN";
        } else {
          boolean pauseState = downloadController.isPaused();
          if (pauseState) statusText = "PAUSED";
          else statusText = "RUNNING";
        }
        statusLabel.setText("Status: " + statusText);

        atlasPercent.setText(
            String.format(TEXT_TENTHPERCENT, data.totalProgressTenthPercent / 10.0));
        if (data.atlas != null) {
          String text =
              String.format(
                  TEXT_PERCENT + " - processing atlas \"%s\" of type %s",
                  data.totalProgressTenthPercent / 10,
                  data.atlas.getName(),
                  data.atlas.getOutputFormat());
          if (downloadController != null && downloadController.isPaused()) text += " [PAUSED]";
          AtlasProgressFrame.this.setTitle(text);
        }
      } catch (NullPointerException e) {
      }

      long seconds = -1;
      int totalProgress = data.totalProgress;
      if (totalProgress != 0) {
        // Avoid for a possible division by zero
        int totalTilesRemaining = data.totalNumberOfTiles - totalProgress;
        long totalElapsedTime = System.currentTimeMillis() - initialTotalTime;
        seconds = (totalElapsedTime * totalTilesRemaining / (1000L * totalProgress));
      }
      atlasTimeLeft.setText("Time remaining: " + formatTime(seconds));

      // layer progress
      mapDownloadProgressBar.setMaximum(data.mapDownloadNumberOfTiles);
      mapDownloadProgressBar.setValue(data.mapDownloadProgress);

      mapDownloadPercent.setText(
          String.format(TEXT_PERCENT, (int) (mapDownloadProgressBar.getPercentComplete() * 100)));

      mapDownloadElementsDone.setText(
          Integer.toString(data.mapDownloadProgress)
              + " of "
              + data.mapDownloadNumberOfTiles
              + " tiles done");

      seconds = -1;
      int mapDlProgress = data.mapDownloadProgress;
      if (mapDlProgress != 0 && initialMapDownloadTime > 0)
        seconds =
            ((System.currentTimeMillis() - initialMapDownloadTime)
                * (data.mapDownloadNumberOfTiles - mapDlProgress)
                / (1000L * mapDlProgress));
      mapDownloadTimeLeft.setText("Time remaining: " + formatTime(seconds));

      // map progress
      mapCreation.setText("Map creation");
      mapCreationProgressBar.setValue(data.mapCreationProgress);
      mapCreationProgressBar.setMaximum(data.mapCreationMax);
      atlasMapsDone.setText(
          (data.currentMapNumber - 1) + " of " + data.totalNumberOfMaps + " done");

      // bytes per second
      long rate = data.numberOfDownloadedBytes * 1000;
      long time = System.currentTimeMillis() - initialMapDownloadTime;
      if (data.mapCreationProgress == 0 && initialMapDownloadTime > 0) {
        if (time == 0) {
          nrOfDownloadedBytesPerSecondValue.setText(": ?? KiByte / second");
        } else {
          rate = rate / time;
          nrOfDownloadedBytesPerSecondValue.setText(
              ": " + Utilities.formatBytes(rate) + " / second");
        }
      }

      // downloaded bytes
      nrOfDownloadedBytesValue.setText(": " + Utilities.formatBytes(data.numberOfDownloadedBytes));
      nrOfCacheBytesValue.setText(": " + Utilities.formatBytes(data.numberOfBytesLoadedFromCache));

      // total creation time
      long totalSeconds = (System.currentTimeMillis() - initialTotalTime) / 1000;
      totalDownloadTimeValue.setText(": " + formatTime(totalSeconds));
      totalDownloadTimeValue.repaint();

      // active downloads
      int activeDownloads =
          (downloadController == null) ? 0 : downloadController.countActiveDownloads();
      activeDownloadsValue.setText(": " + activeDownloads);
      activeDownloadsValue.repaint();

      // TODO fix this
      retryableDownloadErrorsValue.setText(
          ": current map: " + data.currentMapRetryErrors + ", total: " + data.totalRetryErrors);
      permanentDownloadErrorsValue.setText(
          ": current map: "
              + data.currentMapPermanentErrors
              + ", total: "
              + data.totalPermanentErrors);
      retryableDownloadErrorsValue.repaint();
      permanentDownloadErrorsValue.repaint();
    }