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


Reply via email to