/**
* 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;
}
}
}