001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.wsdlextensions.jms.validator;
021:
022: import java.util.Properties;
023: import java.util.StringTokenizer;
024: import java.net.URLDecoder;
025: import java.io.UnsupportedEncodingException;
026:
027: /**
028: * URLParser
029: * A generic parser for the following pattern:
030: * protocol://host[:port][/path]
031: * path :== file?query | ?query | file
032: *
033: * Examples:
034: * p://h
035: * p://h:p
036: * p://h/file?query
037: * p://h?query
038: *
039: */
040: public class UrlParser extends ConnectionUrl {
041: private String mUrl;
042: private boolean mParsed;
043: private String mProtocol;
044: private int mPort;
045: private String mHost;
046: private String mPath;
047: private String mFile;
048: private String mQuery;
049:
050: /**
051: * Constructor
052: *
053: * @param url String
054: */
055: public UrlParser(String url) {
056: mUrl = url;
057: }
058:
059: private void parse() throws ValidationException {
060: if (mParsed) {
061: return;
062: }
063:
064: String r = mUrl;
065: mParsed = true;
066:
067: // Protocol
068: int i = r.indexOf("://");
069: if (i < 0) {
070: throw new ValidationException("Invalid URL [" + mUrl
071: + "]: no protocol specified");
072: }
073: mProtocol = r.substring(0, i);
074: r = r.substring(i + "://".length());
075:
076: // host[:port]
077: i = r.indexOf('/');
078: if (i < 0) {
079: i = r.indexOf('?');
080: }
081: String server = i >= 0 ? r.substring(0, i) : r;
082: r = i >= 0 ? r.substring(i) : "";
083:
084: i = server.indexOf(':');
085: if (i >= 0) {
086: mHost = server.substring(0, i);
087: String port = server.substring(i + 1);
088: if (port.length() > 0) {
089: mPort = Integer.parseInt(port);
090: } else {
091: mPort = -1;
092: }
093: } else {
094: mHost = server;
095: mPort = -1;
096: }
097:
098: // path
099: if (r.length() > 0) {
100: mFile = r.substring(0);
101: } else {
102: mFile = "";
103: }
104:
105: // file
106: if (!r.startsWith("/")) {
107: mPath = "";
108: } else {
109: i = r.indexOf('?');
110: if (i >= 0) {
111: mPath = r.substring(0, i);
112: r = r.substring(i);
113: } else {
114: mPath = r;
115: r = "";
116: }
117: }
118:
119: // query
120: if (r.startsWith("?")) {
121: mQuery = r.substring(1);
122: }
123: }
124:
125: /**
126: * Changes the port
127: *
128: * @param port int
129: */
130: public void setPort(int port) throws ValidationException {
131: parse();
132: mPort = port;
133: mUrl = null;
134: }
135:
136: /**
137: * Changes the server portion
138: *
139: * @param host String
140: */
141: public void setHost(String host) throws ValidationException {
142: parse();
143: mHost = host;
144: mUrl = null;
145: }
146:
147: /**
148: * Returns the URL in full string form
149: *
150: * @return String
151: */
152: public String toString() {
153: if (mUrl == null) {
154: StringBuffer url = new StringBuffer();
155: url.append(mProtocol).append("://").append(mHost);
156: if (mPort != -1) {
157: url.append(":").append(mPort);
158: }
159: url.append(mFile);
160: mUrl = url.toString();
161: }
162: return mUrl;
163: }
164:
165: /**
166: * Gets the protocol name of this <code>URL</code>.
167: *
168: * @return the protocol of this <code>URL</code>.
169: */
170: public String getProtocol() throws ValidationException {
171: parse();
172: return mProtocol;
173: }
174:
175: /**
176: * Gets the host name of this <code>URL</code>
177: *
178: * @return the host name of this <code>URL</code>.
179: */
180: public String getHost() throws ValidationException {
181: parse();
182: return mHost;
183: }
184:
185: /**
186: * Gets the port number of this <code>URL</code>.
187: *
188: * @return the port number, or -1 if the port is not set
189: */
190: public int getPort() throws ValidationException {
191: parse();
192: return mPort;
193: }
194:
195: /**
196: * Gets the file name of this <code>URL</code>.
197: * The returned file portion will be
198: * the same as <CODE>getPath()</CODE>, plus the concatenation of
199: * the value of <CODE>getQuery()</CODE>, if any. If there is
200: * no query portion, this method and <CODE>getPath()</CODE> will
201: * return identical results.
202: *
203: * @return the file name of this <code>URL</code>,
204: * or an empty string if one does not exist
205: */
206: public String getFile() throws ValidationException {
207: parse();
208: return mFile;
209: }
210:
211: /**
212: * Gets the path part of this <code>URL</code>.
213: *
214: * @return the path part of this <code>URL</code>, or an
215: * empty string if one does not exist
216: */
217: public String getPath() throws ValidationException {
218: parse();
219: return mPath;
220: }
221:
222: /**
223: * Gets the query part of this <code>URL</code>.
224: *
225: * @return the query part of this <code>URL</code>,
226: * or <CODE>null</CODE> if one does not exist
227: */
228: public String getQuery() throws ValidationException {
229: parse();
230: return mQuery;
231: }
232:
233: /**
234: * Extracts the key value pairs from the query string
235: *
236: * @param toAddTo Properties key-value pairs will be added to this properties set
237: */
238: public void getQueryProperties(Properties toAddTo)
239: throws ValidationException {
240: String q = getQuery();
241: getQueryProperties(q, toAddTo);
242: }
243:
244: /**
245: * Tool function: queries a query string and adds the key/value pairs to the specified
246: * properties map
247: *
248: * @param q String
249: * @param toAddTo Properties
250: */
251: public static void getQueryProperties(String q, Properties toAddTo)
252: throws ValidationException {
253: if (q == null || q.length() == 0) {
254: return;
255: }
256: for (StringTokenizer iter = new StringTokenizer(q, "&"); iter
257: .hasMoreElements();/*-*/) {
258: String pair = (String) iter.nextToken();
259: int split = pair.indexOf('=');
260: if (split <= 0) {
261: throw new ValidationException("Invalid pair [" + pair
262: + "] in query string [" + q + "]");
263: } else {
264: String key = pair.substring(0, split);
265: String value = pair.substring(split + 1);
266: try {
267: key = URLDecoder.decode(key, "UTF-8");
268: value = URLDecoder.decode(value, "UTF-8");
269: } catch (UnsupportedEncodingException e) {
270: throw new ValidationException(
271: "Invalid encoding in [" + pair
272: + "] in query string [" + q + "]",
273: e);
274: }
275: toAddTo.setProperty(key, value);
276: }
277: }
278: }
279: }
|