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 bool Akonadi::Entity::operator<( const Entity & other ) const 00123 { 00124 return d_ptr->mId < other.d_ptr->mId; 00125 } 00126 00127 void Entity::addAttribute(Attribute * attr) 00128 { 00129 if ( d_ptr->mAttributes.contains( attr->type() ) ) { 00130 Attribute *existing = d_ptr->mAttributes.value( attr->type() ); 00131 if ( attr == existing ) { 00132 return; 00133 } 00134 d_ptr->mAttributes.remove( attr->type() ); 00135 delete existing; 00136 } 00137 d_ptr->mAttributes.insert( attr->type(), attr ); 00138 d_ptr->mDeletedAttributes.remove( attr->type() ); 00139 } 00140 00141 void Entity::removeAttribute( const QByteArray &type ) 00142 { 00143 if ( d_ptr->mAttributes.contains( type ) ) { 00144 d_ptr->mDeletedAttributes.insert( type ); 00145 delete d_ptr->mAttributes.take( type ); 00146 } 00147 } 00148 00149 bool Entity::hasAttribute(const QByteArray & type) const 00150 { 00151 return d_ptr->mAttributes.contains( type ); 00152 } 00153 00154 Attribute::List Entity::attributes() const 00155 { 00156 return d_ptr->mAttributes.values(); 00157 } 00158 00159 void Akonadi::Entity::clearAttributes() 00160 { 00161 foreach ( Attribute *attr, d_ptr->mAttributes ) { 00162 d_ptr->mDeletedAttributes.insert( attr->type() ); 00163 delete attr; 00164 } 00165 d_ptr->mAttributes.clear(); 00166 } 00167 00168 Attribute * Entity::attribute(const QByteArray & type) const 00169 { 00170 if ( d_ptr->mAttributes.contains( type ) ) 00171 return d_ptr->mAttributes.value( type ); 00172 return 0; 00173 } 00174 00175 uint qHash( const Akonadi::Entity &entity ) 00176 { 00177 return qHash( entity.id() ); 00178 } 00179 00180 Collection& Entity::parentCollection() 00181 { 00182 if ( !d_ptr->mParent ) 00183 d_ptr->mParent = new Collection(); 00184 return *(d_ptr->mParent); 00185 } 00186 00187 Collection Entity::parentCollection() const 00188 { 00189 if ( !d_ptr->mParent ) 00190 return *(s_defaultParentCollection); 00191 else 00192 return *(d_ptr->mParent); 00193 } 00194 00195 void Entity::setParentCollection( const Collection &parent ) 00196 { 00197 delete d_ptr->mParent; 00198 d_ptr->mParent = new Collection( parent ); 00199 } 00200 00201 AKONADI_DEFINE_PRIVATE( Entity )