You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by as...@apache.org on 2005/07/11 07:04:39 UTC
svn commit: r210069 - in
/webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc:
handler/HandlerChainImpl.java utils/ utils/ClassUtils.java
utils/StringUtils.java
Author: ashutosh
Date: Sun Jul 10 22:04:37 2005
New Revision: 210069
URL: http://svn.apache.org/viewcvs?rev=210069&view=rev
Log:
Some utility classes taken from Axis1.2
Added:
webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/
webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/ClassUtils.java
webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/StringUtils.java
Modified:
webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/handler/HandlerChainImpl.java
Modified: webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/handler/HandlerChainImpl.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/handler/HandlerChainImpl.java?rev=210069&r1=210068&r2=210069&view=diff
==============================================================================
--- webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/handler/HandlerChainImpl.java (original)
+++ webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/handler/HandlerChainImpl.java Sun Jul 10 22:04:37 2005
@@ -19,18 +19,20 @@
import org.apache.axis.jaxrpc.handler.soap.SOAPMessageContextImpl;
import org.apache.axis.jaxrpc.handler.MessageContextImpl;
+import org.apache.axis.jaxrpc.utils.ClassUtils;
+
public class HandlerChainImpl extends ArrayList implements HandlerChain {
private String[] roles;
private int falseIndex = -1;
- protected List handlerInfos = new ArrayList();
+ protected List<HandlerInfo> handlerInfos = new ArrayList<HandlerInfo>();
public static final String JAXRPC_METHOD_INFO = "jaxrpc.method.info";
private HandlerInfo getHandlerInfo(int index){
- return (HandlerInfo)handlerInfos.get(index);
+ return handlerInfos.get(index);
}
private Handler getHandlerInstance(int index) {
@@ -47,6 +49,10 @@
}
}
+ private void preInvoke(SOAPMessageContext msgContext){
+ // EMPTY FUNCTION FOR NOW, MAY USE LATER
+ }
+
private void postInvoke(SOAPMessageContext msgContext) {
SOAPMessage message = msgContext.getMessage();
ArrayList oldList = (ArrayList)msgContext.getProperty(JAXRPC_METHOD_INFO);
@@ -61,7 +67,7 @@
}
- public HandlerChainImpl(List handlerInfos){
+ public HandlerChainImpl(List<HandlerInfo> handlerInfos){
this.handlerInfos = handlerInfos;
for(int i = 0; i < handlerInfos.size(); i++){
add(newHandler(getHandlerInfo(i)));
@@ -98,9 +104,11 @@
return list;
}
- public boolean handleRequest(MessageContext context) throws JAXRPCException {
- SOAPMessageContextImpl actx = (SOAPMessageContextImpl)context;
+ public boolean handleRequest(MessageContext _context) throws JAXRPCException {
+ SOAPMessageContextImpl actx = (SOAPMessageContextImpl)_context;
actx.setRoles(getRoles());
+ SOAPMessageContext context = (SOAPMessageContext)_context;
+ preInvoke(context);
try {
for (int i = 0; i < size(); i++) {
Handler currentHandler = getHandlerInstance(i);
@@ -116,13 +124,14 @@
}
return true;
}finally {
- postInvoke(actx);
+ postInvoke(context);
}
}
public boolean handleResponse(MessageContext context)
throws JAXRPCException {
SOAPMessageContextImpl scontext = (SOAPMessageContextImpl)context;
+ preInvoke(scontext);
try {
int endIdx = size() - 1;
if (falseIndex != -1) {
@@ -141,6 +150,7 @@
public boolean handleFault(MessageContext _context) throws JAXRPCException {
SOAPMessageContextImpl context = (SOAPMessageContextImpl)_context;
+ preInvoke(context);
try {
int endIdx = size() - 1;
if (falseIndex != -1) {
Added: webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/ClassUtils.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/ClassUtils.java?rev=210069&view=auto
==============================================================================
--- webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/ClassUtils.java (added)
+++ webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/ClassUtils.java Sun Jul 10 22:04:37 2005
@@ -0,0 +1,304 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.axis.jaxrpc.utils;
+
+import java.io.InputStream;
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+/**
+ * Utility methods for Class Loading.
+ *
+ * @author Davanum Srinvas (dims@yahoo.com)
+ * @author Matthew Pocock (matthew_pocock@yahoo.co.uk)
+ */
+public final class ClassUtils {
+ /** default class loader */
+ private static ClassLoader defaultClassLoader
+ = ClassUtils.class.getClassLoader();
+
+ /** hash table of class loaders */
+ private static java.util.Hashtable classloaders = new java.util.Hashtable();
+
+ /**
+ * Set the default ClassLoader. If loader is null, the default loader is
+ * not changed.
+ *
+ * @param loader the new default ClassLoader
+ */
+ public static void setDefaultClassLoader(ClassLoader loader) {
+ if (loader != null)
+ defaultClassLoader = loader;
+ }
+
+ public static ClassLoader getDefaultClassLoader() {
+ return defaultClassLoader;
+ }
+
+ /**
+ * Set the ClassLoader associated with the given className. If either the
+ * class name or the loader are null, no action is performed.
+ *
+ * @param className the name of a class
+ * @param loader the ClassLoader for the class
+ */
+ public static void setClassLoader(String className, ClassLoader loader) {
+ if (className != null && loader != null)
+ classloaders.put(className, loader);
+ }
+
+ /**
+ * Obtain the ClassLoader (if any) associated with the given
+ * className.
+ *
+ * @param className the name of a class
+ * @return class loader
+ */
+ public static ClassLoader getClassLoader(String className) {
+ if (className == null) {
+ return null;
+ }
+ return (ClassLoader) classloaders.get(className);
+ }
+
+ /**
+ * Deregister the ClassLoader for a given className.
+ *
+ * @param className the name of a class
+ */
+ public static void removeClassLoader(String className) {
+ classloaders.remove(className);
+ }
+
+
+ /**
+ * Use this method instead of Class.forName
+ *
+ * @param className Class name
+ * @return java class
+ * @throws ClassNotFoundException if the class is not found
+ */
+ public static Class forName(String className)
+ throws ClassNotFoundException {
+ return loadClass(className);
+ }
+
+ /**
+ * Use this method instead of Class.forName (String className, boolean init, ClassLoader loader)
+ *
+ * @param _className Class name
+ * @param init initialize the class
+ * @param _loader class loader
+ * @return java class
+ *
+ * @throws ClassNotFoundException if the class is not found
+ */
+ public static Class forName(
+ String _className, boolean init, ClassLoader _loader)
+ throws ClassNotFoundException {
+
+ // Create final vars for doPrivileged block
+ final String className = _className;
+ final ClassLoader loader = _loader;
+ try {
+ // Get the class within a doPrivleged block
+ Object ret =
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ try {
+ return Class.forName(className, true, loader);
+ } catch (Throwable e) {
+ return e;
+ }
+ }
+ });
+ // If the class was located, return it. Otherwise throw exception
+ if (ret instanceof Class) {
+ return (Class) ret;
+ } else if (ret instanceof ClassNotFoundException) {
+ throw (ClassNotFoundException) ret;
+ } else {
+ throw new ClassNotFoundException(_className);
+ }
+ } catch (ClassNotFoundException cnfe) {
+ return loadClass(className);
+ }
+ }
+
+ /**
+ * Loads the class from the context class loader and then falls back to
+ * getDefaultClassLoader().forName
+ *
+ * @param _className Class name
+ * @return java class
+ * @throws ClassNotFoundException if the class is not found
+ */
+ private static Class loadClass(String _className)
+ throws ClassNotFoundException {
+ // Create final vars for doPrivileged block
+ final String className = _className;
+
+ // Get the class within a doPrivleged block
+ Object ret =
+ AccessController.doPrivileged(
+ new PrivilegedAction() {
+ public Object run() {
+ try {
+ // Check if the class is a registered class then
+ // use the classloader for that class.
+ ClassLoader classLoader = getClassLoader(className);
+ return Class.forName(className, true, classLoader);
+ } catch (ClassNotFoundException cnfe) {
+ }
+
+ try {
+ // Try the context class loader
+ ClassLoader classLoader =
+ Thread.currentThread().getContextClassLoader();
+ return Class.forName(className, true, classLoader);
+ } catch (ClassNotFoundException cnfe2) {
+ try {
+ // Try the classloader that loaded this class.
+ ClassLoader classLoader =
+ ClassUtils.class.getClassLoader();
+ return Class.forName(className, true, classLoader);
+ } catch (ClassNotFoundException cnfe3) {
+ // Try the default class loader.
+ try {
+ return defaultClassLoader.loadClass(
+ className);
+ } catch (Throwable e) {
+ // Still not found, return exception
+ return e;
+ }
+ }
+ }
+ }
+ });
+
+ // If the class was located, return it. Otherwise throw exception
+ if (ret instanceof Class) {
+ return (Class) ret;
+ } else if (ret instanceof ClassNotFoundException) {
+ throw (ClassNotFoundException) ret;
+ } else {
+ throw new ClassNotFoundException(_className);
+ }
+ }
+
+ /**
+ * Get an input stream from a named resource.
+ * Tries
+ * <ol>
+ * <li>the classloader that loaded "clazz" first,
+ * <li>the system classloader
+ * <li>the class "clazz" itself
+ * </ol>
+ * @param clazz class to use in the lookups
+ * @param resource resource string to look for
+ * @param checkThreadContextFirst check the thread context first?
+ * @return input stream if found, or null
+ */
+ public static InputStream getResourceAsStream(Class clazz, String resource, boolean checkThreadContextFirst) {
+ InputStream myInputStream = null;
+
+ if (checkThreadContextFirst &&
+ Thread.currentThread().getContextClassLoader() != null) {
+ // try the context class loader.
+ myInputStream =
+ Thread.currentThread().getContextClassLoader()
+ .getResourceAsStream(resource);
+ }
+ if (myInputStream == null) {
+ // if not found in context class loader fall back to default
+ myInputStream = getResourceAsStream(clazz, resource);
+ }
+ return myInputStream;
+ }
+
+ /**
+ * Get an input stream from a named resource.
+ * Tries
+ * <ol>
+ * <li>the classloader that loaded "clazz" first,
+ * <li>the system classloader
+ * <li>the class "clazz" itself
+ * </ol>
+ * @param clazz class to use in the lookups
+ * @param resource resource string to look for
+ * @return input stream if found, or null
+ */
+ public static InputStream getResourceAsStream(Class clazz, String resource) {
+ InputStream myInputStream = null;
+
+ if(clazz.getClassLoader()!=null) {
+ // Try the class loader that loaded this class.
+ myInputStream = clazz.getClassLoader().getResourceAsStream(resource);
+ } else {
+ // Try the system class loader.
+ myInputStream = ClassLoader.getSystemClassLoader().getResourceAsStream(resource);
+ }
+ if (myInputStream == null && Thread.currentThread().getContextClassLoader() != null) {
+ // try the context class loader.
+ myInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(resource);
+ }
+ if (myInputStream == null) {
+ // if not found in classpath fall back to default
+ myInputStream = clazz.getResourceAsStream(resource);
+ }
+ return myInputStream;
+ }
+
+ /**
+ * Creates a new ClassLoader from a classpath specification and a parent
+ * class loader.
+ * The classpath string will be split using the system path seperator
+ * character (e.g. : or ;), just as the java system-wide class path is
+ * processed.
+ *
+ * @param classpath the classpath String
+ * @param parent the parent ClassLoader, or null if the default is to be
+ * used
+ * @throws SecurityException if you don't have privilages to create
+ * class loaders
+ * @throws IllegalArgumentException if your classpath string is silly
+ */
+ public static ClassLoader createClassLoader(String classpath,
+ ClassLoader parent)
+ throws SecurityException
+ {
+ String[] names = StringUtils.split(classpath, System.getProperty("path.separator").charAt(0));
+
+ URL[] urls = new URL[names.length];
+ try {
+ for(int i = 0; i < urls.length; i++)
+ urls[i] = new File(names[i]).toURL();
+ }
+ catch (MalformedURLException e) {
+ // I don't think this is possible, so I'm throwing this as an
+ // un-checked exception
+ throw (IllegalArgumentException) new IllegalArgumentException(
+ "Unable to parse classpath: " + classpath);
+ }
+
+ return new URLClassLoader(urls, parent);
+ }
+}
Added: webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/StringUtils.java
URL: http://svn.apache.org/viewcvs/webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/StringUtils.java?rev=210069&view=auto
==============================================================================
--- webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/StringUtils.java (added)
+++ webservices/axis/trunk/archive/java/scratch/ashu_jaya_venkat/jaxws/src/org/apache/axis/jaxrpc/utils/StringUtils.java Sun Jul 10 22:04:37 2005
@@ -0,0 +1,454 @@
+/*
+ * Copyright 2001-2004 The Apache Software Foundation.
+ *
+ * Licensed 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 org.apache.axis.jaxrpc.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.io.Writer;
+import java.io.IOException;
+import java.io.StringWriter;
+
+public class StringUtils {
+ private StringUtils() {
+ }
+
+ /**
+ * An empty immutable <code>String</code> array.
+ */
+ public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+ /**
+ * Tests if this string starts with the specified prefix (Ignoring whitespaces)
+ * @param prefix
+ * @param string
+ * @return boolean
+ */
+ public static boolean startsWithIgnoreWhitespaces(String prefix, String string) {
+ int index1 = 0;
+ int index2 = 0;
+ int length1 = prefix.length();
+ int length2 = string.length();
+ char ch1 = ' ';
+ char ch2 = ' ';
+ while (index1 < length1 && index2 < length2) {
+ while (index1 < length1 && Character.isWhitespace(ch1 = prefix.charAt(index1))) {
+ index1++;
+ }
+ while (index2 < length2 && Character.isWhitespace(ch2 = string.charAt(index2))) {
+ index2++;
+ }
+ if (index1 == length1 && index2 == length2) {
+ return true;
+ }
+ if (ch1 != ch2) {
+ return false;
+ }
+ index1++;
+ index2++;
+ }
+ if(index1 < length1 && index2 >= length2)
+ return false;
+ return true;
+ }
+
+ /**
+ * <p>Splits the provided text into an array, separator specified.
+ * This is an alternative to using StringTokenizer.</p>
+ *
+ * <p>The separator is not included in the returned String array.
+ * Adjacent separators are treated as one separator.</p>
+ *
+ * <p>A <code>null</code> input String returns <code>null</code>.</p>
+ *
+ * <pre>
+ * StringUtils.split(null, *) = null
+ * StringUtils.split("", *) = []
+ * StringUtils.split("a.b.c", '.') = ["a", "b", "c"]
+ * StringUtils.split("a..b.c", '.') = ["a", "b", "c"]
+ * StringUtils.split("a:b:c", '.') = ["a:b:c"]
+ * StringUtils.split("a\tb\nc", null) = ["a", "b", "c"]
+ * StringUtils.split("a b c", ' ') = ["a", "b", "c"]
+ * </pre>
+ *
+ * @param str the String to parse, may be null
+ * @param separatorChar the character used as the delimiter,
+ * <code>null</code> splits on whitespace
+ * @return an array of parsed Strings, <code>null</code> if null String input
+ */
+ public static String[] split(String str, char separatorChar) {
+ if (str == null) {
+ return null;
+ }
+ int len = str.length();
+ if (len == 0) {
+ return EMPTY_STRING_ARRAY;
+ }
+ List list = new ArrayList();
+ int i = 0, start = 0;
+ boolean match = false;
+ while (i < len) {
+ if (str.charAt(i) == separatorChar) {
+ if (match) {
+ list.add(str.substring(start, i));
+ match = false;
+ }
+ start = ++i;
+ continue;
+ }
+ match = true;
+ i++;
+ }
+ if (match) {
+ list.add(str.substring(start, i));
+ }
+ return (String[]) list.toArray(new String[list.size()]);
+ }
+
+ // Empty checks
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Checks if a String is empty ("") or null.</p>
+ *
+ * <pre>
+ * StringUtils.isEmpty(null) = true
+ * StringUtils.isEmpty("") = true
+ * StringUtils.isEmpty(" ") = false
+ * StringUtils.isEmpty("bob") = false
+ * StringUtils.isEmpty(" bob ") = false
+ * </pre>
+ *
+ * <p>NOTE: This method changed in Lang version 2.0.
+ * It no longer trims the String.
+ * That functionality is available in isBlank().</p>
+ *
+ * @param str the String to check, may be null
+ * @return <code>true</code> if the String is empty or null
+ */
+ public static boolean isEmpty(String str) {
+ return (str == null || str.length() == 0);
+ }
+
+ // Stripping
+ //-----------------------------------------------------------------------
+ /**
+ * <p>Strips whitespace from the start and end of a String.</p>
+ *
+ * <p>This removes whitespace. Whitespace is defined by
+ * {@link Character#isWhitespace(char)}.</p>
+ *
+ * <p>A <code>null</code> input String returns <code>null</code>.</p>
+ *
+ * <pre>
+ * StringUtils.strip(null) = null
+ * StringUtils.strip("") = ""
+ * StringUtils.strip(" ") = ""
+ * StringUtils.strip("abc") = "abc"
+ * StringUtils.strip(" abc") = "abc"
+ * StringUtils.strip("abc ") = "abc"
+ * StringUtils.strip(" abc ") = "abc"
+ * StringUtils.strip(" ab c ") = "ab c"
+ * </pre>
+ *
+ * @param str the String to remove whitespace from, may be null
+ * @return the stripped String, <code>null</code> if null String input
+ */
+ public static String strip(String str) {
+ return strip(str, null);
+ }
+
+ /**
+ * <p>Strips any of a set of characters from the start and end of a String.
+ * This is similar to {@link String#trim()} but allows the characters
+ * to be stripped to be controlled.</p>
+ *
+ * <p>A <code>null</code> input String returns <code>null</code>.
+ * An empty string ("") input returns the empty string.</p>
+ *
+ * <p>If the stripChars String is <code>null</code>, whitespace is
+ * stripped as defined by {@link Character#isWhitespace(char)}.
+ * Alternatively use {@link #strip(String)}.</p>
+ *
+ * <pre>
+ * StringUtils.strip(null, *) = null
+ * StringUtils.strip("", *) = ""
+ * StringUtils.strip("abc", null) = "abc"
+ * StringUtils.strip(" abc", null) = "abc"
+ * StringUtils.strip("abc ", null) = "abc"
+ * StringUtils.strip(" abc ", null) = "abc"
+ * StringUtils.strip(" abcyx", "xyz") = " abc"
+ * </pre>
+ *
+ * @param str the String to remove characters from, may be null
+ * @param stripChars the characters to remove, null treated as whitespace
+ * @return the stripped String, <code>null</code> if null String input
+ */
+ public static String strip(String str, String stripChars) {
+ if (str == null) {
+ return str;
+ }
+ int len = str.length();
+ if (len == 0) {
+ return str;
+ }
+ int start = getStripStart(str, stripChars);
+ if (start == len) {
+ return "";
+ }
+ int end = getStripEnd(str, stripChars);
+ return (start == 0 && end == len) ? str : str.substring(start, end);
+ }
+
+ /**
+ * <p>Strips any of a set of characters from the start of a String.</p>
+ *
+ * <p>A <code>null</code> input String returns <code>null</code>.
+ * An empty string ("") input returns the empty string.</p>
+ *
+ * <p>If the stripChars String is <code>null</code>, whitespace is
+ * stripped as defined by {@link Character#isWhitespace(char)}.</p>
+ *
+ * <pre>
+ * StringUtils.stripStart(null, *) = null
+ * StringUtils.stripStart("", *) = ""
+ * StringUtils.stripStart("abc", "") = "abc"
+ * StringUtils.stripStart("abc", null) = "abc"
+ * StringUtils.stripStart(" abc", null) = "abc"
+ * StringUtils.stripStart("abc ", null) = "abc "
+ * StringUtils.stripStart(" abc ", null) = "abc "
+ * StringUtils.stripStart("yxabc ", "xyz") = "abc "
+ * </pre>
+ *
+ * @param str the String to remove characters from, may be null
+ * @param stripChars the characters to remove, null treated as whitespace
+ * @return the stripped String, <code>null</code> if null String input
+ */
+ public static String stripStart(String str, String stripChars) {
+ int start = getStripStart(str, stripChars);
+ return (start <= 0) ? str : str.substring(start);
+ }
+
+ private static int getStripStart(String str, String stripChars) {
+ int strLen;
+ if (str == null || (strLen = str.length()) == 0) {
+ return -1;
+ }
+ int start = 0;
+ if (stripChars == null) {
+ while ((start != strLen) && Character.isWhitespace(str.charAt(start))) {
+ start++;
+ }
+ } else if (stripChars.length() == 0) {
+ return start;
+ } else {
+ while ((start != strLen) && (stripChars.indexOf(str.charAt(start)) != -1)) {
+ start++;
+ }
+ }
+ return start;
+ }
+
+ /**
+ * <p>Strips any of a set of characters from the end of a String.</p>
+ *
+ * <p>A <code>null</code> input String returns <code>null</code>.
+ * An empty string ("") input returns the empty string.</p>
+ *
+ * <p>If the stripChars String is <code>null</code>, whitespace is
+ * stripped as defined by {@link Character#isWhitespace(char)}.</p>
+ *
+ * <pre>
+ * StringUtils.stripEnd(null, *) = null
+ * StringUtils.stripEnd("", *) = ""
+ * StringUtils.stripEnd("abc", "") = "abc"
+ * StringUtils.stripEnd("abc", null) = "abc"
+ * StringUtils.stripEnd(" abc", null) = " abc"
+ * StringUtils.stripEnd("abc ", null) = "abc"
+ * StringUtils.stripEnd(" abc ", null) = " abc"
+ * StringUtils.stripEnd(" abcyx", "xyz") = " abc"
+ * </pre>
+ *
+ * @param str the String to remove characters from, may be null
+ * @param stripChars the characters to remove, null treated as whitespace
+ * @return the stripped String, <code>null</code> if null String input
+ */
+ public static String stripEnd(String str, String stripChars) {
+ int end = getStripEnd(str, stripChars);
+ return (end < 0) ? str : str.substring(0, end);
+ }
+
+ private static int getStripEnd(String str, String stripChars) {
+ int end;
+ if (str == null || (end = str.length()) == 0) {
+ return -1;
+ }
+ if (stripChars == null) {
+ while ((end != 0) && Character.isWhitespace(str.charAt(end - 1))) {
+ end--;
+ }
+ } else if (stripChars.length() == 0) {
+ return end;
+ } else {
+ while ((end != 0) && (stripChars.indexOf(str.charAt(end - 1)) != -1)) {
+ end--;
+ }
+ }
+ return end;
+ }
+
+ /**
+ * write the escaped version of a given string
+ *
+ * @param str string to be encoded
+ * @return a new escaped <code>String</code>, <code>null</code> if null string input
+ */
+ public static String escapeNumericChar(String str) {
+ if (str == null) {
+ return null;
+ }
+ try {
+ StringWriter writer = new StringWriter(str.length());
+ escapeNumericChar(writer, str);
+ return writer.toString();
+ } catch (IOException ioe) {
+ // this should never ever happen while writing to a StringWriter
+ ioe.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * write the escaped version of a given string
+ *
+ * @param out writer to write this string to
+ * @param str string to be encoded
+ */
+ public static void escapeNumericChar(Writer out, String str)
+ throws IOException {
+ if (str == null) {
+ return;
+ }
+ int length = str.length();
+ char character;
+ for (int i = 0; i < length; i++) {
+ character = str.charAt( i );
+ if (character > 0x7F) {
+ out.write("&#x");
+ out.write(Integer.toHexString(character).toUpperCase());
+ out.write(";");
+ } else {
+ out.write(character);
+ }
+ }
+ }
+
+ /**
+ * <p>Unescapes numeric character referencs found in the <code>String</code>.</p>
+ *
+ * <p>For example, it will return a unicode string which means the specified numeric
+ * character references looks like "ようこそ".</p>
+ *
+ * @param str the <code>String</code> to unescape, may be null
+ * @return a new unescaped <code>String</code>, <code>null</code> if null string input
+ */
+ public static String unescapeNumericChar(String str) {
+ if (str == null) {
+ return null;
+ }
+ try {
+ StringWriter writer = new StringWriter(str.length());
+ unescapeNumericChar(writer, str);
+ return writer.toString();
+ } catch (IOException ioe) {
+ // this should never ever happen while writing to a StringWriter
+ ioe.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * <p>Unescapes numeric character references found in the <code>String</code> to a
+ * <code>Writer</code>.</p>
+ *
+ * <p>For example, it will return a unicode string which means the specified numeric
+ * character references looks like "ようこそ".</p>
+ *
+ * <p>A <code>null</code> string input has no effect.</p>
+ *
+ * @param out the <code>Writer</code> used to output unescaped characters
+ * @param str the <code>String</code> to unescape, may be null
+ * @throws IllegalArgumentException if the Writer is <code>null</code>
+ * @throws java.io.IOException if error occurs on underlying Writer
+ */
+ public static void unescapeNumericChar(Writer out, String str) throws IOException {
+ if (out == null) {
+ throw new IllegalArgumentException("The Writer must not be null");
+ }
+ if (str == null) {
+ return;
+ }
+
+ int sz = str.length();
+ StringBuffer unicode = new StringBuffer(4);
+ StringBuffer escapes = new StringBuffer(3);
+ boolean inUnicode = false;
+
+ for (int i = 0; i < sz; i++) {
+ char ch = str.charAt(i);
+ if (inUnicode) {
+ // if in unicode, then we're reading unicode
+ // values in somehow
+ unicode.append(ch);
+ if (unicode.length() == 4) {
+ // unicode now contains the four hex digits
+ // which represents our unicode character
+ try {
+ int value = Integer.parseInt(unicode.toString(), 16);
+ out.write((char) value);
+ unicode.setLength(0);
+ // need to skip the delimiter - ';'
+ i = i + 1;
+ inUnicode = false;
+ } catch (NumberFormatException nfe) {
+ throw new RuntimeException(nfe);
+ }
+ }
+ continue;
+ } else if (ch=='&') {
+ // Start of the escape sequence ...
+ // At least, the numeric character references require 8 bytes to
+ // describe a Unicode character like as""
+ if (i+7 <= sz) {
+ escapes.append(ch);
+ escapes.append(str.charAt(i+1));
+ escapes.append(str.charAt(i+2));
+ if (escapes.toString().equals("&#x") && str.charAt(i+7)==';') {
+ inUnicode = true;
+ } else {
+ out.write(escapes.toString());
+ }
+ escapes.setLength(0);
+ // need to skip the escaping chars - '&#x'
+ i = i + 2;
+ } else {
+ out.write(ch);
+ }
+ continue;
+ }
+ out.write(ch);
+ }
+ }
+}