| /* |
| * 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 flex.messaging.util; |
| |
| import flex.messaging.MessageException; |
| import flex.messaging.FlexContext; |
| |
| import java.net.InetAddress; |
| import java.net.NetworkInterface; |
| import java.util.ArrayList; |
| import java.util.Enumeration; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Methods for replacing tokens in config files |
| * {context.root}, {context-root}, {server.name}, {server-name}, {server.port}, {server-port}. |
| */ |
| public class SettingsReplaceUtil { |
| private static final int TOKEN_NOT_SUPPORTED = 10129; |
| private static final int TOKEN_NOT_SUPPORTED_ANY = 10130; |
| private static final int PARSE_ERROR_DYNAMIC_URL = 10131; |
| |
| public static final String SLASH_CONTEXT_PATH_TOKEN = "/{context.root}"; |
| public static final String CONTEXT_PATH_TOKEN = "{context.root}"; |
| public static final String CONTEXT_PATH_ALT_TOKEN = "{context-root}"; |
| public static final String SERVER_NAME_TOKEN = "{server.name}"; |
| public static final String SERVER_NAME_ALT_TOKEN = "{server-name}"; |
| public static final String SERVER_PORT_TOKEN = "{server.port}"; |
| public static final String SERVER_PORT_ALT_TOKEN = "{server-port}"; |
| |
| /** |
| * Replace {context.root} in the url string. |
| * |
| * @param url the url string |
| * @param contextPath the context path |
| * @return String the url string after replacement |
| */ |
| public static String replaceContextPath(String url, String contextPath) { |
| String token = CONTEXT_PATH_TOKEN; |
| int contextIndex = url.indexOf(CONTEXT_PATH_ALT_TOKEN); |
| if (contextIndex != -1) { |
| token = CONTEXT_PATH_ALT_TOKEN; |
| url = StringUtils.substitute(url, CONTEXT_PATH_ALT_TOKEN, CONTEXT_PATH_TOKEN); |
| } |
| contextIndex = url.indexOf(CONTEXT_PATH_TOKEN); |
| |
| if ((contextPath == null) && (contextIndex != -1)) { |
| MessageException me = new MessageException(); |
| if (FlexContext.getHttpRequest() == null) |
| me.setMessage(TOKEN_NOT_SUPPORTED, "0", new Object[]{token}); |
| else |
| me.setMessage(TOKEN_NOT_SUPPORTED, new Object[]{token}); |
| throw me; |
| } else if (contextPath != null) { |
| if (contextIndex == 0) { |
| url = contextPath + url.substring(CONTEXT_PATH_TOKEN.length()); |
| } else if (contextIndex > 0) { |
| // Avoid adding //contextPath to URLs that have a /{context.root} pattern |
| if (url.indexOf(SLASH_CONTEXT_PATH_TOKEN) != -1) { |
| url = StringUtils.substitute(url, SLASH_CONTEXT_PATH_TOKEN, contextPath); |
| } else { |
| url = StringUtils.substitute(url, CONTEXT_PATH_TOKEN, contextPath); |
| } |
| } |
| } |
| |
| return url; |
| } |
| |
| public static String replaceAllTokensGivenServerName(String url, String contextPath, String serverName, |
| String serverPort, String serverProtocol) { |
| if (url.startsWith("/")) { |
| url = serverProtocol + "://{server.name}:{server.port}" + url; |
| } |
| url = SettingsReplaceUtil.replaceContextPath(url, contextPath); |
| |
| String token = SERVER_NAME_TOKEN; |
| int serverNameIndex = url.indexOf(SERVER_NAME_ALT_TOKEN); |
| if (serverNameIndex != -1) { |
| token = SERVER_NAME_ALT_TOKEN; |
| url = StringUtils.substitute(url, SERVER_NAME_ALT_TOKEN, SERVER_NAME_TOKEN); |
| } |
| |
| serverNameIndex = url.indexOf(SERVER_NAME_TOKEN); |
| if ((serverName == null) && (serverNameIndex != -1)) { |
| MessageException me = new MessageException(); |
| me.setMessage(TOKEN_NOT_SUPPORTED, new Object[]{token}); |
| throw me; |
| } else if ((serverName != null) && (serverNameIndex != -1)) { |
| url = StringUtils.substitute(url, SERVER_NAME_TOKEN, serverName); |
| } |
| |
| token = SERVER_PORT_TOKEN; |
| int serverPortIndex = url.indexOf(SERVER_PORT_ALT_TOKEN); |
| if (serverPortIndex != -1) { |
| token = SERVER_PORT_ALT_TOKEN; |
| url = StringUtils.substitute(url, SERVER_PORT_ALT_TOKEN, SERVER_PORT_TOKEN); |
| } |
| |
| serverPortIndex = url.indexOf(SERVER_PORT_TOKEN); |
| if ((serverPort == null) && (serverPortIndex != -1)) { |
| MessageException me = new MessageException(); |
| me.setMessage(TOKEN_NOT_SUPPORTED, new Object[]{token}); |
| throw me; |
| } else if ((serverPort != null) && (serverPortIndex != -1)) { |
| url = StringUtils.substitute(url, SERVER_PORT_TOKEN, serverPort); |
| } |
| |
| return updateIPv6(url); |
| } |
| |
| /** |
| * Replace all tokens in the urls. |
| * |
| * @param urls a list of urls |
| * @param contextPath the context path |
| * @return Set a set of urls after replacement |
| */ |
| public static Set replaceAllTokensCalculateServerName(List urls, String contextPath) { |
| List contextParsedUrls = new ArrayList(urls.size()); |
| Set newURLs = new HashSet(urls.size()); |
| |
| // first replace context path |
| for (int i = 0; i < urls.size(); i++) { |
| String url = (String) urls.get(i); |
| url = url.toLowerCase().trim(); |
| url = SettingsReplaceUtil.replaceContextPath(url, contextPath); |
| contextParsedUrls.add(url); |
| |
| } |
| // then replace {server.name} |
| replaceServerNameWithLocalHost(contextParsedUrls, newURLs); |
| |
| return newURLs; |
| } |
| |
| |
| /** |
| * Replace {server.name} a horribly complicated way. This is needed to support relative |
| * URLs. I would like for us to rethink this someday and find a better way to do this |
| * |
| * @param urls the list of urls to replace |
| * @param newURLs the set of new urls |
| */ |
| public static void replaceServerNameWithLocalHost(List urls, Set newURLs) { |
| for (Iterator iterator = urls.iterator(); iterator.hasNext(); ) { |
| String url = (String) iterator.next(); |
| url = url.toLowerCase().trim(); |
| |
| String token = SERVER_PORT_TOKEN; |
| int serverPortIndex = url.indexOf(SERVER_PORT_ALT_TOKEN); |
| if (serverPortIndex != -1) { |
| token = SERVER_PORT_ALT_TOKEN; |
| url = StringUtils.substitute(url, SERVER_PORT_ALT_TOKEN, SERVER_PORT_TOKEN); |
| } |
| |
| serverPortIndex = url.indexOf(SERVER_PORT_TOKEN); |
| if (serverPortIndex != -1) { |
| MessageException me = new MessageException(); |
| me.setMessage(TOKEN_NOT_SUPPORTED_ANY, new Object[]{token}); |
| throw me; |
| } |
| |
| if (url.indexOf(SERVER_NAME_ALT_TOKEN) != 0) { |
| StringUtils.substitute(url, SERVER_NAME_ALT_TOKEN, SERVER_NAME_TOKEN); |
| } |
| |
| if (url.indexOf(SERVER_NAME_TOKEN) != 0) { |
| |
| try { |
| addLocalServerURL(url, "localhost", newURLs); |
| addLocalServerURL(url, "127.0.0.1", newURLs); |
| addLocalServerURL(url, "[::1]", newURLs); // for IPv6 |
| |
| InetAddress local = InetAddress.getLocalHost(); |
| addInetAddress(local, url, newURLs); |
| |
| // if we're using JDK 1.4 or higher, we use NetworkInterface to get the list of hostnames |
| // and IP addresses. |
| Enumeration e = NetworkInterface.getNetworkInterfaces(); |
| while (e.hasMoreElements()) { |
| NetworkInterface address = (NetworkInterface) e.nextElement(); |
| Enumeration e2 = (Enumeration) address.getInetAddresses(); |
| while (e2.hasMoreElements()) { |
| local = (InetAddress) e2.nextElement(); |
| addInetAddress(local, url, newURLs); |
| } |
| } |
| } catch (Exception e) { |
| MessageException me = new MessageException(); |
| me.setMessage(PARSE_ERROR_DYNAMIC_URL); |
| throw me; |
| } |
| } else { |
| addParsedURL(url, newURLs); |
| } |
| } |
| } |
| |
| private static void addInetAddress(InetAddress local, String url, Set newURLs) throws Exception { |
| String localHostAddress = local.getHostAddress(); |
| if (localHostAddress != null) { |
| addLocalServerURL(url, localHostAddress, newURLs); |
| } |
| |
| String localHostName = local.getHostName(); |
| if (localHostName != null) { |
| addLocalServerURL(url, localHostName, newURLs); |
| |
| InetAddress[] addrs = InetAddress.getAllByName(localHostName); |
| for (int i = 0; i < addrs.length; i++) { |
| InetAddress addr = addrs[i]; |
| String hostName = addr.getHostName(); |
| if (!hostName.equals(localHostName)) { |
| addLocalServerURL(url, hostName, newURLs); |
| } |
| String hostAddress = addr.getHostAddress(); |
| if (!hostAddress.equals(localHostAddress)) { |
| addLocalServerURL(url, hostAddress, newURLs); |
| } |
| } |
| } |
| } |
| |
| private static void addLocalServerURL(String url, String sub, Set newURLs) { |
| String toSub = null; |
| |
| // if ipv6, then add square brackets |
| if (sub.indexOf(":") != -1) { |
| StringBuffer ipv6Sub = new StringBuffer("["); |
| ipv6Sub.append(sub); |
| ipv6Sub.append("]"); |
| toSub = ipv6Sub.toString(); |
| } else { |
| toSub = sub; |
| } |
| |
| String newUrl = StringUtils.substitute(url, SERVER_NAME_TOKEN, toSub); |
| addParsedURL(newUrl, newURLs); |
| } |
| |
| private static void addParsedURL(String url, Set newURLs) { |
| if (!newURLs.contains(url)) { |
| newURLs.add(updateIPv6(url)); |
| } |
| } |
| |
| /** |
| * Update IPv6 IP address. |
| * |
| * @param src the source IP address string |
| * @return String the updated IP address string |
| */ |
| public static String updateIPv6(String src) { |
| // if the ip address has "[" and "]" then it's IPv6, check that it's long form as well |
| if ((src != null) && (src.indexOf('[') != -1) && (src.indexOf(']') != -1)) { |
| // then, it's IPv6 and remove the square brackets and update to long form if required |
| int start = src.indexOf('['); |
| int end = src.indexOf(']'); |
| |
| StringBuffer updated = new StringBuffer(src.substring(0, start + 1)); |
| updated.append(updateToLongForm(src.substring(start + 1, end))); |
| updated.append(src.substring(end)); |
| |
| return updated.toString(); |
| } else { |
| return src; |
| } |
| } |
| |
| protected static String updateToLongForm(String src) { |
| // Let's see if the short form is in use. |
| int numberOfTokens = 0; |
| int doubleColonIndex = src.indexOf("::", 0); |
| if (doubleColonIndex != -1) { |
| String[] hexTokens = src.split("\\:"); |
| for (int i = 0; i < hexTokens.length; i++) { |
| if (!hexTokens[i].equals("")) |
| numberOfTokens++; |
| } |
| |
| // Replace missing zeros |
| int numberOfMissingZeros = 8 - numberOfTokens; |
| if (numberOfMissingZeros > 0) { |
| String replacement = ""; |
| if (!src.startsWith("::")) |
| replacement = ":"; |
| while (numberOfMissingZeros-- > 0) |
| replacement += "0:"; |
| src = src.replaceFirst("\\::", replacement); |
| } |
| } |
| |
| return src; |
| } |
| |
| } |