You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by ta...@apache.org on 2009/03/03 22:24:25 UTC

svn commit: r749762 - in /activemq/activemq-cpp/trunk/src: main/activemq/util/ test/activemq/util/

Author: tabish
Date: Tue Mar  3 21:24:25 2009
New Revision: 749762

URL: http://svn.apache.org/viewvc?rev=749762&view=rev
Log:
URI Support class now has support for parsing the composite URI used for failover.

Modified:
    activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.cpp
    activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.h
    activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp
    activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h
    activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp
    activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h

Modified: activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.cpp?rev=749762&r1=749761&r2=749762&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.cpp (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.cpp Tue Mar  3 21:24:25 2009
@@ -18,6 +18,7 @@
 #include "CompositeData.h"
 
 #include <sstream>
+#include <memory>
 #include <activemq/util/URISupport.h>
 
 using namespace std;
@@ -25,6 +26,7 @@
 using namespace activemq::util;
 using namespace decaf;
 using namespace decaf::net;
+using namespace decaf::util;
 
 ////////////////////////////////////////////////////////////////////////////////
 CompositeData::CompositeData() {
@@ -48,11 +50,15 @@
     } else {
         sb << "(";
 
-        for( std::size_t i = 0; i < components.size(); i++ ) {
-            if( i != 0 ) {
+        bool firstTime = true;
+        std::auto_ptr< Iterator<URI> > iter( components.iterator() );
+
+        while( iter->hasNext() ) {
+            if( firstTime == true ) {
                 sb << ",";
+                firstTime = false;
             }
-            sb << components[i].toString();
+            sb << iter->next().toString();
         }
 
         sb << ")";

Modified: activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.h?rev=749762&r1=749761&r2=749762&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.h (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/util/CompositeData.h Tue Mar  3 21:24:25 2009
@@ -20,12 +20,14 @@
 
 #include <activemq/util/Config.h>
 #include <decaf/util/Properties.h>
+#include <decaf/util/StlList.h>
 #include <decaf/net/URI.h>
 #include <decaf/net/URISyntaxException.h>
 
 namespace activemq {
 namespace util {
 
+    using decaf::util::StlList;
     using decaf::net::URI;
     using decaf::util::Properties;
 
@@ -40,7 +42,7 @@
         std::string host;
         std::string scheme;
         std::string path;
-        std::vector<URI> components;
+        StlList<URI> components;
         Properties parameters;
         std::string fragment;
 
@@ -49,11 +51,14 @@
         CompositeData();
         virtual ~CompositeData();
 
-        const std::vector<URI>& getComponents() const {
+        StlList<URI>& getComponents() {
+            return components;
+        }
+        const StlList<URI>& getComponents() const {
             return components;
         }
 
-        void setComponents( const std::vector<URI>& components ) {
+        void setComponents( const StlList<URI>& components ) {
             this->components = components;
         }
 

Modified: activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp?rev=749762&r1=749761&r2=749762&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.cpp Tue Mar  3 21:24:25 2009
@@ -106,8 +106,7 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void URISupport::parseQuery( std::string query,
-                             Properties* properties )
+void URISupport::parseQuery( std::string query, Properties* properties )
     throw ( IllegalArgumentException ) {
 
     try {
@@ -237,3 +236,141 @@
     AMQ_CATCH_EXCEPTION_CONVERT( Exception, URISyntaxException )
     AMQ_CATCHALL_THROW( URISyntaxException )
 }
+
+////////////////////////////////////////////////////////////////////////////////
+bool URISupport::checkParenthesis( const std::string& str ) {
+
+    bool result = true;
+    if( str != "" ) {
+        int open = 0;
+        int closed = 0;
+
+        std::string::const_iterator iter = str.begin();
+
+        for( ; iter != str.end(); ++iter ) {
+            if( *iter == '(' ) {
+                open++;
+            } else if( *iter == ')' ){
+                closed++;
+            }
+        }
+
+        result = open == closed;
+    }
+
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+CompositeData URISupport::parseComposite( const URI& uri )
+    throw( decaf::net::URISyntaxException ) {
+
+    CompositeData result;
+    result.setScheme( uri.getScheme() );
+    string ssp = stripPrefix( uri.getSchemeSpecificPart(), "//" );
+    parseComposite( uri, result, ssp );
+    result.setFragment( uri.getFragment() );
+    return result;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void URISupport::parseComposite( const URI& uri, CompositeData& rc, const std::string& ssp )
+    throw( decaf::net::URISyntaxException ) {
+
+    std::string componentString;
+    std::string params;
+
+    if( !checkParenthesis( ssp ) ) {
+        throw URISyntaxException(
+            __FILE__, __LINE__,
+            "%s, Not a matching number of '(' and ')' parenthesis",
+            uri.toString() );
+    }
+
+    int p;
+    int intialParen = ssp.find( "(" );
+    if( intialParen == 0 ) {
+        rc.setHost( ssp.substr( 0, intialParen ) );
+        p = rc.getHost().find( "/" );
+        if( p >= 0 ) {
+            rc.setPath( rc.getHost().substr( p ) );
+            rc.setHost( rc.getHost().substr( 0, p ) );
+        }
+
+        p = ssp.rfind( ")" );
+        componentString = ssp.substr( intialParen + 1, p - (intialParen + 1) );
+        params = ssp.substr( p + 1 );
+
+    } else {
+        componentString = ssp;
+        params = "";
+    }
+
+    StlList<std::string> components = splitComponents( componentString );
+    std::auto_ptr< Iterator<std::string> > iter( components.iterator() );
+    while( iter->hasNext() ) {
+        rc.getComponents().add( URI( iter->next() ) );
+    }
+
+    p = params.find( "?" );
+    if( p >= 0 ) {
+        if( p > 0 ) {
+            rc.setPath( stripPrefix( params.substr( 0, p ), "/" ) );
+        }
+
+        rc.setParameters( parseQuery( params.substr( p + 1 ) ) );
+    } else {
+        if( params.length() > 0 ) {
+            rc.setPath( stripPrefix( params, "/" ) );
+        }
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+StlList<std::string> URISupport::splitComponents( const std::string& str ) {
+
+    StlList<std::string> components;
+
+    int last = 0;
+    int depth = 0;
+
+    std::string::const_iterator iter = str.begin();
+
+    for( std::size_t i = 0; iter != str.end(); ++iter, ++i ) {
+
+        switch( *iter ) {
+        case '(':
+            depth++;
+            break;
+        case ')':
+            depth--;
+            break;
+        case ',':
+            if( depth == 0 ) {
+                std::string s = str.substr( last, i );
+                components.add( s );
+                last = i + 1;
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    std::string s = str.substr( last );
+    if( s.length() != 0 ) {
+        components.add( s );
+    }
+
+    return components;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+std::string URISupport::stripPrefix( const std::string& value, const std::string& prefix ) {
+
+    if( value.find( prefix ) == 0 ) {
+        return value.substr( prefix.length() );
+    }
+
+    return value;
+}

Modified: activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h?rev=749762&r1=749761&r2=749762&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h (original)
+++ activemq/activemq-cpp/trunk/src/main/activemq/util/URISupport.h Tue Mar  3 21:24:25 2009
@@ -21,6 +21,7 @@
 #include <activemq/util/Config.h>
 #include <activemq/util/CompositeData.h>
 #include <decaf/util/Properties.h>
+#include <decaf/util/StlList.h>
 #include <decaf/lang/exceptions/IllegalArgumentException.h>
 
 namespace activemq{
@@ -41,11 +42,26 @@
             throw ( decaf::lang::exceptions::IllegalArgumentException );
 
         /**
+         * Parses a Composite URI into a Composite Data instance, the Composite URI
+         * takes the for scheme://(uri1,uri2,...uriN)?param1=value1, each of the composite
+         * URIs is stored in the CompositeData's internal list.
+         *
+         * @param uri - The Composite URI to parse.
+         * @return a new CompositeData object with the parsed data
+         *
+         * @throw URISyntaxException if the URI is not well formed.
+         */
+        static CompositeData parseComposite( const URI& uri )
+            throw( decaf::net::URISyntaxException );
+
+        /**
          * Parse the Query portion of a URI String and return a Simple
          * Properties object containing the parameter names as keys, and
          * the parameter values and values of the Properties.
          * @param query. the query string to parse.
          * @returns Properties object with the parsed output.
+         *
+         * @throw IllegalArgumentException if the Query string is not well formed.
          */
         static decaf::util::Properties parseQuery( std::string query )
             throw ( decaf::lang::exceptions::IllegalArgumentException );
@@ -56,6 +72,8 @@
          * the parameter values and values of the Properties.
          * @param query - the query string to parse.
          * @param properties - object pointer to get the parsed output.
+         *
+         * @throw IllegalArgumentException if the Query string is not well formed.
          */
         static void parseQuery( std::string query,
                                 decaf::util::Properties* properties )
@@ -79,6 +97,48 @@
     private:
 
         /**
+         * Perform a parse on the given composite URI, placing the results in the passed
+         * CompositeData
+         *
+         * @param uri - The URI to parse
+         * @param rc - The CompositeData object to Populate
+         * @param ssp - the Scheme Specific Part from the original URI.
+         *
+         * @throw URISyntaxException if the URI is not well formed.
+         */
+        static void parseComposite( const URI& uri, CompositeData& rc, const std::string& ssp )
+            throw( decaf::net::URISyntaxException );
+
+        /**
+         * Splits all the Component URIs in a Composite URI into individual strings which
+         * can then be parsed separately and stored in a Composite Data object.
+         *
+         * @param str - the set of Composite URIs
+         */
+        static decaf::util::StlList<std::string> splitComponents( const std::string& str );
+
+        /**
+         * Given a string value and a prefix value, return a new string that has the prefix
+         * removed if it was part of the passed in string, otherwise just return the passed
+         * in string
+         *
+         * @param value - String to strip
+         * @param prefix - value to strip from the passed in string
+         *
+         * @return the new string with prefix removed.
+         */
+        static std::string stripPrefix( const std::string& value, const std::string& prefix );
+
+        /**
+         * Matches all opening and closing parenthesis in a String
+         *
+         * @param str - The String to match parenthesis in.
+         *
+         * @return true if all parenthesis have valid open and close values.
+         */
+        static bool checkParenthesis( const std::string& str );
+
+        /**
          * Accepts a string value and checks to see if that value is of the
          * form ${XXX} which is our accepted form for environment variables.
          * If so the we attempt to replace the value with what is stored in that

Modified: activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp?rev=749762&r1=749761&r2=749762&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp (original)
+++ activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.cpp Tue Mar  3 21:24:25 2009
@@ -120,3 +120,35 @@
         URISupport::parseURL( test, map ),
         decaf::lang::exceptions::IllegalArgumentException );
 }
+
+////////////////////////////////////////////////////////////////////////////////
+void URISupportTest::testParseComposite() {
+
+    CompositeData data = URISupport::parseComposite(
+        URI("broker:()/localhost?persistent=false" ) );
+    CPPUNIT_ASSERT( 0 == data.getComponents().size() );
+
+    data = URISupport::parseComposite( URI( "test:(path)/path" ) );
+    CPPUNIT_ASSERT( data.getPath() == "path" );
+
+    data = URISupport::parseComposite( URI( "test:path" ) );
+    CPPUNIT_ASSERT( data.getPath() == "" );
+
+    data = URISupport::parseComposite( URI( "test:part1" ) );
+    CPPUNIT_ASSERT( 1 == data.getComponents().size() );
+
+    data = URISupport::parseComposite(
+        URI( "test:(part1://host,part2://(sub1://part,sube2:part))" ) );
+    CPPUNIT_ASSERT( 2 == data.getComponents().size() );
+
+    data = URISupport::parseComposite(
+        URI( "broker://(tcp://localhost:61616?wireformat=openwire)?name=foo" ) );
+
+    CPPUNIT_ASSERT( data.getScheme() == "broker" );
+    CPPUNIT_ASSERT( data.getParameters().hasProperty( "name" ) );
+    CPPUNIT_ASSERT( string( data.getParameters().getProperty( "name" ) ) == "foo" );
+    CPPUNIT_ASSERT( data.getComponents().size() == 1 );
+    CPPUNIT_ASSERT( data.getComponents().get(0).toString() ==
+                    "tcp://localhost:61616?wireformat=openwire" );
+
+}

Modified: activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h?rev=749762&r1=749761&r2=749762&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h (original)
+++ activemq/activemq-cpp/trunk/src/test/activemq/util/URISupportTest.h Tue Mar  3 21:24:25 2009
@@ -29,6 +29,7 @@
        CPPUNIT_TEST_SUITE( URISupportTest );
        CPPUNIT_TEST( test );
        CPPUNIT_TEST( testURIParseEnv );
+       CPPUNIT_TEST( testParseComposite );
        CPPUNIT_TEST_SUITE_END();
 
     public:
@@ -38,6 +39,7 @@
 
         void test();
         void testURIParseEnv();
+        void testParseComposite();
 
     };