Added:
mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/StringUtilities.java
URL:
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/StringUtilities.java?rev=685389&view=auto
==============================================================================
---
mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/StringUtilities.java
(added)
+++
mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/StringUtilities.java
Tue Aug 12 17:05:41 2008
@@ -0,0 +1,313 @@
+/*
+ * 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 org.apache.mina.proxy.utils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.security.sasl.AuthenticationException;
+import javax.security.sasl.SaslException;
+
+/**
+ * StringUtilities.java - Various methods to handle strings.
+ * Note: Some code has been borrowed from <a
href="http://tedorg.free.fr/en/projects.php">Mailster </a>
+ *
+ * @author <a href="mailto:[EMAIL PROTECTED]">Edouard De Oliveira</a>
+ * @version $Id: $
+ */
+public class StringUtilities {
+
+ /**
+ * Returns the value of a directive from the map. If mandatory is true and
the value is null,
+ * then it throws a [EMAIL PROTECTED] AuthenticationException}.
+ */
+ public static String getDirectiveValue(
+ HashMap<String, String> directivesMap, String directive,
+ boolean mandatory) throws AuthenticationException {
+ String value = directivesMap.get(directive);
+ if (value == null) {
+ if (mandatory) {
+ throw new AuthenticationException("\"" + directive
+ + "\" mandatory directive is missing");
+ } else {
+ return "";
+ }
+ }
+
+ return value;
+ }
+
+ /**
+ * Copy the directive to the [EMAIL PROTECTED] StringBuilder} if not null.
+ */
+ public static String copyDirective(HashMap<String, String> directives,
+ StringBuilder sb, String directive) {
+ String directiveValue = directives.get(directive);
+ if (directiveValue != null) {
+ sb.append(directive).append(" = \"").append(directiveValue).append(
+ "\", ");
+ }
+
+ return directiveValue;
+ }
+
+ /**
+ * Copy the directive to the from src to dst if not null.
+ */
+ public static String copyDirective(HashMap<String, String> src,
+ HashMap<String, String> dst, String directive) {
+ String directiveValue = src.get(directive);
+ if (directiveValue != null) {
+ dst.put(directive, directiveValue);
+ }
+
+ return directiveValue;
+ }
+
+ /**
+ * Parses digest-challenge string, extracting each token
+ * and value(s)
+ *
+ * @param buf A non-null digest-challenge string.
+ * @throws UnsupportedEncodingException
+ * @throws SaslException if the String cannot be parsed according to RFC
2831
+ */
+ public static HashMap<String, String> parseDirectives(byte[] buf)
+ throws SaslException {
+ HashMap<String, String> map = new HashMap<String, String>();
+ boolean gettingKey = true;
+ boolean gettingQuotedValue = false;
+ boolean expectSeparator = false;
+ byte bch;
+
+ ByteArrayOutputStream key = new ByteArrayOutputStream(10);
+ ByteArrayOutputStream value = new ByteArrayOutputStream(10);
+
+ int i = skipLws(buf, 0);
+ while (i < buf.length) {
+ bch = buf[i];
+
+ if (gettingKey) {
+ if (bch == ',') {
+ if (key.size() != 0) {
+ throw new SaslException("Directive key contains a ',':"
+ + key);
+ }
+
+ // Empty element, skip separator and lws
+ i = skipLws(buf, i + 1);
+ } else if (bch == '=') {
+ if (key.size() == 0) {
+ throw new SaslException("Empty directive key");
+ }
+
+ gettingKey = false; // Termination of key
+ i = skipLws(buf, i + 1); // Skip to next non whitespace
+
+ // Check whether value is quoted
+ if (i < buf.length) {
+ if (buf[i] == '"') {
+ gettingQuotedValue = true;
+ ++i; // Skip quote
+ }
+ } else {
+ throw new SaslException("Valueless directive found: "
+ + key.toString());
+ }
+ } else if (isLws(bch)) {
+ // LWS that occurs after key
+ i = skipLws(buf, i + 1);
+
+ // Expecting '='
+ if (i < buf.length) {
+ if (buf[i] != '=') {
+ throw new SaslException("'=' expected after key: "
+ + key.toString());
+ }
+ } else {
+ throw new SaslException("'=' expected after key: "
+ + key.toString());
+ }
+ } else {
+ key.write(bch); // Append to key
+ ++i; // Advance
+ }
+ } else if (gettingQuotedValue) {
+ // Getting a quoted value
+ if (bch == '\\') {
+ // quoted-pair = "\" CHAR ==> CHAR
+ ++i; // Skip escape
+ if (i < buf.length) {
+ value.write(buf[i]);
+ ++i; // Advance
+ } else {
+ // Trailing escape in a quoted value
+ throw new SaslException(
+ "Unmatched quote found for directive: "
+ + key.toString() + " with value: "
+ + value.toString());
+ }
+ } else if (bch == '"') {
+ // closing quote
+ ++i; // Skip closing quote
+ gettingQuotedValue = false;
+ expectSeparator = true;
+ } else {
+ value.write(bch);
+ ++i; // Advance
+ }
+ } else if (isLws(bch) || bch == ',') {
+ // Value terminated
+ extractDirective(map, key.toString(), value.toString());
+ key.reset();
+ value.reset();
+ gettingKey = true;
+ gettingQuotedValue = expectSeparator = false;
+ i = skipLws(buf, i + 1); // Skip separator and LWS
+ } else if (expectSeparator) {
+ throw new SaslException(
+ "Expecting comma or linear whitespace after quoted
string: \""
+ + value.toString() + "\"");
+ } else {
+ value.write(bch); // Unquoted value
+ ++i; // Advance
+ }
+ }
+
+ if (gettingQuotedValue) {
+ throw new SaslException("Unmatched quote found for directive: "
+ + key.toString() + " with value: " + value.toString());
+ }
+
+ // Get last pair
+ if (key.size() > 0) {
+ extractDirective(map, key.toString(), value.toString());
+ }
+
+ return map;
+ }
+
+ /**
+ * Processes directive/value pairs from the digest-challenge and
+ * fill out the provided map.
+ *
+ * @param key A non-null String challenge token name.
+ * @param value A non-null String token value.
+ * @throws SaslException if either the key or the value is null or
+ * if the key already has a value.
+ */
+ private static void extractDirective(HashMap<String, String> map,
+ String key, String value) throws SaslException {
+ if (map.get(key) != null) {
+ throw new SaslException("Peer sent more than one " + key
+ + " directive");
+ } else {
+ map.put(key, value);
+ }
+ }
+
+ /**
+ * Is character a linear white space ?
+ * LWS = [CRLF] 1*( SP | HT )
+ * Note that we're checking individual bytes instead of CRLF
+ *
+ * @param b the byte to check
+ * @return <code>true</code> if it's a linear white space
+ */
+ public static boolean isLws(byte b) {
+ switch (b) {
+ case 13: // US-ASCII CR, carriage return
+ case 10: // US-ASCII LF, line feed
+ case 32: // US-ASCII SP, space
+ case 9: // US-ASCII HT, horizontal-tab
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Skip all linear white spaces
+ */
+ private static int skipLws(byte[] buf, int start) {
+ int i;
+
+ for (i = start; i < buf.length; i++) {
+ if (!isLws(buf[i])) {
+ return i;
+ }
+ }
+
+ return i;
+ }
+
+ /**
+ * Used to convert username-value, passwd or realm to 8859_1 encoding
+ * if all chars in string are within the 8859_1 (Latin 1) encoding range.
+ *
+ * @param str a non-null String
+ * @return a non-null String containing the 8859_1 encoded string
+ * @throws AuthenticationException
+ */
+ public static String stringTo8859_1(String str)
+ throws UnsupportedEncodingException {
+ if (str == null) {
+ return "";
+ } else {
+ return new String(str.getBytes("UTF8"), "8859_1");
+ }
+ }
+
+ public static String getSingleValuedHeader(
+ Map<String, List<String>> headers, String key) {
+ List<String> values = headers.get(key);
+
+ if (values == null) {
+ return null;
+ } else {
+ if (values.size() > 1) {
+ throw new IllegalArgumentException("Header with key [\"" + key
+ + "\"] isn't single valued !");
+ } else {
+ return values.get(0);
+ }
+ }
+ }
+
+ public static void addValueToHeader(Map<String, List<String>> headers,
+ String key, String value, boolean singleValued) {
+ List<String> values = headers.get(key);
+
+ if (values == null) {
+ values = new ArrayList<String>(1);
+ headers.put(key, values);
+ }
+
+ if (singleValued && values.size() == 1) {
+ values.set(0, value);
+ } else {
+ values.add(value);
+ }
+ }
+}
\ No newline at end of file
Propchange:
mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/StringUtilities.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
mina/trunk/core/src/main/java/org/apache/mina/proxy/utils/StringUtilities.java
------------------------------------------------------------------------------
svn:mime-type = text/plain