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/05/20 17:03:50 UTC

svn commit: r776721 - in /activemq/activemq-cpp/trunk/activemq-cpp/src: main/ main/activemq/util/ main/activemq/wireformat/openwire/ main/activemq/wireformat/stomp/ main/decaf/util/ main/decaf/util/logging/ test-benchmarks/decaf/util/

Author: tabish
Date: Wed May 20 15:03:50 2009
New Revision: 776721

URL: http://svn.apache.org/viewvc?rev=776721&view=rev
Log:
Refactored Properties class in decaf to add Thread Safety and define the load/save interface.

Added:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.cpp   (with props)
Modified:
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/openwire/OpenWireFormat.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/stomp/StompFrame.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.cpp
    activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.h
    activemq/activemq-cpp/trunk/activemq-cpp/src/test-benchmarks/decaf/util/PropertiesBenchmark.cpp

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/Makefile.am Wed May 20 15:03:50 2009
@@ -97,6 +97,7 @@
     cms/MessageEOFException.cpp \
     cms/MessageNotReadableException.cpp \
     cms/InvalidClientIdException.cpp \
+    cms/IllegalStateException.cpp \
     cms/MessageFormatException.cpp \
     activemq/transport/mock/MockTransportFactory.cpp \
     activemq/transport/mock/MockTransport.cpp \
@@ -314,10 +315,10 @@
     activemq/wireformat/openwire/utils/HexTable.cpp \
     activemq/wireformat/openwire/OpenWireFormatNegotiator.cpp \
     activemq/wireformat/stomp/StompCommandConstants.cpp \
-    activemq/wireformat/stomp/StompHelper.cpp \
     activemq/wireformat/stomp/StompFrame.cpp \
     activemq/wireformat/stomp/StompWireFormatFactory.cpp \
     activemq/wireformat/stomp/StompWireFormat.cpp \
+    activemq/wireformat/stomp/StompHelper.cpp \
     activemq/wireformat/WireFormatRegistry.cpp \
     activemq/cmsutil/PooledSession.cpp \
     activemq/cmsutil/ResourceLifecycleManager.cpp \
@@ -326,6 +327,7 @@
     activemq/cmsutil/CmsDestinationAccessor.cpp \
     activemq/cmsutil/CmsAccessor.cpp \
     activemq/cmsutil/SessionPool.cpp \
+    activemq/util/ActiveMQProperties.cpp \
     activemq/util/PrimitiveValueConverter.cpp \
     activemq/util/URISupport.cpp \
     activemq/util/PrimitiveMap.cpp \
@@ -606,6 +608,7 @@
     cms/MessageEOFException.h \
     cms/TemporaryQueue.h \
     cms/InvalidSelectorException.h \
+    cms/IllegalStateException.h \
     cms/MapMessage.h \
     cms/Connection.h \
     cms/ConnectionMetaData.h \

Added: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.cpp?rev=776721&view=auto
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.cpp (added)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.cpp Wed May 20 15:03:50 2009
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#include "ActiveMQProperties.h"
+
+using namespace std;
+using namespace activemq;
+using namespace activemq::util;
+using namespace decaf::util;
+
+////////////////////////////////////////////////////////////////////////////////
+ActiveMQProperties::~ActiveMQProperties() {
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void ActiveMQProperties::copy( const CMSProperties* source ){
+
+    if( source == NULL ) {
+        return;
+    }
+
+    properties.clear();
+
+    std::vector< std::pair< std::string, std::string > > vec =
+        source->toArray();
+
+    for( unsigned int ix=0; ix<vec.size(); ++ix ){
+        properties.setProperty(vec[ix].first, vec[ix].second );
+    }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+cms::CMSProperties* ActiveMQProperties::clone() const{
+
+    ActiveMQProperties* props = new ActiveMQProperties();
+    props->copy( this );
+    return props;
+}

Propchange: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.h?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/util/ActiveMQProperties.h Wed May 20 15:03:50 2009
@@ -31,6 +31,8 @@
     /**
      * Implementation of the CMSProperties interface that
      * delegates to a decaf::util::Properties object.
+     *
+     * @since 2.0
      */
     class AMQCPP_API ActiveMQProperties : public cms::CMSProperties {
     private:
@@ -39,18 +41,18 @@
 
     public:
 
-        virtual ~ActiveMQProperties(){}
+        virtual ~ActiveMQProperties();
 
         virtual decaf::util::Properties& getProperties() {
-            return properties;
+            return this->properties;
         }
 
         virtual const decaf::util::Properties& getProperties() const {
-            return properties;
+            return this->properties;
         }
 
         virtual void setProperties( decaf::util::Properties& props ) {
-            properties.copy( &props );
+            this->properties = props;
         }
 
         /**
@@ -126,30 +128,13 @@
          * Copies the contents of the given properties object to this one.
          * @param source The source properties object.
          */
-        virtual void copy( const CMSProperties* source ){
-
-            properties.clear();
-
-            std::vector< std::pair< std::string, std::string > > vec =
-                source->toArray();
-
-            for( unsigned int ix=0; ix<vec.size(); ++ix ){
-                properties.setProperty(vec[ix].first, vec[ix].second );
-            }
-        }
+        virtual void copy( const CMSProperties* source );
 
         /**
          * Clones this object.
          * @returns a replica of this object.
          */
-        virtual CMSProperties* clone() const{
-
-            ActiveMQProperties* props = new ActiveMQProperties();
-
-            props->properties.copy(&properties);
-
-            return props;
-        }
+        virtual CMSProperties* clone() const;
 
         /**
          * Clears all properties from the map.

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/openwire/OpenWireFormat.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/openwire/OpenWireFormat.cpp?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/openwire/OpenWireFormat.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/openwire/OpenWireFormat.cpp Wed May 20 15:03:50 2009
@@ -56,7 +56,7 @@
 OpenWireFormat::OpenWireFormat( const decaf::util::Properties& properties ) {
 
     // Copy config data
-    this->properties.copy( &properties );
+    this->properties = properties;
 
     // Fill in that DataStreamMarshallers collection
     this->dataMarshallers.resize( 256 );

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/stomp/StompFrame.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/stomp/StompFrame.cpp?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/stomp/StompFrame.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/wireformat/stomp/StompFrame.cpp Wed May 20 15:03:50 2009
@@ -47,8 +47,7 @@
 void StompFrame::copy( const StompFrame* src ) {
 
     this->setCommand( src->getCommand() );
-    this->properties.copy( &( src->getProperties() ) );
-    // Use the Vectors assignment operator.
+    this->properties = src->getProperties();
     this->body = src->getBody();
 }
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.cpp?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.cpp Wed May 20 15:03:50 2009
@@ -17,13 +17,45 @@
 
 #include "Properties.h"
 
+#include <map>
+#include <sstream>
 #include <decaf/util/Date.h>
+#include <decaf/lang/exceptions/UnsupportedOperationException.h>
+#include <decaf/util/concurrent/Mutex.h>
 
 using namespace decaf;
 using namespace decaf::util;
+using namespace decaf::lang;
+using namespace decaf::lang::exceptions;
+using namespace decaf::io;
+
+////////////////////////////////////////////////////////////////////////////////
+namespace decaf{
+namespace util{
+
+    class PropertiesInternal{
+    public:
+
+        std::map< std::string, std::string > properties;
+        decaf::util::concurrent::Mutex mutex;
+
+    };
+
+}}
 
 ////////////////////////////////////////////////////////////////////////////////
 Properties::Properties() {
+    this->internal.reset( new PropertiesInternal() );
+}
+
+////////////////////////////////////////////////////////////////////////////////
+Properties::Properties( const Properties& src ) {
+    this->internal.reset( new PropertiesInternal() );
+    this->internal->properties = src.internal->properties;
+
+    if( src.defaults.get() != NULL ) {
+        this->defaults.reset( src.defaults->clone() );
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -31,46 +63,83 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
+Properties& Properties::operator= ( const Properties& src ) {
+
+    if( this == &src ) {
+        return *this;
+    }
+
+    synchronized( &( internal->mutex ) ) {
+        this->internal.reset( new PropertiesInternal() );
+
+        synchronized( &( src.internal->mutex ) ) {
+            this->internal->properties = src.internal->properties;
+        }
+
+        if( src.defaults.get() != NULL ) {
+            this->defaults.reset( src.defaults->clone() );
+        }
+    }
+
+    return *this;
+}
+
+////////////////////////////////////////////////////////////////////////////////
 bool Properties::isEmpty() const {
-    return properties.empty();
+    synchronized( &( internal->mutex ) ) {
+        return internal->properties.empty();
+    }
+
+    return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 const char* Properties::getProperty( const std::string& name ) const{
 
-    std::map< std::string, std::string >::const_iterator iter =
-    properties.find( name );
-    if( iter == properties.end() ){
-        return NULL;
+    synchronized( &( internal->mutex ) ) {
+        std::map< std::string, std::string >::const_iterator iter =
+            internal->properties.find( name );
+        if( iter == internal->properties.end() ){
+            return NULL;
+        }
+
+        return iter->second.c_str();
     }
 
-    return iter->second.c_str();
+    return NULL;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 std::string Properties::getProperty( const std::string& name,
                                      const std::string& defaultValue ) const {
 
-    std::map< std::string, std::string >::const_iterator iter =
-    properties.find( name );
-    if( iter == properties.end() ){
-        return defaultValue;
+    synchronized( &( internal->mutex ) ) {
+        std::map< std::string, std::string >::const_iterator iter =
+            internal->properties.find( name );
+        if( iter != internal->properties.end() ){
+            return iter->second;
+        }
     }
 
-    return iter->second;
+    return defaultValue;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void Properties::setProperty( const std::string& name,
                               const std::string& value ){
-    properties[name] = value;
+
+    synchronized( &( internal->mutex ) ) {
+        internal->properties[name] = value;
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 bool Properties::hasProperty( const std::string& name ) const {
 
-    if( properties.find(name) != properties.end() ) {
-        return true;
+    synchronized( &( internal->mutex ) ) {
+        if( internal->properties.find(name) != internal->properties.end() ) {
+            return true;
+        }
     }
 
     return false;
@@ -78,24 +147,33 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 void Properties::remove( const std::string& name ){
-    properties.erase( name );
+    synchronized( &( internal->mutex ) ) {
+        internal->properties.erase( name );
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 std::vector< std::pair< std::string, std::string > > Properties::toArray() const{
 
-    // Create a vector big enough to hold all the elements in the map.
-    std::vector< std::pair<std::string, std::string> > vec(
-            properties.begin(), properties.end() );
+    std::vector< std::pair<std::string, std::string> > result;
+
+    synchronized( &( internal->mutex ) ) {
+        result.assign( internal->properties.begin(), internal->properties.end() );
+    }
 
-    return vec;
+    return result;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void Properties::copy( const Properties* source ){
+void Properties::copy( const Properties& source ){
+
+    if( &source == this ) {
+        return;
+    }
 
-    clear();
-    this->properties = source->properties;
+    synchronized( &( internal->mutex ) ) {
+        *this = source;
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -103,14 +181,17 @@
 
     Properties* props = new Properties();
 
-    props->properties = properties;
+    *props = *this;
 
     return props;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void Properties::clear(){
-    properties.clear();
+
+    synchronized( &( internal->mutex ) ) {
+        internal->properties.clear();
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -121,12 +202,110 @@
 
     stream << "Begin Class decaf::util::Properties:" << std::endl;
 
-    for( iter = properties.begin(); iter != properties.end(); ++iter ){
-        stream << " properties[" << iter->first << "] = "
-               << iter->second << std::endl;
+    synchronized( &( internal->mutex ) ) {
+        for( iter = internal->properties.begin(); iter != internal->properties.end(); ++iter ){
+            stream << " property[" << iter->first << "] = "
+                   << iter->second << std::endl;
+        }
     }
 
     stream << "End Class decaf::util::Properties:" << std::endl;
 
     return stream.str();
 }
+
+////////////////////////////////////////////////////////////////////////////////
+void Properties::load( decaf::io::InputStream* stream )
+    throw( decaf::io::IOException,
+           decaf::lang::exceptions::IllegalArgumentException,
+           decaf::lang::exceptions::NullPointerException ) {
+
+    try{
+
+        if( stream == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "The Stream instance passed was Null" );
+        }
+
+        throw UnsupportedOperationException(
+            __FILE__, __LINE__,
+            "Not yet Implemented." );
+    }
+    DECAF_CATCH_RETHROW( IOException )
+    DECAF_CATCH_RETHROW( IllegalArgumentException )
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+    DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Properties::load( decaf::io::Reader* reader )
+    throw( decaf::io::IOException,
+           decaf::lang::exceptions::IllegalArgumentException,
+           decaf::lang::exceptions::NullPointerException ) {
+
+    try{
+
+        if( reader == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "The Reader instance passed was Null" );
+        }
+
+        throw UnsupportedOperationException(
+            __FILE__, __LINE__,
+            "Not yet Implemented." );
+    }
+    DECAF_CATCH_RETHROW( IOException )
+    DECAF_CATCH_RETHROW( IllegalArgumentException )
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+    DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Properties::store( decaf::io::OutputStream* out, const std::string& comments DECAF_UNUSED )
+    throw( decaf::io::IOException,
+           decaf::lang::exceptions::NullPointerException ) {
+
+    try{
+
+        if( out == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "The OutputStream instance passed was Null" );
+        }
+
+        throw UnsupportedOperationException(
+            __FILE__, __LINE__,
+            "Not yet Implemented." );
+    }
+    DECAF_CATCH_RETHROW( IOException )
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+    DECAF_CATCHALL_THROW( IOException )
+}
+
+////////////////////////////////////////////////////////////////////////////////
+void Properties::store( decaf::io::Writer* writer, const std::string& comments DECAF_UNUSED )
+    throw( decaf::io::IOException,
+           decaf::lang::exceptions::NullPointerException ) {
+
+    try{
+
+        if( writer == NULL ) {
+            throw NullPointerException(
+                __FILE__, __LINE__,
+                "The Writer instance passed was Null" );
+        }
+
+        throw UnsupportedOperationException(
+            __FILE__, __LINE__,
+            "Not yet Implemented." );
+    }
+    DECAF_CATCH_RETHROW( IOException )
+    DECAF_CATCH_RETHROW( NullPointerException )
+    DECAF_CATCH_EXCEPTION_CONVERT( Exception, IOException )
+    DECAF_CATCHALL_THROW( IOException )
+}

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.h?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/Properties.h Wed May 20 15:03:50 2009
@@ -18,36 +18,71 @@
 #ifndef _DECAF_UTIL_PROPERTIES_H_
 #define _DECAF_UTIL_PROPERTIES_H_
 
-#include <map>
+#include <memory>
 #include <vector>
 #include <string>
-#include <sstream>
 #include <decaf/util/Config.h>
+#include <decaf/io/InputStream.h>
+#include <decaf/io/OutputStream.h>
+#include <decaf/io/Reader.h>
+#include <decaf/io/Writer.h>
+#include <decaf/lang/exceptions/IllegalArgumentException.h>
+#include <decaf/lang/exceptions/NullPointerException.h>
+#include <decaf/io/IOException.h>
 
 namespace decaf{
 namespace util{
 
+    class PropertiesInternal;
+
     /**
      * Java-like properties class for mapping string names to string values.
+     * <p>
+     * The Properties list contains a key value pair of properties that can be loaded and
+     * stored to a stream.  Each Properties instance can contain an internal Properties list
+     * that contains default values for keys not found in the Properties List.
+     * <p>
+     * The Properties list if a Thread Safe class, it can be shared amongst objects in
+     * multiple threads without the need for additional synchronization.
      *
      * @since 1.0
      */
     class DECAF_API Properties{
     private:
 
-        std::map< std::string, std::string > properties;
+        std::auto_ptr<PropertiesInternal> internal;
+
+    protected:
+
+        /**
+         * Default list used to answer for any keys not found in the properties list, can
+         * be filled in by another implementation of this class.
+         */
+        std::auto_ptr<Properties> defaults;
 
     public:
 
         Properties();
 
+        Properties( const Properties& src );
+
         virtual ~Properties();
 
         /**
+         * Assignment Operator
+         *
+         * @param src
+         *      The Properties list to copy to this List.
+         *
+         * @return a reference to this List for use in chaining.
+         */
+        Properties& operator= ( const Properties& src );
+
+        /**
          * Returns true if the properties object is empty
          * @return true if empty
          */
-        virtual bool isEmpty() const;
+        bool isEmpty() const;
 
         /**
          * Looks up the value for the given property.
@@ -55,7 +90,8 @@
          * @return the value of the property with the given name, if it
          * exists.  If it does not exist, returns NULL.
          */
-        virtual const char* getProperty( const std::string& name ) const;
+        const char* getProperty( const std::string& name ) const;
+
         /**
          * Looks up the value for the given property.
          * @param name the name of the property to be looked up.
@@ -64,8 +100,8 @@
          * @return The value of the property specified by <code>name</code>, if it
          * exists, otherwise the <code>defaultValue</code>.
          */
-        virtual std::string getProperty( const std::string& name,
-                                         const std::string& defaultValue ) const;
+        std::string getProperty( const std::string& name,
+                                 const std::string& defaultValue ) const;
 
         /**
          * Sets the value for a given property.  If the property already
@@ -73,20 +109,21 @@
          * @param name The name of the value to be written.
          * @param value The value to be written.
          */
-        virtual void setProperty( const std::string& name,
-                                  const std::string& value );
+        void setProperty( const std::string& name,
+                          const std::string& value );
+
         /**
          * Check to see if the Property exists in the set
          * @param name - property name to check for in this properties set.
          * @return true if property exists, false otherwise.
          */
-        virtual bool hasProperty( const std::string& name ) const;
+        bool hasProperty( const std::string& name ) const;
 
         /**
          * Removes the property with the given name.
          * @param name the name of the property to remove.
          */
-        virtual void remove( const std::string& name );
+        void remove( const std::string& name );
 
         /**
          * Method that serializes the contents of the property map to
@@ -94,31 +131,230 @@
          * @return list of pairs where the first is the name and the second
          * is the value.
          */
-        virtual std::vector< std::pair< std::string, std::string > > toArray() const;
+        std::vector< std::pair< std::string, std::string > > toArray() const;
 
         /**
-         * Copies the contents of the given properties object to this one.
-         * @param source The source properties object.
+         * Copies the contents of the given properties object to this one, if the
+         * given Properties instance in NULL then this List is not modified.
+         *
+         * @param source
+         *      The source properties object.
          */
-        virtual void copy( const Properties* source );
+        void copy( const Properties& source );
 
         /**
          * Clones this object.
+         *
          * @returns a replica of this object.
          */
-        virtual Properties* clone() const;
+        Properties* clone() const;
 
         /**
          * Clears all properties from the map.
          */
-        virtual void clear();
+        void clear();
 
         /**
          * Formats the contents of the Properties Object into a string
          * that can be logged, etc.
          * @returns string value of this object.
          */
-        virtual std::string toString() const;
+        std::string toString() const;
+
+        /**
+         * Reads a property list (key and element pairs) from the input byte stream. The
+         * input stream is in a simple line-oriented format as specified in load(Reader) and
+         * is assumed to use the ISO 8859-1 character encoding.
+         *
+         * This method does not close the stream upon its return.
+         *
+         * @param stream
+         *      The stream to read the properties data from.
+         *
+         * @throw IOException if there is an error while reading from the stream.
+         * @throw IllegalArgumentException if malformed data is found while reading the properties.
+         * @throw NullPointerException if the passed stream is Null.
+         */
+        void load( decaf::io::InputStream* stream )
+            throw( decaf::io::IOException,
+                   decaf::lang::exceptions::IllegalArgumentException,
+                   decaf::lang::exceptions::NullPointerException );
+
+        /**
+         * Reads a property list (key and element pairs) from the input character stream in a
+         * simple line-oriented format.
+         * <p>
+         * Properties are processed in terms of lines. There are two kinds of line, natural lines
+         * and logical lines. A natural line is defined as a line of characters that is terminated
+         * either by a set of line terminator characters (\n or \r or \r\n) or by the end of the
+         * stream. A natural line may be either a blank line, a comment line, or hold all or some
+         * of a key-element pair. A logical line holds all the data of a key-element pair, which
+         * may be spread out across several adjacent natural lines by escaping the line terminator
+         * sequence with a backslash character \. Note that a comment line cannot be extended in
+         * this manner; every natural line that is a comment must have its own comment indicator,
+         * as described below. Lines are read from input until the end of the stream is reached.
+         * <p>
+         * A natural line that contains only white space characters is considered blank and is
+         * ignored. A comment line has an ASCII '#' or '!' as its first non-white space character;
+         * comment lines are also ignored and do not encode key-element information. In addition
+         * to line terminators, this format considers the characters space (' '), tab ('\t'),
+         * and form feed ('\f') to be white space.
+         * <p>
+         * If a logical line is spread across several natural lines, the backslash escaping the
+         * line terminator sequence, the line terminator sequence, and any white space at the
+         * start of the following line have no affect on the key or element values. The remainder
+         * of the discussion of key and element parsing (when loading) will assume all the
+         * characters constituting the key and element appear on a single natural line after line
+         * continuation characters have been removed. Note that it is not sufficient to only
+         * examine the character preceding a line terminator sequence to decide if the line
+         * terminator is escaped; there must be an odd number of contiguous backslashes for the
+         * line terminator to be escaped. Since the input is processed from left to right, a
+         * non-zero even number of 2n contiguous backslashes before a line terminator (or
+         * elsewhere) encodes n backslashes after escape processing.
+         * <p>
+         * The key contains all of the characters in the line starting with the first non-white
+         * space character and up to, but not including, the first unescaped '=', ':', or white
+         * space character other than a line terminator. All of these key termination characters
+         * may be included in the key by escaping them with a preceding backslash character; for
+         * example,
+         *
+         *    \:\=
+         *
+         * would be the two-character key ":=". Line terminator characters can be included using
+         * \r and \n escape sequences. Any white space after the key is skipped; if the first
+         * non-white space character after the key is '=' or ':', then it is ignored and any white
+         * space characters after it are also skipped. All remaining characters on the line become
+         * part of the associated element string; if there are no remaining characters, the element
+         * is the empty string "". Once the raw character sequences constituting the key and
+         * element are identified, escape processing is performed as described above.
+         * <p>
+         * As an example, each of the following three lines specifies the key "Truth" and the
+         * associated element value "Beauty":
+         * <p>
+         *     Truth = Beauty
+         *             Truth:Beauty
+         *         Truth                  :Beauty
+         * <p>
+         * As another example, the following three lines specify a single property:
+         * <p>
+         * fruits                           apple, banana, pear, \
+         *                                  cantaloupe, watermelon, \
+         *                                  kiwi, mango
+         * <p>
+         * The key is "fruits" and the associated element is:
+         *     "apple, banana, pear, cantaloupe, watermelon, kiwi, mango"
+         * <p>
+         * Note that a space appears before each \ so that a space will appear after each comma
+         * in the final result; the \, line terminator, and leading white space on the continuation
+         * line are merely discarded and are not replaced by one or more other characters.
+         * <p>
+         * As a third example, the line:
+         *
+         *   cheeses
+         *
+         * specifies that the key is "cheeses" and the associated element is the empty string "".
+         * <p>
+         * Characters in keys and elements can be represented in escape sequences similar to those
+         * used for character and string literals (see §3.3 and §3.10.6 of the Java Language
+         * Specification). The differences from the character escape sequences and Unicode escapes
+         * used for characters and strings are:
+         *
+         *   - Octal escapes are not recognized.
+         *   - The character sequence \b does not represent a backspace character.
+         *   - The method does not treat a backslash character, \, before a non-valid escape
+         *     character as an error; the backslash is silently dropped. For example, in a C++
+         *     string the sequence "\z" would cause a compile time error. In contrast, this
+         *     method silently drops the backslash. Therefore, this method treats the two
+         *     character sequence "\b" as equivalent to the single character 'b'.
+         *   - Escapes are not necessary for single and double quotes; however, by the rule above,
+         *     single and double quote characters preceded by a backslash still yield single and
+         *     double quote characters, respectively.
+         *
+         * This method does not close the Reader upon its return.
+         *
+         * @param reader
+         *      The Reader that provides an character stream as input.
+         *
+         * @throw IOException if there is an error while reading from the stream.
+         * @throw IllegalArgumentException if malformed data is found while reading the properties.
+         * @throw NullPointerException if the passed stream is Null.
+         */
+        void load( decaf::io::Reader* reader )
+            throw( decaf::io::IOException,
+                   decaf::lang::exceptions::IllegalArgumentException,
+                   decaf::lang::exceptions::NullPointerException );
+
+        /**
+         * Writes this property list (key and element pairs) in this Properties table to the
+         * output stream in a format suitable for loading into a Properties table using the
+         * load(InputStream) method.
+         * <p>
+         * Properties from the defaults table of this Properties table (if any) are not
+         * written out by this method.
+         * <p>
+         * This method outputs the comments, properties keys and values in the same format
+         * as specified in store(Writer), with the following differences:
+         *
+         *   - The stream is written using the ISO 8859-1 character encoding.
+         *   - Characters not in Latin-1 in the comments are written as \uxxxx for their
+         *     appropriate unicode hexadecimal value xxxx.
+         *   - Characters less than \u0020 and characters greater than \u007E in property keys
+         *     or values are written as \uxxxx for the appropriate hexadecimal value xxxx.
+         *
+         * After the entries have been written, the output stream is flushed. The output stream
+         * remains open after this method returns.
+         *
+         * @param out
+         *      The OutputStream instance to write the properties to.
+         * @param comment
+         *      A description of these properties that is written to the output stream.
+         *
+         * @throw IOException if there is an error while writing from the stream.
+         * @throw NullPointerException if the passed stream is Null.
+         */
+        void store( decaf::io::OutputStream* out, const std::string& comments )
+            throw( decaf::io::IOException,
+                   decaf::lang::exceptions::NullPointerException );
+
+        /**
+         * Writes this property list (key and element pairs) in this Properties table to the output
+         * character stream in a format that can be read by the load(Reader) method.
+         * <p>
+         * Properties from the defaults table of this Properties table (if any) are not written
+         * out by this method.
+         * <p>
+         * If the comments argument is not empty, then an ASCII # character, the comments string,
+         * and a line separator are first written to the output stream. Thus, the comments can
+         * serve as an identifying comment. Any one of a line feed ('\n'), a carriage return ('\r'),
+         * or a carriage return followed immediately by a line feed in comments is replaced by a
+         * line separator generated by the Writer and if the next character in comments is not
+         * character # or character ! then an ASCII # is written out after that line separator.
+         * <p>
+         * Next, a comment line is always written, consisting of an ASCII # character, the current
+         * date and time (as if produced by the toString method of Date for the current time), and
+         * a line separator as generated by the Writer.
+         * <p>
+         * Then every entry in this Properties table is written out, one per line. For each entry
+         * the key string is written, then an ASCII =, then the associated element string. For the
+         * key, all space characters are written with a preceding \ character. For the element,
+         * leading space characters, but not embedded or trailing space characters, are written
+         * with a preceding \ character. The key and element characters #, !, =, and : are written
+         * with a preceding backslash to ensure that they are properly loaded.
+         * <p>
+         * After the entries have been written, the output stream is flushed. The output stream
+         * remains open after this method returns.
+         *
+         * @param writer
+         *      The Writer instance to use to output the properties.
+         * @param comments
+         *      A description of these properties that is written before writing the properties.
+         *
+         * @throw IOException if there is an error while writing from the stream.
+         * @throw NullPointerException if the passed stream is Null.
+         */
+        void store( decaf::io::Writer* writer, const std::string& comments )
+            throw( decaf::io::IOException,
+                   decaf::lang::exceptions::NullPointerException );
 
     };
 

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.cpp?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.cpp Wed May 20 15:03:50 2009
@@ -39,10 +39,10 @@
 }
 
 ////////////////////////////////////////////////////////////////////////////////
-void LogManager::setProperties( const Properties* properties )
+void LogManager::setProperties( const Properties& properties )
 {
     // Copy the properties
-    this->properties.copy(properties);
+    this->properties = properties;
 
     // Update the configuration of the loggers.
     // TODO

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.h
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.h?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.h (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/main/decaf/util/logging/LogManager.h Wed May 20 15:03:50 2009
@@ -146,7 +146,7 @@
          * its loggers.  Once set a properties change event is fired.
          * @param properties Pointer to read the configuration from
          */
-        virtual void setProperties( const util::Properties* properties );
+        virtual void setProperties( const util::Properties& properties );
 
         /**
          * Gets a reference to the Logging Properties used by this

Modified: activemq/activemq-cpp/trunk/activemq-cpp/src/test-benchmarks/decaf/util/PropertiesBenchmark.cpp
URL: http://svn.apache.org/viewvc/activemq/activemq-cpp/trunk/activemq-cpp/src/test-benchmarks/decaf/util/PropertiesBenchmark.cpp?rev=776721&r1=776720&r2=776721&view=diff
==============================================================================
--- activemq/activemq-cpp/trunk/activemq-cpp/src/test-benchmarks/decaf/util/PropertiesBenchmark.cpp (original)
+++ activemq/activemq-cpp/trunk/activemq-cpp/src/test-benchmarks/decaf/util/PropertiesBenchmark.cpp Wed May 20 15:03:50 2009
@@ -56,7 +56,7 @@
     }
 
     for( int i = 0; i < numRuns; ++i ) {
-        copy.copy( &properties );
+        copy.copy( properties );
         copy.clear();
     }