summaryrefslogtreecommitdiffstats
path: root/src/libcmis/property.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/libcmis/property.cxx')
-rw-r--r--src/libcmis/property.cxx232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/libcmis/property.cxx b/src/libcmis/property.cxx
new file mode 100644
index 0000000..41c181b
--- /dev/null
+++ b/src/libcmis/property.cxx
@@ -0,0 +1,232 @@
+/* libcmis
+ * Version: MPL 1.1 / GPLv2+ / LGPLv2+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ * Copyright (C) 2011 SUSE <cbosdonnat@suse.com>
+ *
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPLv2+"), or
+ * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
+ * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable
+ * instead of those above.
+ */
+
+#include <libcmis/property.hxx>
+
+#include <boost/algorithm/string.hpp>
+
+#include <libcmis/object-type.hxx>
+#include <libcmis/xml-utils.hxx>
+
+using namespace std;
+
+namespace libcmis
+{
+ Property::Property( ):
+ m_propertyType( ),
+ m_strValues( ),
+ m_boolValues( ),
+ m_longValues( ),
+ m_doubleValues( ),
+ m_dateTimeValues( )
+ {
+ }
+
+ Property::Property( PropertyTypePtr propertyType, std::vector< std::string > strValues ) :
+ m_propertyType( propertyType ),
+ m_strValues( ),
+ m_boolValues( ),
+ m_longValues( ),
+ m_doubleValues( ),
+ m_dateTimeValues( )
+ {
+ setValues( strValues );
+ }
+
+ void Property::setValues( vector< string > strValues )
+ {
+ m_strValues = strValues;
+ m_boolValues.clear( );
+ m_longValues.clear( );
+ m_doubleValues.clear( );
+ m_dateTimeValues.clear( );
+
+ for ( vector< string >::iterator it = strValues.begin(); it != strValues.end( ); ++it )
+ {
+ try
+ {
+ // If no PropertyType was provided at construction time, use String
+ PropertyType::Type type = PropertyType::String;
+ if ( getPropertyType( ) != NULL )
+ type = getPropertyType( )->getType( );
+
+ switch ( type )
+ {
+ case PropertyType::Integer:
+ m_longValues.push_back( parseInteger( *it ) );
+ break;
+ case PropertyType::Decimal:
+ m_doubleValues.push_back( parseDouble( *it ) );
+ break;
+ case PropertyType::Bool:
+ m_boolValues.push_back( parseBool( *it ) );
+ break;
+ case PropertyType::DateTime:
+ {
+ boost::posix_time::ptime time = parseDateTime( *it );
+ if ( !time.is_not_a_date_time( ) )
+ m_dateTimeValues.push_back( time );
+ }
+ break;
+ default:
+ case PropertyType::String:
+ // Nothing to convert for strings
+ break;
+ }
+ }
+ catch( const Exception& )
+ {
+ // Just ignore the unparsable values
+ }
+ }
+ }
+
+ void Property::setPropertyType( PropertyTypePtr propertyType)
+ {
+ m_propertyType = propertyType;
+ }
+ void Property::toXml( xmlTextWriterPtr writer )
+ {
+ // Don't write the property if we have no type for it.
+ if ( getPropertyType( ) != NULL )
+ {
+ string xmlType = string( "cmis:property" ) + getPropertyType()->getXmlType( );
+ xmlTextWriterStartElement( writer, BAD_CAST( xmlType.c_str( ) ) );
+
+ // Write the attributes
+ xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "propertyDefinitionId" ),
+ "%s", BAD_CAST( getPropertyType()->getId( ).c_str( ) ) );
+ xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "localName" ),
+ "%s", BAD_CAST( getPropertyType()->getLocalName( ).c_str( ) ) );
+ xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "displayName" ),
+ "%s", BAD_CAST( getPropertyType()->getDisplayName( ).c_str( ) ) );
+ xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "queryName" ),
+ "%s", BAD_CAST( getPropertyType()->getQueryName( ).c_str( ) ) );
+
+ // Write the values
+ for ( vector< string >::iterator it = m_strValues.begin( ); it != m_strValues.end( ); ++it )
+ {
+ xmlTextWriterWriteElement( writer, BAD_CAST( "cmis:value" ), BAD_CAST( it->c_str( ) ) );
+ }
+
+ xmlTextWriterEndElement( writer );
+ }
+ }
+
+ string Property::toString( )
+ {
+ string res;
+ if ( getPropertyType( ) != NULL )
+ {
+ for ( vector< string >::iterator it = m_strValues.begin( );
+ it != m_strValues.end( ); ++it )
+ {
+ res.append( *it );
+ }
+ }
+ return res;
+ }
+
+ PropertyPtr parseProperty( xmlNodePtr node, ObjectTypePtr objectType )
+ {
+ PropertyPtr property;
+
+ if ( node != NULL )
+ {
+ // Get the property definition Id
+ string propDefinitionId;
+ try
+ {
+ propDefinitionId = getXmlNodeAttributeValue( node, "propertyDefinitionId" );
+ }
+ catch ( const Exception& )
+ {
+ }
+
+ // Try to get the property type definition
+ PropertyTypePtr propType;
+ if ( !propDefinitionId.empty() && objectType )
+ {
+ map< string, PropertyTypePtr >::iterator it = objectType->getPropertiesTypes( ).find( propDefinitionId );
+ if ( it != objectType->getPropertiesTypes().end( ) )
+ propType = it->second;
+ }
+
+ // Try to construct a temporary type definition
+ if ( !propDefinitionId.empty( ) && !propType )
+ {
+ if ( node->name != NULL )
+ {
+ string localName = getXmlNodeAttributeValue( node,
+ "localName", "" );
+ string displayName = getXmlNodeAttributeValue( node,
+ "displayName", "" );
+ string queryName = getXmlNodeAttributeValue( node,
+ "queryName", "" );
+
+ string xmlType( ( char * )node->name );
+ string propStr( "property" );
+ size_t pos = xmlType.find( propStr );
+ if ( pos == 0 ) {
+ xmlType = xmlType.substr( propStr.length( ) );
+ boost::to_lower( xmlType );
+ }
+
+ propType.reset( new PropertyType( xmlType, propDefinitionId,
+ localName, displayName,
+ queryName ) );
+ }
+ }
+
+ if ( propType )
+ {
+ try
+ {
+ // Find the value nodes
+ vector< string > values;
+ for ( xmlNodePtr child = node->children; child; child = child->next )
+ {
+ if ( xmlStrEqual( child->name, BAD_CAST( "value" ) ) )
+ {
+ xmlChar* content = xmlNodeGetContent( child );
+ values.push_back( string( ( char * ) content ) );
+ xmlFree( content );
+ }
+ }
+ property.reset( new Property( propType, values ) );
+ }
+ catch ( const Exception& )
+ {
+ // Ignore that non-property node
+ }
+ }
+ }
+
+ return property;
+ }
+}