2 * Copyright 2000-2015 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.intellij.util;
18 import com.intellij.openapi.util.text.StringUtil;
19 import com.intellij.util.io.URLUtil;
20 import org.jetbrains.annotations.NotNull;
21 import org.jetbrains.annotations.Nullable;
23 public final class UrlImpl implements Url {
24 private final String scheme;
25 private final String authority;
27 private final String path;
28 private String decodedPath;
30 private final String parameters;
32 private String externalForm;
33 private UrlImpl withoutParameters;
35 public UrlImpl(@NotNull String path) {
36 this(null, null, path, null);
39 UrlImpl(@NotNull String scheme, @Nullable String authority, @Nullable String path) {
40 this(scheme, authority, path, null);
43 public UrlImpl(@Nullable String scheme, @Nullable String authority, @Nullable String path, @Nullable String parameters) {
45 this.authority = authority;
46 this.path = StringUtil.notNullize(path);
47 this.parameters = StringUtil.nullize(parameters);
52 public String getPath() {
53 if (decodedPath == null) {
54 decodedPath = URLUtil.unescapePercentSequences(path);
61 public String getScheme() {
67 public String getAuthority() {
72 public boolean isInLocalFileSystem() {
73 return URLUtil.FILE_PROTOCOL.equals(scheme);
78 public String getParameters() {
83 public String toDecodedForm() {
84 StringBuilder builder = new StringBuilder();
86 builder.append(scheme);
87 if (authority == null) {
91 builder.append(URLUtil.SCHEME_SEPARATOR);
94 if (authority != null) {
95 builder.append(authority);
98 builder.append(getPath());
99 if (parameters != null) {
100 builder.append(parameters);
102 return builder.toString();
107 public String toExternalForm() {
108 if (externalForm != null) {
112 // relative path - special url, encoding is not required
113 // authority is null in case of URI
114 if ((authority == null || (!path.isEmpty() && path.charAt(0) != '/')) && !isInLocalFileSystem()) {
115 return toDecodedForm();
118 String result = Urls.toUriWithoutParameters(this).toASCIIString();
119 if (parameters != null) {
120 result += parameters;
122 externalForm = result;
128 public Url trimParameters() {
129 if (parameters == null) {
132 else if (withoutParameters == null) {
133 withoutParameters = new UrlImpl(scheme, authority, path, null);
135 return withoutParameters;
139 public String toString() {
140 return toExternalForm();
144 public boolean equals(Object o) {
148 if (!(o instanceof UrlImpl)) {
152 UrlImpl url = (UrlImpl)o;
153 return StringUtil.equals(scheme, url.scheme) && StringUtil.equals(authority, url.authority) && getPath().equals(url.getPath()) && StringUtil.equals(parameters, url.parameters);
157 public boolean equalsIgnoreCase(@Nullable Url o) {
161 if (!(o instanceof UrlImpl)) {
165 UrlImpl url = (UrlImpl)o;
166 return StringUtil.equalsIgnoreCase(scheme, url.scheme) &&
167 StringUtil.equalsIgnoreCase(authority, url.authority) &&
168 getPath().equalsIgnoreCase(url.getPath()) &&
169 StringUtil.equalsIgnoreCase(parameters, url.parameters);
173 public boolean equalsIgnoreParameters(@Nullable Url url) {
174 return url != null && equals(url.trimParameters());
177 private int computeHashCode(boolean caseSensitive) {
178 int result = stringHashCode(scheme, caseSensitive);
179 result = 31 * result + stringHashCode(authority, caseSensitive);
180 result = 31 * result + stringHashCode(getPath(), caseSensitive);
181 result = 31 * result + stringHashCode(parameters, caseSensitive);
185 private static int stringHashCode(@Nullable CharSequence string, boolean caseSensitive) {
186 return string == null ? 0 : (caseSensitive ? string.hashCode() : StringUtil.stringHashCodeInsensitive(string));
190 public int hashCode() {
191 return computeHashCode(true);
195 public int hashCodeCaseInsensitive() {
196 return computeHashCode(false);