| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package flash.util; |
| |
| import java.util.Iterator; |
| import java.util.LinkedHashMap; |
| import java.util.Map; |
| import java.util.StringTokenizer; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| |
| public class URLHelper |
| { |
| private static Pattern URL_PATTERN = Pattern.compile("^(.*?)(\\?.*?)?(#.*)?$"); //$NON-NLS-1$ |
| |
| /** |
| * Everything before the "query" part of the URL. E.g. for |
| * "http://www.example.com/file?firstname=Bob&lastname=Smith#foo" |
| * this would be "http://www.example.com/file". |
| */ |
| private String m_everythingBeforeQuery; |
| |
| /** |
| * The "query" in a URL is the "?firstname=Bob&lastname=Smith" part. |
| * m_query contains the query (including "?"), or contains "" if the |
| * URL has no query. Never null. |
| */ |
| private String m_query; |
| |
| /** |
| * The "fragment" in a URL is the "#foo" part at the end of a URL. |
| * m_fragment contains the fragment (including "#"), or contains "" if the |
| * URL has no fragment. Never null. |
| */ |
| private String m_fragment; |
| |
| public URLHelper(String url) |
| { |
| Matcher matcher = URL_PATTERN.matcher(url); |
| |
| if (!matcher.matches()) |
| throw new IllegalArgumentException(url); |
| |
| if (matcher.matches()) |
| { |
| m_everythingBeforeQuery = matcher.group(1); |
| |
| m_query = matcher.group(2); |
| if (m_query == null) m_query = ""; //$NON-NLS-1$ |
| |
| m_fragment = matcher.group(3); |
| if (m_fragment == null) m_fragment = ""; //$NON-NLS-1$ |
| } |
| } |
| |
| /** |
| * Everything before the "query" part of the URL. E.g. for |
| * "http://www.example.com/file?firstname=Bob&lastname=Smith#foo" |
| * this would be "http://www.example.com/file". |
| */ |
| public String getEverythingBeforeQuery() |
| { |
| return m_everythingBeforeQuery; |
| } |
| |
| public void setEverythingBeforeQuery(String everythingBeforeQuery) |
| { |
| assertValidArguments(everythingBeforeQuery, getQuery(), getFragment()); |
| m_everythingBeforeQuery = everythingBeforeQuery; |
| } |
| |
| /** |
| * Rturns the "query" portion of the URL, e.g. the |
| * "?firstname=Bob&lastname=Smith" part. m_query contains the query |
| * (including "?"), or "" if the URL has no query. Never null. |
| */ |
| public String getQuery() |
| { |
| return m_query; |
| } |
| |
| /** |
| * Sets the "query" portion of the URL. This must be either the |
| * empty string or a string that begins with "?". |
| */ |
| public void setQuery(String query) |
| { |
| // if there is a query, make sure it starts with "?" |
| if (query.length() > 0 && query.charAt(0) != '?') |
| query = "?" + query; //$NON-NLS-1$ |
| |
| assertValidArguments(getEverythingBeforeQuery(), query, getFragment()); |
| |
| m_query = query; |
| } |
| |
| /** |
| * Returns the "fragment" portion of the URL, e.g. the "#foo" part, or |
| * "" if the URL has no fragment. Never null. |
| */ |
| public String getFragment() |
| { |
| return m_fragment; |
| } |
| |
| /** |
| * Sets the "fragment" portion of the URL. This must be either the |
| * empty string or a string that begins with "#". |
| * @param fragment |
| */ |
| public void setFragment(String fragment) |
| { |
| // if there is a fragment, make sure it starts with "#" |
| if (fragment.length() > 0 && fragment.charAt(0) != '#') |
| fragment = "#" + fragment; //$NON-NLS-1$ |
| |
| assertValidArguments(getEverythingBeforeQuery(), getQuery(), fragment); |
| m_fragment = fragment; |
| } |
| |
| private static void assertValidArguments(String everythingBeforeQuery, String query, String fragment) |
| { |
| assert areArgumentsValid(everythingBeforeQuery, query, fragment); |
| } |
| |
| /** |
| * This will test for various error conditions, e.g. a query string that |
| * contains "#" or has incorrect contents. |
| */ |
| private static boolean areArgumentsValid(String everythingBeforeQuery, String query, String fragment) |
| { |
| if (everythingBeforeQuery == null || query == null || fragment == null) |
| return false; |
| |
| URLHelper newHelper = new URLHelper(everythingBeforeQuery + query + fragment); |
| if (!newHelper.getEverythingBeforeQuery().equals(everythingBeforeQuery) || |
| !newHelper.getQuery().equals(query) || |
| !newHelper.getFragment().equals(fragment)) |
| { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| /** |
| * Returns the entire URL. |
| */ |
| public String getURL() |
| { |
| return m_everythingBeforeQuery + m_query + m_fragment; |
| } |
| |
| /** |
| * Returns the query portion of the URL, broken up into individual key/value |
| * pairs. Does NOT unescape the keys and values. |
| */ |
| public LinkedHashMap<String, String> getParameterMap() |
| { |
| LinkedHashMap<String, String> map; |
| |
| StringTokenizer tokens = new StringTokenizer(getQuery(), "?&"); //$NON-NLS-1$ |
| // multiply by 2 to create a sufficiently large HashMap |
| map = new LinkedHashMap<String, String>(tokens.countTokens() * 2); |
| |
| while (tokens.hasMoreElements()) |
| { |
| String nameValuePair = tokens.nextToken(); |
| String name = nameValuePair; |
| String value = ""; //$NON-NLS-1$ |
| int equalsIndex = nameValuePair.indexOf('='); |
| if (equalsIndex != -1) |
| { |
| name = nameValuePair.substring(0, equalsIndex); |
| if (name.length() > 0) |
| { |
| value = nameValuePair.substring(equalsIndex + 1); |
| } |
| } |
| map.put(name, value); |
| } |
| |
| return map; |
| } |
| |
| /** |
| * Sets the query portion of the URL. |
| * |
| * @param parameterMap |
| * a key/value mapping; these must already be escaped! |
| */ |
| public void setParameterMap(Map<String,String> parameterMap) |
| { |
| if ((parameterMap != null) && (!parameterMap.isEmpty())) |
| { |
| StringBuilder queryString = new StringBuilder(); |
| |
| Iterator<Map.Entry<String,String>> it = parameterMap.entrySet().iterator(); |
| while (it.hasNext()) |
| { |
| Map.Entry<String,String> entry = it.next(); |
| String name = (String) entry.getKey(); |
| String value = String.valueOf(entry.getValue()); |
| queryString.append(name); |
| if ((value != null) && (!value.equals(""))) //$NON-NLS-1$ |
| { |
| queryString.append('='); |
| queryString.append(value); |
| } |
| if (it.hasNext()) |
| { |
| queryString.append('&'); |
| } |
| } |
| |
| setQuery(queryString.toString()); |
| } else |
| { |
| setQuery(""); //$NON-NLS-1$ |
| } |
| } |
| |
| // shortcut for converting spaces to %20 in URIs |
| public static String escapeSpace(String uri) |
| { |
| return escapeCharacter(uri, ' ', "%20"); //$NON-NLS-1$ |
| } |
| |
| /** |
| * Locates characters 'c' in the scheme specific portion of a URI and |
| * translates them into 'to' |
| */ |
| public static String escapeCharacter(String uri, char c, String to) |
| { |
| StringBuilder sb = new StringBuilder(); |
| |
| int size = uri.length(); |
| int at = uri.indexOf(':'); |
| int lastAt = 0; |
| |
| // skip the scheme |
| if (at > -1) |
| { |
| for(int i=0; i<=at; i++) |
| sb.append(uri.charAt(i)); |
| lastAt = ++at; |
| } |
| |
| // while we have 'c's in uri |
| while( (at = uri.indexOf(c, at)) > -1) |
| { |
| // original portion |
| for(int i=lastAt; i<at; i++) |
| sb.append(uri.charAt(i)); |
| |
| // conversion |
| sb.append(to); |
| lastAt = ++at; // advance to char after conversion |
| } |
| |
| if (lastAt < size) |
| { |
| for(int i=lastAt; i<size; i++) |
| sb.append(uri.charAt(i)); |
| } |
| return sb.toString(); |
| } |
| } |