blob: ab581c28934260d4974e9983095b0486fc9452d2 [file] [log] [blame]
Brian Attwell493f8d12014-12-18 12:42:03 -08001/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17package com.android.contacts.quickcontact;
18
Gary Mai0a49afa2016-12-05 15:53:58 -080019import static android.util.Patterns.GOOD_IRI_CHAR;
20
Brian Attwell493f8d12014-12-18 12:42:03 -080021import java.util.Locale;
22import java.util.regex.Matcher;
23import java.util.regex.Pattern;
24
Brian Attwell493f8d12014-12-18 12:42:03 -080025/**
26 * Below is a partial copy of {@link android.net.WebAddress}. The original author doesn't
27 * believe this API is suitable for making public. He recommends we copy it.
28 *
29 * Web Address Parser
30 *
31 * This is called WebAddress, rather than URL or URI, because it
32 * attempts to parse the stuff that a user will actually type into a
33 * browser address widget.
34 *
35 * Unlike java.net.uri, this parser will not choke on URIs missing
36 * schemes. It will only throw a ParseException if the input is
37 * really hosed.
38 *
39 * If given an https scheme but no port, fills in port
40 *
41 */
42public class WebAddress {
43
44 private String mScheme;
45 private String mHost;
46 private int mPort;
47 private String mPath;
48 private String mAuthInfo;
49
50 static final int MATCH_GROUP_SCHEME = 1;
51 static final int MATCH_GROUP_AUTHORITY = 2;
52 static final int MATCH_GROUP_HOST = 3;
53 static final int MATCH_GROUP_PORT = 4;
54 static final int MATCH_GROUP_PATH = 5;
55
56 static Pattern sAddressPattern = Pattern.compile(
57 /* scheme */ "(?:(http|https|file)\\:\\/\\/)?" +
58 /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
59 /* host */ "([" + GOOD_IRI_CHAR + "%_-][" + GOOD_IRI_CHAR + "%_\\.-]*|\\[[0-9a-fA-F:\\.]+\\])?" +
60 /* port */ "(?:\\:([0-9]*))?" +
61 /* path */ "(\\/?[^#]*)?" +
62 /* anchor */ ".*", Pattern.CASE_INSENSITIVE);
63
64 /** parses given uriString. */
65 public WebAddress(String address) throws ParseException {
66 if (address == null) {
67 throw new NullPointerException();
68 }
69
70 // android.util.Log.d(LOGTAG, "WebAddress: " + address);
71
72 mScheme = "";
73 mHost = "";
74 mPort = -1;
75 mPath = "/";
76 mAuthInfo = "";
77
78 Matcher m = sAddressPattern.matcher(address);
79 String t;
80 if (m.matches()) {
81 t = m.group(MATCH_GROUP_SCHEME);
82 if (t != null) mScheme = t.toLowerCase(Locale.ROOT);
83 t = m.group(MATCH_GROUP_AUTHORITY);
84 if (t != null) mAuthInfo = t;
85 t = m.group(MATCH_GROUP_HOST);
86 if (t != null) mHost = t;
87 t = m.group(MATCH_GROUP_PORT);
88 if (t != null && t.length() > 0) {
89 // The ':' character is not returned by the regex.
90 try {
91 mPort = Integer.parseInt(t);
92 } catch (NumberFormatException ex) {
93 throw new ParseException("Bad port");
94 }
95 }
96 t = m.group(MATCH_GROUP_PATH);
97 if (t != null && t.length() > 0) {
98 /* handle busted myspace frontpage redirect with
99 missing initial "/" */
100 if (t.charAt(0) == '/') {
101 mPath = t;
102 } else {
103 mPath = "/" + t;
104 }
105 }
106
107 } else {
108 // nothing found... outa here
109 throw new ParseException("Bad address");
110 }
111
112 /* Get port from scheme or scheme from port, if necessary and
113 possible */
114 if (mPort == 443 && mScheme.equals("")) {
115 mScheme = "https";
116 } else if (mPort == -1) {
117 if (mScheme.equals("https"))
118 mPort = 443;
119 else
120 mPort = 80; // default
121 }
122 if (mScheme.equals("")) mScheme = "http";
123 }
124
125 @Override
126 public String toString() {
127 String port = "";
128 if ((mPort != 443 && mScheme.equals("https")) ||
129 (mPort != 80 && mScheme.equals("http"))) {
130 port = ":" + Integer.toString(mPort);
131 }
132 String authInfo = "";
133 if (mAuthInfo.length() > 0) {
134 authInfo = mAuthInfo + "@";
135 }
136
137 return mScheme + "://" + authInfo + mHost + port + mPath;
138 }
139
140 public class ParseException extends Exception {
141 public String response;
142
143 ParseException(String response) {
144 this.response = response;
145 }
146 }
147}