- Timestamp:
- 2015-05-23T00:46:21+02:00 (10 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/data/maps.xsd
r8350 r8418 681 681 <!-- tile size provided by imagery source. Default - 256 --> 682 682 <xs:element name="tile-size" minOccurs="0" maxOccurs="1" type="xs:positiveInteger" /> 683 <!-- HTTP headers that contain valuable informatin and that will be shown on "Shown Tile Info" dialog --> 684 <xs:element name="metadata-header" minOccurs="0" maxOccurs="unbounded"> 685 <xs:complexType> 686 <xs:attribute name="header-name" type="xs:string" /> 687 <xs:attribute name="metadata-key" type="xs:string" /> 688 </xs:complexType> 689 </xs:element> 683 690 </xs:choice> 684 691 </xs:sequence> -
trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java
r8389 r8418 2 2 package org.openstreetmap.josm.data.cache; 3 3 4 import java.util.HashMap; 4 import java.util.Arrays; 5 import java.util.Collections; 6 import java.util.HashSet; 5 7 import java.util.Map; 8 import java.util.Map.Entry; 9 import java.util.Set; 10 import java.util.concurrent.ConcurrentHashMap; 6 11 7 12 import org.apache.commons.jcs.engine.ElementAttributes; 13 import org.openstreetmap.josm.Main; 8 14 9 15 /** … … 15 21 public class CacheEntryAttributes extends ElementAttributes { 16 22 private static final long serialVersionUID = 1L; //version 17 private final Map<String, String> attrs = new HashMap<String, String>();23 private final Map<String, String> attrs = new ConcurrentHashMap<String, String>(RESERVED_KEYS.size()); 18 24 private static final String NO_TILE_AT_ZOOM = "noTileAtZoom"; 19 25 private static final String ETAG = "Etag"; … … 21 27 private static final String EXPIRATION_TIME = "expirationTime"; 22 28 private static final String HTTP_RESPONSE_CODE = "httpResponceCode"; 29 // this contains all of the above 30 private static final Set<String> RESERVED_KEYS = new HashSet<>(Arrays.asList(new String[]{ 31 NO_TILE_AT_ZOOM, 32 ETAG, 33 LAST_MODIFICATION, 34 EXPIRATION_TIME, 35 HTTP_RESPONSE_CODE 36 })); 23 37 24 38 /** … … 28 42 super(); 29 43 attrs.put(NO_TILE_AT_ZOOM, "false"); 30 attrs.put(ETAG, null);31 44 attrs.put(LAST_MODIFICATION, "0"); 32 45 attrs.put(EXPIRATION_TIME, "0"); … … 44 57 } 45 58 public void setEtag(String etag) { 46 attrs.put(ETAG, etag); 59 if(etag != null) { 60 attrs.put(ETAG, etag); 61 } 47 62 } 48 63 … … 82 97 } 83 98 99 /** 100 * Sets the metadata about cache entry. As it stores all data together, with other attributes 101 * in common map, some keys might not be stored. 102 * 103 * @param map metadata to save 104 */ 105 public void setMetadata(Map<String, String> map) { 106 for (Entry<String, String> e: map.entrySet()) { 107 if (RESERVED_KEYS.contains(e.getKey())) { 108 Main.info("Metadata key configuration contains key {0} which is reserved for internal use"); 109 } else { 110 attrs.put(e.getKey(), e.getValue()); 111 } 112 } 113 } 114 115 /** 116 * Returns an unmodifiable Map containing all metadata. Unmodifiable prevents access to metadata within attributes. 117 * @return unmodifiable Map with cache element metadata 118 */ 119 public Map<String, String> getMetadata() { 120 return Collections.unmodifiableMap(attrs); 121 } 84 122 } -
trunk/src/org/openstreetmap/josm/data/cache/HostLimitQueue.java
r8403 r8418 30 30 31 31 public class HostLimitQueue extends LinkedBlockingDeque<Runnable> { 32 private static final long serialVersionUID = 1L; 32 33 33 private Map<String, Semaphore> hostSemaphores = new ConcurrentHashMap<>();34 private int hostLimit;34 private final Map<String, Semaphore> hostSemaphores = new ConcurrentHashMap<>(); 35 private final int hostLimit; 35 36 36 37 /** … … 91 92 92 93 private Semaphore getSemaphore(JCSCachedTileLoaderJob<?, ?> job) { 93 String host = ((JCSCachedTileLoaderJob<?, ?>)job).getUrl().getHost();94 String host = job.getUrl().getHost(); 94 95 Semaphore limit = hostSemaphores.get(host); 95 96 if (limit == null) { … … 112 113 limit.acquire(); 113 114 jcsJob.setFinishedTask(new Runnable() { 115 @Override 114 116 public void run() { 115 117 releaseSemaphore(jcsJob); … … 128 130 if (ret) { 129 131 job.setFinishedTask(new Runnable() { 132 @Override 130 133 public void run() { 131 134 releaseSemaphore(job); -
trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
r8404 r8418 198 198 /** icon used in menu */ 199 199 private String icon; 200 // when adding a field, also adapt the ImageryInfo(ImageryInfo) constructor 201 private Map<String, String> noTileHeaders; 200 // when adding a field, also adapt the ImageryInfo(ImageryInfo) constructor, equals method, and ImageryPreferenceEntry 202 201 203 202 /** … … 228 227 @pref Map<String, String> noTileHeaders; 229 228 @pref int tileSize = OsmMercator.DEFAUL_TILE_SIZE; 229 @pref Map<String, String> metadataHeaders; 230 230 231 231 /** … … 285 285 } 286 286 287 if (i.metadataHeaders != null && !i.metadataHeaders.isEmpty()) { 288 metadataHeaders = i.metadataHeaders; 289 } 290 287 291 tileSize = i.getTileSize(); 288 292 } … … 408 412 } 409 413 setTileSize(e.tileSize); 414 metadataHeaders = e.metadataHeaders; 410 415 } 411 416 … … 436 441 this.icon = i.icon; 437 442 this.description = i.description; 443 this.noTileHeaders = i.noTileHeaders; 444 this.metadataHeaders = i.metadataHeaders; 438 445 } 439 446 … … 465 472 return false; 466 473 } 467 if (!Objects.equals(this.name, other.name)) { 468 return false; 469 } 470 if (!Objects.equals(this.id, other.id)) { 471 return false; 472 } 473 if (!Objects.equals(this.url, other.url)) { 474 return false; 475 } 476 if (!Objects.equals(this.cookies, other.cookies)) { 477 return false; 478 } 479 if (!Objects.equals(this.eulaAcceptanceRequired, other.eulaAcceptanceRequired)) { 480 return false; 481 } 482 if (this.imageryType != other.imageryType) { 483 return false; 484 } 485 if (this.defaultMaxZoom != other.defaultMaxZoom) { 486 return false; 487 } 488 if (this.defaultMinZoom != other.defaultMinZoom) { 489 return false; 490 } 491 if (!Objects.equals(this.bounds, other.bounds)) { 492 return false; 493 } 494 if (!Objects.equals(this.serverProjections, other.serverProjections)) { 495 return false; 496 } 497 if (!Objects.equals(this.attributionText, other.attributionText)) { 498 return false; 499 } 500 if (!Objects.equals(this.attributionLinkURL, other.attributionLinkURL)) { 501 return false; 502 } 503 if (!Objects.equals(this.attributionImage, other.attributionImage)) { 504 return false; 505 } 506 if (!Objects.equals(this.attributionImageURL, other.attributionImageURL)) { 507 return false; 508 } 509 if (!Objects.equals(this.termsOfUseText, other.termsOfUseText)) { 510 return false; 511 } 512 if (!Objects.equals(this.termsOfUseURL, other.termsOfUseURL)) { 513 return false; 514 } 515 if (!Objects.equals(this.countryCode, other.countryCode)) { 516 return false; 517 } 518 if (!Objects.equals(this.icon, other.icon)) { 519 return false; 520 } 521 if (!Objects.equals(this.description, other.description)) { 522 return false; 523 } 524 return true; 474 475 return 476 Objects.equals(this.name, other.name) && 477 Objects.equals(this.id, other.id) && 478 Objects.equals(this.url, other.url) && 479 Objects.equals(this.cookies, other.cookies) && 480 Objects.equals(this.eulaAcceptanceRequired, other.eulaAcceptanceRequired) && 481 Objects.equals(this.imageryType, other.imageryType) && 482 Objects.equals(this.defaultMaxZoom, other.defaultMaxZoom) && 483 Objects.equals(this.defaultMinZoom, other.defaultMinZoom) && 484 Objects.equals(this.bounds, other.bounds) && 485 Objects.equals(this.serverProjections, other.serverProjections) && 486 Objects.equals(this.attributionText, other.attributionText) && 487 Objects.equals(this.attributionLinkURL, other.attributionLinkURL) && 488 Objects.equals(this.attributionImageURL, other.attributionImageURL) && 489 Objects.equals(this.attributionImage, other.attributionImage) && 490 Objects.equals(this.termsOfUseText, other.termsOfUseText) && 491 Objects.equals(this.termsOfUseURL, other.termsOfUseURL) && 492 Objects.equals(this.countryCode, other.countryCode) && 493 Objects.equals(this.icon, other.icon) && 494 Objects.equals(this.description, other.description) && 495 Objects.equals(this.noTileHeaders, other.noTileHeaders) && 496 Objects.equals(this.metadataHeaders, other.metadataHeaders); 525 497 } 526 498 … … 1058 1030 return noTileHeaders; 1059 1031 } 1032 1033 public void setMetadataHeaders(Map<String, String> metadataHeaders) { 1034 this.metadataHeaders = metadataHeaders; 1035 } 1060 1036 } -
trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java
r8349 r8418 150 150 for (ImageryInfo def : defaultLayers) { 151 151 // temporary migration code, so all user preferences will get updated with new settings from JOSM site (can be removed ~Dez. 2015) 152 if (def.getNoTileHeaders() != null || def.getTileSize() > 0 ) {152 if (def.getNoTileHeaders() != null || def.getTileSize() > 0 || def.getMetadataHeaders() != null ) { 153 153 for (ImageryInfo i: layers) { 154 154 if (isSimilar(def, i)) { … … 158 158 if (def.getTileSize() > 0) { 159 159 i.setTileSize(def.getTileSize()); 160 } 161 if (def.getMetadataHeaders() != null && def.getMetadataHeaders().size() > 0) { 162 i.setMetadataHeaders(def.getMetadataHeaders()); 160 163 } 161 164 changed = true; -
trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
r8403 r8418 10 10 import java.util.List; 11 11 import java.util.Map; 12 import java.util.Map.Entry; 12 13 import java.util.Set; 13 14 import java.util.concurrent.ConcurrentHashMap; … … 133 134 @Override 134 135 protected boolean cacheAsEmpty(Map<String, List<String>> headers, int statusCode, byte[] content) { 136 // cacheAsEmpty is called for every successful download, so we can put 137 // metadata handling here 138 attributes.setMetadata(tile.getTileSource().getMetadata(headers)); 135 139 if (tile.getTileSource().isNoTileAtZoom(headers, statusCode, content)) { 136 140 attributes.setNoTileAtZoom(true); … … 166 170 if(!tile.isLoaded()) { //if someone else already loaded tile, skip all the handling 167 171 tile.finishLoading(); // whatever happened set that loading has finished 172 // set tile metadata 173 if (this.attributes != null) { 174 for (Entry<String, String> e: this.attributes.getMetadata().entrySet()) { 175 tile.putValue(e.getKey(), e.getValue()); 176 } 177 } 178 168 179 switch(result){ 169 180 case SUCCESS: … … 214 225 if (isObjectLoadable()) { 215 226 try { 227 // set tile metadata 228 if (this.attributes != null) { 229 for (Entry<String, String> e: this.attributes.getMetadata().entrySet()) { 230 tile.putValue(e.getKey(), e.getValue()); 231 } 232 } 233 216 234 if (data != null && data.getImage() != null) { 217 235 tile.setImage(data.getImage()); -
trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java
r8403 r8418 8 8 import java.awt.Graphics; 9 9 import java.awt.Graphics2D; 10 import java.awt.GridBagLayout; 10 11 import java.awt.Image; 11 12 import java.awt.Point; … … 20 21 import java.io.StringReader; 21 22 import java.net.URL; 23 import java.text.SimpleDateFormat; 22 24 import java.util.ArrayList; 23 25 import java.util.Collections; 24 26 import java.util.Comparator; 27 import java.util.Date; 25 28 import java.util.HashMap; 26 29 import java.util.LinkedList; 27 30 import java.util.List; 28 31 import java.util.Map; 32 import java.util.Map.Entry; 29 33 import java.util.Scanner; 30 34 import java.util.concurrent.Callable; … … 34 38 import javax.swing.AbstractAction; 35 39 import javax.swing.Action; 40 import javax.swing.BorderFactory; 36 41 import javax.swing.JCheckBoxMenuItem; 42 import javax.swing.JLabel; 37 43 import javax.swing.JMenuItem; 38 44 import javax.swing.JOptionPane; 45 import javax.swing.JPanel; 39 46 import javax.swing.JPopupMenu; 47 import javax.swing.JTextField; 40 48 41 49 import org.openstreetmap.gui.jmapviewer.AttributionSupport; … … 80 88 import org.openstreetmap.josm.io.UTFInputStreamReader; 81 89 import org.openstreetmap.josm.tools.CheckParameterUtil; 90 import org.openstreetmap.josm.tools.GBC; 82 91 import org.openstreetmap.josm.tools.Utils; 83 92 import org.xml.sax.InputSource; … … 533 542 tileOptionMenu.add(new JMenuItem(new AbstractAction( 534 543 tr("Show Tile Info")) { 544 private String getSizeString(int size) { 545 StringBuilder ret = new StringBuilder(); 546 return ret.append(size).append("x").append(size).toString(); 547 } 548 549 private JTextField createTextField(String text) { 550 JTextField ret = new JTextField(text); 551 ret.setEditable(false); 552 ret.setBorder(BorderFactory.createEmptyBorder()); 553 return ret; 554 } 535 555 @Override 536 556 public void actionPerformed(ActionEvent ae) { 537 557 if (clickedTile != null) { 538 558 ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Tile Info"), new String[]{tr("OK")}); 559 JPanel panel = new JPanel(new GridBagLayout()); 560 Rectangle displaySize = tileToRect(clickedTile); 561 String url = ""; 562 try { 563 url = clickedTile.getUrl(); 564 } catch (IOException e) { 565 // silence exceptions 566 } 567 568 String[][] content = { 569 {"Tile name", clickedTile.getKey()}, 570 {"Tile url", url}, 571 {"Tile size", getSizeString(clickedTile.getTileSource().getTileSize()) }, 572 {"Tile display size", new StringBuilder().append(displaySize.width).append("x").append(displaySize.height).toString()}, 573 }; 574 575 for (String[] entry: content) { 576 panel.add(new JLabel(tr(entry[0]) + ":"), GBC.std()); 577 panel.add(GBC.glue(5,0), GBC.std()); 578 panel.add(createTextField(entry[1]), GBC.eol().fill(GBC.HORIZONTAL)); 579 } 580 581 for (Entry<String, String> e: clickedTile.getMetadata().entrySet()) { 582 panel.add(new JLabel(tr("Metadata ") + tr(e.getKey()) + ":"), GBC.std()); 583 panel.add(GBC.glue(5,0), GBC.std()); 584 String value = e.getValue(); 585 if ("lastModification".equals(e.getKey()) || "expirationTime".equals(e.getKey())) { 586 value = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(Long.parseLong(value))); 587 } 588 panel.add(createTextField(value), GBC.eol().fill(GBC.HORIZONTAL)); 589 590 } 539 591 ed.setIcon(JOptionPane.INFORMATION_MESSAGE); 540 StringBuilder content = new StringBuilder(); 541 content.append("Tile name: ").append(clickedTile.getKey()).append('\n'); 542 try { 543 content.append("Tile url: ").append(clickedTile.getUrl()).append('\n'); 544 } catch (IOException e) { 545 } 546 content.append("Tile size: ").append(clickedTile.getTileSource().getTileSize()).append('x').append(clickedTile.getTileSource().getTileSize()).append('\n'); 547 Rectangle displaySize = tileToRect(clickedTile); 548 content.append("Tile display size: ").append(displaySize.width).append('x').append(displaySize.height).append('\n'); 549 ed.setContent(content.toString()); 592 ed.setContent(panel); 550 593 ed.showDialog(); 551 594 } -
trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
r8390 r8418 42 42 SHAPE, 43 43 NO_TILE, 44 METADATA, 44 45 UNKNOWN, // element is not recognized in the current context 45 46 } … … 88 89 private List<String> projections; 89 90 private Map<String, String> noTileHeaders; 91 private Map<String, String> metadataHeaders; 90 92 91 93 @Override … … 117 119 skipEntry = false; 118 120 newState = State.ENTRY; 121 noTileHeaders = new HashMap<>(); 122 metadataHeaders = new HashMap<>(); 119 123 } 120 124 break; … … 157 161 newState = State.PROJECTIONS; 158 162 } else if ("no-tile-header".equals(qName)) { 159 noTileHeaders = new HashMap<>();160 163 noTileHeaders.put(atts.getValue("name"), atts.getValue("value")); 161 164 newState = State.NO_TILE; 165 } else if ("metadata-header".equals(qName)) { 166 metadataHeaders.put(atts.getValue("header-name"), atts.getValue("metadata-key")); 167 newState = State.METADATA; 162 168 } 163 169 break; … … 196 202 skipEntry = true; 197 203 } 198 return;199 204 } 200 205 … … 211 216 case ENTRY: 212 217 if ("entry".equals(qName)) { 218 entry.setNoTileHeaders(noTileHeaders); 219 noTileHeaders = null; 220 entry.setMetadataHeaders(metadataHeaders); 221 metadataHeaders = null; 222 213 223 if (!skipEntry) { 214 224 entries.add(entry); … … 332 342 break; 333 343 case NO_TILE: 334 entry.setNoTileHeaders(noTileHeaders);335 noTileHeaders = null;336 344 break; 337 345
Note:
See TracChangeset
for help on using the changeset viewer.