001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.preferences; 003 004import static org.openstreetmap.josm.tools.Utils.equal; 005 006import java.io.File; 007import java.util.regex.Matcher; 008import java.util.regex.Pattern; 009 010import org.openstreetmap.josm.Main; 011 012/** 013 * A source entry primarily used to save the user's selection of mappaint styles, 014 * but also for preset sources. 015 */ 016public class SourceEntry { 017 018 /** 019 * A URL can be anything that MirroredInputStream understands, i.e. 020 * a local file, http://, or a file from the current jar 021 */ 022 public String url; 023 024 /** 025 * Indicates, that {@link #url} is a zip file and the resource is 026 * inside the zip file. 027 */ 028 public boolean isZip; 029 030 /** 031 * If {@link #isZip} is true, denotes the path inside the zip file. 032 */ 033 public String zipEntryPath; 034 035 /** 036 * Name is used as a namespace for color preferences and (currently) only 037 * one file with a name can be loaded at a time. Additional styles must 038 * either have the same name as the main style or no name at all. 039 * If no name is provided, it will be set to the default value "standard". 040 * The name can also be given in the xml file as attribute for the rules tag. 041 * (This overrides the name given in the preferences, otherwise both 042 * methods are equivalent.) 043 */ 044 public String name; 045 046 /** 047 * A title that can be used as menu entry. 048 */ 049 public String title; 050 051 /** 052 * active is a boolean flag that can be used to turn the style on or off 053 * at runtime. 054 */ 055 public boolean active; 056 057 public SourceEntry(String url, boolean isZip, String zipEntryPath, String name, String title, boolean active) { 058 this.url = url; 059 this.isZip = isZip; 060 this.zipEntryPath = equal(zipEntryPath, "") ? null : zipEntryPath; 061 this.name = equal(name, "") ? null : name; 062 this.title = equal(title, "") ? null : title; 063 this.active = active; 064 } 065 066 public SourceEntry(String url, String name, String title, Boolean active) { 067 this(url, false, null, name, title, active); 068 } 069 070 public SourceEntry(SourceEntry e) { 071 this.url = e.url; 072 this.isZip = e.isZip; 073 this.zipEntryPath = e.zipEntryPath; 074 this.name = e.name; 075 this.title = e.title; 076 this.active = e.active; 077 } 078 079 @Override 080 public boolean equals(Object obj) { 081 if (obj == null || getClass() != obj.getClass()) 082 return false; 083 final SourceEntry other = (SourceEntry) obj; 084 return equal(other.url, url) && 085 other.isZip == isZip && 086 equal(other.zipEntryPath, zipEntryPath) && 087 equal(other.name, name) && 088 equal(other.title, title) && 089 other.active == active; 090 } 091 092 @Override 093 public int hashCode() { 094 int hash = 5; 095 hash = 89 * hash + (this.url != null ? this.url.hashCode() : 0); 096 hash = 89 * hash + (this.isZip ? 1 : 0); 097 hash = 89 * hash + (this.zipEntryPath != null ? this.zipEntryPath.hashCode() : 0); 098 hash = 89 * hash + (this.name != null ? this.name.hashCode() : 0); 099 hash = 89 * hash + (this.title != null ? this.title.hashCode() : 0); 100 hash = 89 * hash + (this.active ? 1 : 0); 101 return hash; 102 } 103 104 @Override 105 public String toString() { 106 return title != null ? title : url; 107 } 108 109 /** 110 * String to show in menus and error messages. 111 * @return Usually the shortdescription, but can be the file name 112 * if no shortdescription is available. 113 */ 114 public String getDisplayString() { 115 if (title != null) 116 return title; 117 else 118 return getFileNamePart(); 119 } 120 121 /** 122 * extract file part from url, e.g.: 123 * http://www.test.com/file.xml?format=text --> file.xml 124 */ 125 public String getFileNamePart() { 126 Pattern p = Pattern.compile("([^/\\\\]*?)([?].*)?$"); 127 Matcher m = p.matcher(url); 128 if (m.find()) { 129 return m.group(1); 130 } else { 131 Main.warn("Unexpected URL format: "+url); 132 return url; 133 } 134 } 135 136 /** 137 * the name / identifier that should be used to save custom color values 138 * and similar stuff to the preference file 139 * @return the identifier; never null. Usually the result is "standard" 140 */ 141 public String getPrefName() { 142 return name == null ? "standard" : name; 143 } 144 145 public boolean isLocal() { 146 if (url.startsWith("http://") || url.startsWith("resource://")) 147 return false; 148 return true; 149 } 150 151 public String getLocalSourceDir() { 152 if (!isLocal()) 153 return null; 154 File f = new File(url); 155 File dir = f.getParentFile(); 156 if (dir == null) 157 return null; 158 return dir.getPath(); 159 } 160 161 /** 162 * Returns the parent directory of the resource inside the zip file. 163 * 164 * @return the parent directory of the resource inside the zip file, 165 * "." if zipEntryPath is a top level file; null, if zipEntryPath is null 166 */ 167 public String getZipEntryDirName() { 168 if (zipEntryPath == null) return null; 169 File file = new File(zipEntryPath); 170 File dir = file.getParentFile(); 171 if (dir == null) return "."; 172 String path = dir.getPath(); 173 if (!"/".equals(File.separator)) { 174 path = path.replace(File.separator, "/"); 175 } 176 return path; 177 } 178}