akonadi
entity.cpp
00001 /* 00002 Copyright (c) 2008 Tobias Koenig <tokoe@kde.org> 00003 00004 This library is free software; you can redistribute it and/or modify it 00005 under the terms of the GNU Library General Public License as published by 00006 the Free Software Foundation; either version 2 of the License, or (at your 00007 option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, but WITHOUT 00010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00012 License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to the 00016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00017 02110-1301, USA. 00018 */ 00019 00020 #include "entity.h" 00021 #include "entity_p.h" 00022 #include "collection.h" 00023 00024 #include <kglobal.h> 00025 00026 using namespace Akonadi; 00027 00028 K_GLOBAL_STATIC( Akonadi::Collection, s_defaultParentCollection ) 00029 00030 00033 static void assignEntityPrivate( QSharedDataPointer<EntityPrivate> &one, const QSharedDataPointer<EntityPrivate> &other ) 00034 { 00035 // We can't simply do one = other here, we have to use a temp. 00036 // Otherwise ProtocolHelperTest::testParentCollectionAfterCollectionParsing() 00037 // will break. 00038 // 00039 // The reason are assignments like 00040 // col = col.parentCollection() 00041 // 00042 // Here, parentCollection() actually returns a reference to a pointer owned 00043 // by col. So when col (or rather, it's private class) is deleted, the pointer 00044 // to the parent collection and therefore the reference becomes invalid. 00045 // 00046 // With a single-line assignment here, the parent collection would be deleted 00047 // before it is assigned, and therefore the resulting object would point to 00048 // uninitalized memory. 00049 QSharedDataPointer<EntityPrivate> temp = other; 00050 one = temp; 00051 } 00052 00053 00054 Entity::Entity( const Entity &other ) 00055 { 00056 assignEntityPrivate( d_ptr, other.d_ptr ); 00057 } 00058 00059 Entity::Entity( EntityPrivate *dd ) 00060 : d_ptr( dd ) 00061 { 00062 } 00063 00064 Entity::~Entity() 00065 { 00066 } 00067 00068 void Entity::setId( Id id ) 00069 { 00070 d_ptr->mId = id; 00071 } 00072 00073 Entity::Id Entity::id() const 00074 { 00075 return d_ptr->mId; 00076 } 00077 00078 void Entity::setRemoteId( const QString& id ) 00079 { 00080 d_ptr->mRemoteId = id; 00081 } 00082 00083 QString Entity::remoteId() const 00084 { 00085 return d_ptr->mRemoteId; 00086 } 00087 00088 void Entity::setRemoteRevision( const QString& revision ) 00089 { 00090 d_ptr->mRemoteRevision = revision; 00091 } 00092 00093 QString Entity::remoteRevision() const 00094 { 00095 return d_ptr->mRemoteRevision; 00096 } 00097 00098 bool Entity::isValid() const 00099 { 00100 return ( d_ptr->mId >= 0 ); 00101 } 00102 00103 bool Entity::operator==( const Entity &other ) const 00104 { 00105 return ( d_ptr->mId == other.d_ptr->mId ); 00106 } 00107 00108 bool Akonadi::Entity::operator!=(const Entity & other) const 00109 { 00110 return d_ptr->mId != other.d_ptr->mId; 00111 } 00112 00113 Entity& Entity ::operator=( const Entity &other ) 00114 { 00115 if ( this != &other ) { 00116 assignEntityPrivate( d_ptr, other.d_ptr ); 00117 } 00118 00119 return *this; 00120 } 00121 00122 void Entity::addAttribute(Attribute * attr) 00123 { 00124 if ( d_ptr->mAttributes.contains( attr->type() ) ) { 00125 Attribute *existing = d_ptr->mAttributes.value( attr->type() ); 00126 if ( attr == existing ) { 00127 return; 00128 } 00129 d_ptr->mAttributes.remove( attr->type() ); 00130 delete existing; 00131 } 00132 d_ptr->mAttributes.insert( attr->type(), attr ); 00133 d_ptr->mDeletedAttributes.remove( attr->type() ); 00134 } 00135 00136 void Entity::removeAttribute( const QByteArray &type ) 00137 { 00138 if ( d_ptr->mAttributes.contains( type ) ) { 00139 d_ptr->mDeletedAttributes.insert( type ); 00140 delete d_ptr->mAttributes.take( type ); 00141 } 00142 } 00143 00144 bool Entity::hasAttribute(const QByteArray & type) const 00145 { 00146 return d_ptr->mAttributes.contains( type ); 00147 } 00148 00149 Attribute::List Entity::attributes() const 00150 { 00151 return d_ptr->mAttributes.values(); 00152 } 00153 00154 void Akonadi::Entity::clearAttributes() 00155 { 00156 foreach ( Attribute *attr, d_ptr->mAttributes ) { 00157 d_ptr->mDeletedAttributes.insert( attr->type() ); 00158 delete attr; 00159 } 00160 d_ptr->mAttributes.clear(); 00161 } 00162 00163 Attribute * Entity::attribute(const QByteArray & type) const 00164 { 00165 if ( d_ptr->mAttributes.contains( type ) ) 00166 return d_ptr->mAttributes.value( type ); 00167 return 0; 00168 } 00169 00170 uint qHash( const Akonadi::Entity &entity ) 00171 { 00172 return qHash( entity.id() ); 00173 } 00174 00175 Collection& Entity::parentCollection() 00176 { 00177 if ( !d_ptr->mParent ) 00178 d_ptr->mParent = new Collection(); 00179 return *(d_ptr->mParent); 00180 } 00181 00182 Collection Entity::parentCollection() const 00183 { 00184 if ( !d_ptr->mParent ) 00185 return *(s_defaultParentCollection); 00186 else 00187 return *(d_ptr->mParent); 00188 } 00189 00190 void Entity::setParentCollection( const Collection &parent ) 00191 { 00192 delete d_ptr->mParent; 00193 d_ptr->mParent = new Collection( parent ); 00194 } 00195 00196 AKONADI_DEFINE_PRIVATE( Entity )