/** * 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; }
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); } }
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(); }