blob: ee2340db5a8911b532c91cf1f6f0829fe46a30a1 [file] [log] [blame]
/*
* Copyright 2000-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.util;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.StandardFileSystems;
import com.intellij.util.io.URLUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public final class UrlImpl implements Url {
private final String scheme;
private final String authority;
private final String path;
private String decodedPath;
private final String parameters;
private String externalForm;
private UrlImpl withoutParameters;
public UrlImpl(@Nullable String path) {
this(null, null, path, null);
}
UrlImpl(@NotNull String scheme, @Nullable String authority, @Nullable String path) {
this(scheme, authority, path, null);
}
public UrlImpl(@Nullable String scheme, @Nullable String authority, @Nullable String path, @Nullable String parameters) {
this.scheme = scheme;
this.authority = StringUtil.nullize(authority);
this.path = StringUtil.isEmpty(path) ? "/" : path;
this.parameters = StringUtil.nullize(parameters);
}
@NotNull
@Override
public String getPath() {
if (decodedPath == null) {
decodedPath = URLUtil.unescapePercentSequences(path);
}
return decodedPath;
}
@Nullable
@Override
public String getScheme() {
return scheme;
}
@Override
@Nullable
public String getAuthority() {
return authority;
}
@Override
public boolean isInLocalFileSystem() {
return StandardFileSystems.FILE_PROTOCOL.equals(scheme);
}
@Nullable
@Override
public String getParameters() {
return parameters;
}
@Override
public String toDecodedForm() {
StringBuilder builder = new StringBuilder();
if (scheme != null) {
builder.append(scheme);
if (authority != null || isInLocalFileSystem()) {
builder.append(URLUtil.SCHEME_SEPARATOR);
}
else {
builder.append(':');
}
if (authority != null) {
builder.append(authority);
}
}
builder.append(getPath());
if (parameters != null) {
builder.append(parameters);
}
return builder.toString();
}
@Override
@NotNull
public String toExternalForm() {
if (externalForm != null) {
return externalForm;
}
// relative path - special url, encoding is not required
// authority is null in case of URI or file URL
if ((path.charAt(0) != '/' || authority == null) && !isInLocalFileSystem()) {
return toDecodedForm();
}
String result = Urls.toUriWithoutParameters(this).toASCIIString();
if (parameters != null) {
result += parameters;
}
externalForm = result;
return result;
}
@Override
@NotNull
public Url trimParameters() {
if (parameters == null) {
return this;
}
else if (withoutParameters == null) {
withoutParameters = new UrlImpl(scheme, authority, path, null);
}
return withoutParameters;
}
@Override
public String toString() {
return toExternalForm();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof UrlImpl)) {
return false;
}
UrlImpl url = (UrlImpl)o;
return StringUtil.equals(scheme, url.scheme) && StringUtil.equals(authority, url.authority) && getPath().equals(url.getPath()) && StringUtil.equals(parameters, url.parameters);
}
@Override
public boolean equalsIgnoreCase(@Nullable Url o) {
if (this == o) {
return true;
}
if (!(o instanceof UrlImpl)) {
return false;
}
UrlImpl url = (UrlImpl)o;
return StringUtil.equalsIgnoreCase(scheme, url.scheme) &&
StringUtil.equalsIgnoreCase(authority, url.authority) &&
getPath().equalsIgnoreCase(url.getPath()) &&
StringUtil.equalsIgnoreCase(parameters, url.parameters);
}
@Override
public boolean equalsIgnoreParameters(@Nullable Url url) {
return url != null && equals(url.trimParameters());
}
private int computeHashCode(boolean caseSensitive) {
int result = stringHashCode(scheme, caseSensitive);
result = 31 * result + stringHashCode(authority, caseSensitive);
result = 31 * result + stringHashCode(getPath(), caseSensitive);
result = 31 * result + stringHashCode(parameters, caseSensitive);
return result;
}
private static int stringHashCode(@Nullable CharSequence string, boolean caseSensitive) {
return string == null ? 0 : (caseSensitive ? string.hashCode() : StringUtil.stringHashCodeInsensitive(string));
}
@Override
public int hashCode() {
return computeHashCode(true);
}
@Override
public int hashCodeCaseInsensitive() {
return computeHashCode(false);
}
}