ref #10178: new methods for normalization of names
[cdmlib.git] / cdmlib-commons / src / main / java / eu / etaxonomy / cdm / common / URI.java
1 /**
2 * Copyright (C) 2021 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.common;
10
11 import java.io.File;
12 import java.io.Serializable;
13 import java.net.MalformedURLException;
14 import java.net.URISyntaxException;
15 import java.net.URL;
16
17 /**
18 * See https://dev.e-taxonomy.eu/redmine/issues/9114
19 *
20 * @author a.mueller
21 * @since 05.01.2021
22 */
23 public class URI
24 implements Comparable<URI>, Serializable {
25
26 private static final long serialVersionUID = -8002215586516542076L;
27
28 private final java.net.URI javaUri;
29
30 // ***************************** FACTORY METHODS ***************************************/
31
32 public static URI fromString(String uri) throws URISyntaxException {
33 return new URI(uri);
34 }
35
36 /**
37 * Factory method.
38 *
39 * @see java.net.URI#create(String)
40 */
41 public static URI create(String uri) {
42 try {
43 return new URI(uri);
44 } catch (URISyntaxException e) {
45 throw new IllegalArgumentException(e);
46 }
47 }
48
49 public static URI fromUrl(URL url) throws URISyntaxException {
50 return new URI(url);
51 }
52
53 public static URI fromFile(File file) {
54 return new URI(file.toURI());
55 }
56
57 // ******************************* CONSTRUCTOR ************************************/
58
59 @SuppressWarnings("unused")
60 private URI(){javaUri = null;} //empty constructor required for JAXB (not tested but copied from DOI)
61
62 public URI(String uriString) throws URISyntaxException {
63 javaUri = parseUriString(uriString);
64 }
65
66 public URI(java.net.URI javaUri) {
67 this.javaUri = javaUri;
68 }
69
70 //TODO maybe we can do encoding in between
71 public URI(URL url) throws URISyntaxException {
72 this.javaUri = url.toURI();
73 }
74
75 /**
76 * @see java.net.URI#URI(String, String, String, int, String, String, String)
77 */
78 public URI(String protocol, String userInfo, String host, int port, String path, String query, String ref) throws URISyntaxException {
79 javaUri = new java.net.URI(protocol, userInfo, host, port, path, query, ref);
80 }
81
82 public URI(String scheme, String authority, String path, String query, String fragment) throws URISyntaxException{
83 javaUri = new java.net.URI(scheme, authority, path, query, fragment);
84 }
85
86 //************************************ GETTER ***********************************/
87
88 public java.net.URI getJavaUri(){
89 return javaUri;
90 }
91
92 //************************************ METHODS ************************************/
93
94 private java.net.URI parseUriString(String uriString) throws URISyntaxException {
95 java.net.URI javaUri = null;
96 if(uriString != null){
97 try{
98 javaUri = new java.net.URI(uriString);
99 }catch(Exception e){
100 try {
101 String encodedUri = uriString;
102 URL url = new URL(encodedUri);
103 String[] pathElements = url.getPath().split("/");
104 for (String element: pathElements){
105 if(element.contains("\\")){
106 //TODO needs discussion if backslash should be converted to slash instead, for now we keep it more strict
107 throw new URISyntaxException(uriString, "URI path must not contain backslash ('\')");
108 }
109 String replacement = UrlUtf8Coder.encode(element);
110 encodedUri = encodedUri.replace(element, replacement);
111 }
112 if (url.getQuery() != null){
113 encodedUri = encodedUri.replace(url.getQuery(), UrlUtf8Coder.encode(url.getQuery()));
114 }
115 String fragmentElement = uriString.substring(uriString.indexOf("#")+1,uriString.length());
116 if(fragmentElement.contains("\\")){
117 //TODO needs discussion if backslash should be converted to slash instead, for now we keep it more strict
118 throw new URISyntaxException(uriString, "URI path must not contain backslash ('\')");
119 }
120 String replacement = UrlUtf8Coder.encode(fragmentElement);
121 encodedUri = encodedUri.replace(fragmentElement, replacement);
122
123 url = new URL(encodedUri);
124
125 javaUri = url.toURI();
126 } catch (MalformedURLException e1) {
127 throw new URISyntaxException(uriString, e1.getMessage());
128 }
129 }
130 }
131 return javaUri;
132 }
133
134 public File toFile(){
135 return new File(javaUri);
136 }
137
138 //******************************** Wrapper methods *********************/
139
140 public URL toURL() throws MalformedURLException{
141 return javaUri.toURL();
142 }
143
144 public String getHost() {
145 return javaUri.getHost();
146 }
147
148 public int getPort() {
149 return javaUri.getPort();
150 }
151
152 public String getScheme() {
153 return javaUri.getScheme();
154 }
155
156 public boolean isAbsolute() {
157 return javaUri.isAbsolute();
158 }
159
160 public String getPath() {
161 return javaUri.getPath();
162 }
163
164 public String getFragment() {
165 return javaUri.getFragment();
166 }
167
168 public Object getQuery() {
169 return javaUri.getQuery();
170 }
171
172 //****************************** equals *****************************/
173
174 @Override
175 public int hashCode() {
176 return javaUri.hashCode();
177 }
178
179 @Override
180 public boolean equals(Object obj) {
181 if (obj instanceof URI){
182 return javaUri.equals(((URI)obj).javaUri);
183 }
184 return false;
185 }
186
187 @Override
188 public int compareTo(URI that) {
189 return this.javaUri.compareTo(that.javaUri);
190 }
191
192 //********************** clone ***********************************/
193
194 @Override
195 protected URI clone() throws CloneNotSupportedException {
196 return new URI(this.javaUri);
197 }
198
199 //******************************** toString ****************************/
200
201 @Override
202 public String toString() {
203 return javaUri.toString();
204 }
205 }