/** * Copyright (c) 2005-2006 Aptana, Inc. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html. If redistributing this code, * this entire header must remain intact. */ package org.radrails.rails.internal.ui.browser; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; /** * URL Parser for custom Eclipse URLs * * @author Kevin Sawicki */ public class URLParser { private boolean hasProtocol = false; private boolean isIntroUrl = false; private URL url_inst; /** * Constructor that gets the URL to parse. * * @param url */ public URLParser(String url) { // create a URL instance, and parser it for parameters. parseUrl(url); } private void parseUrl(String url) { if (url == null) { return; } url_inst = null; try { url_inst = new URL(url); } catch (MalformedURLException e) { // not a valid URL. set state. return; } if (url_inst.getProtocol() != null) { // URL has some valid protocol. Check to see if it is an intro url. hasProtocol = true; isIntroUrl = isIntroUrl(url_inst); return; } // not an Intro URL. do nothing. return; } /** * @return Returns the hasProtocol. */ public boolean hasProtocol() { return hasProtocol; } /** * @return Returns the isIntroUrl. */ public boolean hasIntroUrl() { return isIntroUrl; } /** * @return Returns the currebt url Protocol. */ public String getProtocol() { return url_inst.getProtocol(); } /** * @return Returns the currebt url Protocol. */ public String getHost() { return url_inst.getHost(); } /** * Checks to see if tha passed URL is an Intro URL. An intro URL is an http URL that has the intro plugin id as a * host. eg: "http://org.eclipse.ui.intro/test". * * @param url * @return true if url is an intro URL. */ private boolean isIntroUrl(URL url) { if (!url.getProtocol().equalsIgnoreCase(CoreURL.INTRO_PROTOCOL)) { // quick exit. If it is not http, url is not an Intro url. return false; } if (url.getHost().equalsIgnoreCase(CoreURL.INTRO_HOST_ID)) { return true; } return false; } /** * @return Returns the introURL. Will be null if the parsed URL is not an Intro URL. */ public CoreURL getIntroURL() { CoreURL introURL = null; if (isIntroUrl) { // valid intro URL. Extract the action and parameters. String action = getPathAsAction(url_inst); Properties parameters = getQueryParameters(url_inst); // class instance vars are already populated by now. introURL = new CoreURL(action, parameters); } return introURL; } /** * Retruns the path attribute of the passed URL, stripped out of the leading "/". Returns null if the url does not * have a path. * * @param url * @return - action */ private String getPathAsAction(URL url) { // get possible action. String action = url.getPath(); // remove leading "/" from path. if (action != null) { action = action.substring(1); } return action; } /** * Retruns the Query part of the URL as an instance of a Properties class. * * @param url * @return - properties */ public Properties getQueryParameters(URL url) { // parser all query parameters. Properties properties = new Properties(); String query = url.getQuery(); if (query == null) { // we do not have any parameters in this URL, return an empty // Properties instance. return properties; } // now extract the key/value pairs from the query. String[] params = query.split("&"); //$NON-NLS-1$ for (int i = 0; i < params.length; i++) { // for every parameter, ie: key=value pair, create a property // entry. we know we have the key as the first string in the array, // and the value as the second array. String[] keyValuePair = params[i].split("="); //$NON-NLS-1$ if (keyValuePair.length != 2) { continue; } String key = urlDecode(keyValuePair[0]); if (key == null) { continue; } String value = urlDecode(keyValuePair[1]); if (value == null) { continue; } properties.setProperty(key, value); } return properties; } /* * Note: This was copied and adapted from org.eclipse.help.internal.util.URLCoder */ private static String urlDecode(String encodedURL) { int len = encodedURL.length(); ByteArrayOutputStream os = new ByteArrayOutputStream(len); try { for (int i = 0; i < len;) { switch (encodedURL.charAt(i)) { case '%': if (len >= i + 3) { os.write(Integer.parseInt(encodedURL.substring(i + 1, i + 3), 16)); } i += 3; break; case '+': // exception from standard os.write(' '); i++; break; default: os.write(encodedURL.charAt(i++)); break; } } return new String(os.toByteArray(), "UTF8"); //$NON-NLS-1$ } catch (UnsupportedEncodingException ex) { return null; } } }