// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.gui.preferences;
import java.io.File;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.tools.Utils;
/**
* A source entry primarily used to save the user's selection of mappaint styles,
* but also for preset sources or validator rules.
* @since 3796
*/
public class SourceEntry {
/**
* A URL can be anything that CachedFile understands, i.e.
* a local file, http://, or a file from the current jar
*/
public String url;
/**
* Indicates, that {@link #url} is a zip file and the resource is
* inside the zip file.
*/
public boolean isZip;
/**
* If {@link #isZip} is true, denotes the path inside the zip file.
*/
public String zipEntryPath;
/**
* Name is used as a namespace for color preferences and (currently) only
* one file with a name can be loaded at a time. Additional styles must
* either have the same name as the main style or no name at all.
* If no name is provided, it will be set to the default value "standard".
* The name can also be given in the xml file as attribute for the rules tag.
* (This overrides the name given in the preferences, otherwise both
* methods are equivalent.)
*/
public String name;
/**
* A title that can be used as menu entry.
*/
public String title;
/**
* active is a boolean flag that can be used to turn the source on or off at runtime.
*/
public boolean active;
/**
* Constructs a new {@code SourceEntry}.
* @param url URL that {@link org.openstreetmap.josm.io.CachedFile} understands
* @param isZip if url is a zip file and the resource is inside the zip file
* @param zipEntryPath If {@code isZip} is {@code true}, denotes the path inside the zip file
* @param name Source name
* @param title title that can be used as menu entry
* @param active boolean flag that can be used to turn the source on or off at runtime
* @see #url
* @see #isZip
* @see #zipEntryPath
* @see #name
* @see #title
* @see #active
*/
public SourceEntry(String url, boolean isZip, String zipEntryPath, String name, String title, boolean active) {
this.url = url;
this.isZip = isZip;
this.zipEntryPath = "".equals(zipEntryPath) ? null : zipEntryPath;
this.name = "".equals(name) ? null : name;
this.title = "".equals(title) ? null : title;
this.active = active;
}
/**
* Constructs a new {@code SourceEntry}.
* @param url URL that {@link org.openstreetmap.josm.io.CachedFile} understands
* @param name Source name
* @param title title that can be used as menu entry
* @param active boolean flag that can be used to turn the source on or off at runtime
* @see #url
* @see #name
* @see #title
* @see #active
*/
public SourceEntry(String url, String name, String title, boolean active) {
this(url, false, null, name, title, active);
}
/**
* Constructs a new {@code SourceEntry}.
* @param e existing source entry to copy
*/
public SourceEntry(SourceEntry e) {
this.url = e.url;
this.isZip = e.isZip;
this.zipEntryPath = e.zipEntryPath;
this.name = e.name;
this.title = e.title;
this.active = e.active;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
SourceEntry that = (SourceEntry) obj;
return isZip == that.isZip &&
active == that.active &&
Objects.equals(url, that.url) &&
Objects.equals(zipEntryPath, that.zipEntryPath) &&
Objects.equals(name, that.name) &&
Objects.equals(title, that.title);
}
@Override
public int hashCode() {
return Objects.hash(url, isZip, zipEntryPath, name, title, active);
}
@Override
public String toString() {
return title != null ? title : url;
}
/**
* String to show in menus and error messages.
* @return Usually the shortdescription, but can be the file name
* if no shortdescription is available.
*/
public String getDisplayString() {
if (title != null)
return title;
else
return getFileNamePart();
}
/**
* Extracts file part from url, e.g.:
* <code>http://www.test.com/file.xml?format=text --> file.xml</code>
* @return The filename part of the URL
*/
public String getFileNamePart() {
Pattern p = Pattern.compile("([^/\\\\]*?)([?].*)?$");
Matcher m = p.matcher(url);
if (m.find()) {
return m.group(1);
} else {
Main.warn("Unexpected URL format: "+url);
return url;
}
}
/**
* the name / identifier that should be used to save custom color values
* and similar stuff to the preference file
* @return the identifier; never null. Usually the result is "standard"
*/
public String getPrefName() {
return name == null ? "standard" : name;
}
/**
* Determines if this source denotes a file on a local filesystem.
* @return {@code true} if the source is a local file
*/
public boolean isLocal() {
return Utils.isLocalUrl(url);
}
/**
* Return the source directory, only for local files.
* @return The source directory, or {@code null} if this file isn't local, or does not have a parent
* @since 7276
*/
public File getLocalSourceDir() {
if (!isLocal())
return null;
return new File(url).getParentFile();
}
/**
* Returns the parent directory of the resource inside the zip file.
*
* @return the parent directory of the resource inside the zip file,
* "." if zipEntryPath is a top level file; null, if zipEntryPath is null
*/
public String getZipEntryDirName() {
if (zipEntryPath == null) return null;
File file = new File(zipEntryPath);
File dir = file.getParentFile();
if (dir == null) return ".";
String path = dir.getPath();
if (!"/".equals(File.separator)) {
path = path.replace(File.separator, "/");
}
return path;
}
}