1
/****************************************************************************
3
| Copyright (c) 2007 Novell, Inc.
6
| This program is free software; you can redistribute it and/or
7
| modify it under the terms of version 2 of the GNU General Public License as
8
| published by the Free Software Foundation.
10
| This program is distributed in the hope that it will be useful,
11
| but WITHOUT ANY WARRANTY; without even the implied warranty of
12
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
| GNU General Public License for more details.
15
| You should have received a copy of the GNU General Public License
16
| along with this program; if not, contact Novell, Inc.
18
| To contact Novell about this file by physical or electronic mail,
19
| you may find current contact information at www.novell.com
21
| Author: Brady Anderson <banderso@novell.com>
22
/***********************************************************************
23
* This source file implements the Group class.
24
* Groups are implemented as Node objects contained within an
25
* AddressBook (collection). Relationship objects are used to link
28
***********************************************************************/
29
|***************************************************************************/
36
using System.Collections;
40
namespace Novell.AddressBook
43
/// Summary description for Group.
44
/// A Group is equivalent to a Node in the collection store.
46
public class Group : Node
49
internal AddressBook addressBook = null;
50
// private IEnumerator thisEnum = null;
51
internal ArrayList addressList;
52
private Stream logoStream = null;
59
/// Description of the Group
60
/// !NOTE! Doc incomplete
62
public string Description
69
this.Properties.GetSingleProperty(
70
Common.groupDescriptionProperty).ToString());
82
this.Properties.ModifyProperty(
83
Common.groupDescriptionProperty,
88
this.Properties.DeleteProperties(
89
Common.groupDescriptionProperty);
97
/// Url: Specifies the a url to the Group's web page
99
/// Type Value: Single text value
101
/// Example: http://www.eatatjoes.com
111
this.Properties.GetSingleProperty(
112
Common.urlProperty).ToString());
124
this.Properties.ModifyProperty(
130
this.Properties.DeleteProperties(
139
/// NOTE: latest notes about the Group
141
/// Type Value: single value - text
143
/// Example: blah, blah, blah...
153
this.Properties.GetSingleProperty(
154
Common.noteProperty).ToString());
166
this.Properties.ModifyProperty(
172
this.Properties.DeleteProperties(
173
Common.noteProperty);
181
/// Blog: Specifies the Group's blog url
183
/// Type Value: Single text value
185
/// Example: http://simiasteam.blogdomain.com
195
this.Properties.GetSingleProperty(
196
Common.blogProperty).ToString());
208
this.Properties.ModifyProperty(
214
this.Properties.DeleteProperties(Common.blogProperty);
222
/// Calendar: Specifies the Group's calendar url
224
/// Type Value: Single text value
226
/// Example: http://simiasteam.company.com/groupname/ical
229
public string Calendar
236
this.Properties.GetSingleProperty(
237
Common.calProperty).ToString());
249
this.Properties.ModifyProperty(
255
this.Properties.DeleteProperties(Common.calProperty);
265
internal Group(AddressBook addressBook, Node cNode) : base(cNode)
267
this.addressList = new ArrayList();
272
/// Simple Group constructor
274
public Group() : base("")
276
this.addressList = new ArrayList();
280
/// Group constructor that names the group upon construction
282
public Group(string groupName) : base(groupName)
284
this.addressList = new ArrayList();
289
#region Private Methods
291
internal void Add(AddressBook addressBook)
295
this.addressBook = addressBook;
296
if (this.Name != null && this.Name != "")
298
// Add a relationship that will reference the parent Node.
299
Relationship parentChild = new
300
Relationship( addressBook.ID, this.ID );
301
this.Properties.AddProperty( Common.groupToAddressBook, parentChild );
303
if (this.addressList.Count > 0)
305
foreach(Address cAddress in this.addressList)
307
Relationship addressAndContact = new
308
Relationship(addressBook.ID, this.ID );
309
cAddress.Properties.AddProperty( Common.addressToGroup, addressAndContact );
316
throw new ApplicationException(
317
Common.addressBookExceptionHeader + "Group - missing \"Name\" property");
321
/// Retrieves a group from the collection store and deserializes
322
/// to the properties in the Group object.
324
/// An exception is thrown if the contact can't be find by the
327
/// <returns>None</returns>
329
internal void ToObject()
333
// Load up the addresses
334
this.addressList.Clear();
335
Relationship parentChild =
336
new Relationship( this.addressBook.ID, this.ID );
338
this.addressBook.Search( Common.addressToGroup, parentChild );
339
foreach ( ShallowNode cShallow in results )
341
Node cNode = new Node(this.addressBook, cShallow);
342
if (this.addressBook.IsType(cNode, Common.addressProperty) == true)
344
this.addressList.Add(new Group(this.addressBook, cNode));
352
#region Public Methods
355
/// Commits any changes to the Group object.
359
if (this.addressBook != null)
361
this.addressBook.SetType(this, Common.groupType);
363
int nodesToCommit = 1 + this.addressList.Count;
365
Node[] commitList = new Node[nodesToCommit];
367
commitList[i++] = this;
369
if (this.addressList.Count > 0)
371
Novell.AddressBook.Address.PrepareToCommit(this);
372
foreach(Address cAddr in this.addressList)
374
this.addressBook.SetType(cAddr, Common.addressProperty);
375
commitList[i++] = cAddr;
379
this.addressBook.Commit(commitList);
384
/// Deletes the current Group object.
386
public Node[] Delete(bool commit)
388
Node[] nodeList = new Node[1 + this.addressList.Count];
391
foreach(Address cAddress in this.addressList)
393
nodeList[idx++] = cAddress;
395
this.addressList.Clear();
399
if (this.addressBook != null &&
400
this.addressBook != null)
402
nodeList[idx++] = this;
406
this.addressBook.Commit(
407
this.addressBook.Delete(nodeList));
411
this.addressBook.Delete(nodeList);
417
// Return the list of nodes that were deleted
422
/// Deletes the current Group object.
430
/// Adds a contact to the group
433
/// If for any reason the contact cannot be added
434
/// an exception is raised.
436
public void AddContact(Contact cContact)
440
// Add a relationship that will reference the contact Node.
441
Relationship parentChild = new
442
Relationship( this.ID, cContact.ID );
443
this.Properties.AddProperty( Common.groupToContact, parentChild );
447
throw new ApplicationException(Common.addressBookExceptionHeader + "Failed adding Contact");
451
/// Gets the list of contacts attached to this Group.
453
public IABList GetContactList()
455
IABList cList = new IABList();
459
MultiValuedList mList = this.Properties.GetProperties(Common.groupToContact);
460
foreach(Property p in mList)
464
Simias.Storage.Relationship relationship =
465
(Simias.Storage.Relationship) p.Value;
468
this.addressBook.GetNodeByID(relationship.NodeID);
469
if (this.addressBook.IsType(cContactNode, Common.contactType) == true)
471
cList.Add(this.addressBook.GetContact(cContactNode.ID));
478
Relationship parentChild =
479
new Relationship( this.ID, this.ID );
481
this.addressBook.collection.Search( Common.groupToContact, parentChild );
482
foreach ( ShallowNode cShallow in results )
484
Node cNode = new Node(this.addressBook.collection, cShallow);
485
if (this.addressBook.collection.IsType(cNode, Common.contactType) == true)
487
cList.Add(new Contact(this.addressBook, cNode));
497
/// Remove contact from group
501
public void RemoveContact(Contact cContact)
505
MultiValuedList mList = this.Properties.GetProperties(Common.groupToContact);
506
foreach(Property p in mList)
508
if (((Relationship) p.Value).NodeID == cContact.ID)
520
/// Adds a vCard ADR property to the Group.
523
/// vCard ADR is a structured property consisting of:
524
/// Street, Region, Locality, Country and Extended Address
526
/// Each Group may have one preferred ADR.
528
/// If for any reason the ADR cannot be created an exception is raised.
530
public void AddAddress(Address addr)
538
throw new ApplicationException(Common.addressBookExceptionHeader + "Failed adding Address");
542
/// Gets a list of addresses attached to this Group.
544
public IABList GetAddresses()
546
IABList cList = new IABList();
550
foreach(Address addr in this.addressList)
560
/// Gets the preferred address for this Group.
562
public Address GetPreferredAddress()
564
foreach(Address addr in this.addressList)
566
if (addr.Preferred == true)
576
/// Deletes an Address record in a Group.
577
/// A Group may contain 0 to many address records
579
public void DeleteAddress(string addressID)
583
foreach(Address addr in this.addressList)
585
if (addr.ID == addressID)
594
// FIXME - log this condition
599
/// Retrieve a vCard ADR property based on an address ID.
601
/// <param name="addressID">Address ID</param>
603
/// vCard Address is a structured property consisting of:
604
/// Post Office Box, Extended Address, Street Address, Locality,
605
/// Region, Postal Code and Country
607
/// Each contact may have one preferred Address.
609
/// If for any reason the Address can't be retrieved an an exception is raised.
611
/// <returns>An Address object with a valid postal code property.</returns>
612
public Address GetAddress(string addressID)
616
foreach(Address cAddress in this.addressList)
618
if (cAddress.ID == addressID)
626
// FIXME - log this condition
631
/// Export the Group logo via a binary Stream object.
634
/// vCard LOGO is a single valued binary property
636
/// An exception is raised if the Group does not contain
639
/// NOTE: The caller is expected to close the returned
640
/// stream object when finished.
642
/// <returns>A binary stream object which the caller can read from.</returns>
643
public Stream ExportLogo()
645
if (this.addressBook != null)
649
Property p = this.Properties.GetSingleProperty(Common.groupToLogo);
652
Simias.Storage.Relationship relationship =
653
(Simias.Storage.Relationship) p.Value;
656
this.addressBook.GetNodeByID(relationship.NodeID);
658
if (cLogoNode != null)
660
StoreFileNode sfn = new StoreFileNode(cLogoNode);
664
sfn.GetFullPath(this.addressBook),
672
throw new ApplicationException(Common.addressBookExceptionHeader + "Logo property does not exist");
676
if(this.logoStream != null)
678
return(this.logoStream);
681
throw new ApplicationException(Common.addressBookExceptionHeader + "Logo property does not exist");
686
/// Imports a logo photo from a a file name.
688
/// <param name="fileName">Source Filename</param>
690
/// vCard PHOTO is a single valued binary property
692
/// <returns>true if the photo was successfully imported.</returns>
693
public bool ImportLogo(string fileName)
695
bool results = false;
696
Stream srcStream = null;
700
srcStream = new FileStream(fileName, FileMode.Open);
701
results = this.ImportLogo(srcStream);
702
// BUGBUG store the source file name in the store - where it came from
707
if (srcStream != null)
717
/// Imports a logo photo from a stream object.
719
/// <param name="srcStream">Source Stream</param>
721
/// vCard LOGO is a single valued binary property
723
/// <returns>true if the logo photo was successfully imported.</returns>
724
public bool ImportLogo(Stream srcStream)
726
bool finished = false;
727
StoreFileNode sfn = null;
728
//NodeStream photoStream = null;
729
//Stream dstStream = null;
731
if (this.addressBook != null)
735
// See if a photo stream already exists for this contact node.
736
// If one is found - delete it
738
this.Properties.GetSingleProperty(Common.groupToLogo);
741
Simias.Storage.Relationship relationship =
742
(Simias.Storage.Relationship) p.Value;
745
this.addressBook.GetNodeByID(relationship.NodeID);
746
if (cLogoNode != null)
748
this.addressBook.Delete(cLogoNode);
749
this.addressBook.Commit(cLogoNode);
755
// Create the new node
763
Relationship parentChild = new
768
this.Properties.ModifyProperty(Common.groupToLogo, parentChild);
769
this.addressBook.Commit(sfn);
770
this.addressBook.Commit(this);
777
BinaryReader bReader = null;
778
BinaryWriter bWriter = null;
780
// Copy the logo photo into the cached stream
783
// Create the new stream in the file system
784
this.logoStream = new MemoryStream();
785
bWriter = new BinaryWriter(this.logoStream);
787
// Copy the source stream
788
bReader = new BinaryReader(srcStream);
789
bReader.BaseStream.Position = 0;
790
bWriter.BaseStream.Position = 0;
792
//bWriter.Write(bReader.BaseStream, 0, bReader.BaseStream.Length);
794
// BUGBUG better algo for copying
798
i = bReader.BaseStream.ReadByte();
804
bWriter.BaseStream.WriteByte((byte) i);
807
bWriter.BaseStream.Position = 0;