Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Move to old-code

svn path=/old-code/; revision=156242
  • Loading branch information...
commit bcd193e76905c8ef90de8c923b6485bbdec97997 1 parent f14cae2
Miguel de Icaza migueldeicaza authored
Showing with 8,998 additions and 0 deletions.
  1. +51 −0 acceptance-tests-ifolder/Deveel.Pim/AssemblyInfo.cs
  2. +72 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim.mdp
  3. +16 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim.mds
  4. +99 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Address.cs
  5. +214 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/BaseConverter.cs
  6. +134 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/BusinessDetail.cs
  7. +41 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/BusyStatus.cs
  8. +94 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Calendar.cs
  9. +742 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/CalendarConverter.cs
  10. +220 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Contact.cs
  11. +698 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ContactConverter.cs
  12. +63 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ContactDetail.cs
  13. +48 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ConverterException.cs
  14. +77 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Email.cs
  15. +359 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Event.cs
  16. +421 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/EventRecurrence.cs
  17. +109 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/FieldList.cs
  18. +41 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/MeetingStatus.cs
  19. +95 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Name.cs
  20. +72 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Note.cs
  21. +323 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ParamList.cs
  22. +106 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/PersonalDetail.cs
  23. +75 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Phone.cs
  24. +258 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Property.cs
  25. +89 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/PropertyCollection.cs
  26. +122 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/QuotedPrintable.cs
  27. +48 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/RecurrenceDays.cs
  28. +43 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/RecurrencePatternException.cs
  29. +42 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/RecurrenceType.cs
  30. +86 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Reminder.cs
  31. +427 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/TimeUtils.cs
  32. +1,183 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/TimeZone.cs
  33. +75 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Title.cs
  34. +80 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Token.cs
  35. +75 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/WebPage.cs
  36. +57 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/XTag.cs
  37. +117 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/XTagCollection.cs
  38. +912 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/iCalParser.csc
  39. +1,211 −0 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/vCardParser.csc
  40. BIN  acceptance-tests-ifolder/Deveel.Pim/csharpcc/csharpcc.jar
  41. +3 −0  acceptance-tests-ifolder/Deveel.Pim/parsergen
51 acceptance-tests-ifolder/Deveel.Pim/AssemblyInfo.cs
View
@@ -0,0 +1,51 @@
+//
+// AssemblyInfo.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Deveel.Pim")]
+[assembly: AssemblyDescription("Personal Information Management library.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Deveel srl")]
+[assembly: AssemblyProduct("Deveel.Pim")]
+[assembly: AssemblyCopyright("Copyright © 2006 Deveel")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+[assembly: CLSCompliant(true)]
+
+[assembly: Guid("dbf9f729-344e-4fdf-90c4-a1dc8ee69a64")]
+
+[assembly: AssemblyVersion("0.8.5.0")]
+[assembly: AssemblyFileVersion("0.8.5.0")]
72 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim.mdp
View
@@ -0,0 +1,72 @@
+<Project name="Deveel.Pim" fileversion="2.0" language="C#" ctype="DotNetProject">
+ <Configurations active="Debug">
+ <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+ <Output directory="./bin/Debug" assembly="Deveel.Pim" />
+ <Build executeBeforeBuild="./parsergen" debugmode="True" target="Library" />
+ <Execution runwithwarnings="True" consolepause="False" runtime="MsNet" />
+ <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" definesymbols="MONO" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ <Configuration name="Release" ctype="DotNetProjectConfiguration">
+ <Output directory="./bin/Release" assembly="Deveel.Pim" />
+ <Build debugmode="False" target="Library" />
+ <Execution runwithwarnings="True" consolepause="False" runtime="MsNet" />
+ <CodeGeneration compiler="Csc" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" definesymbols="MONO" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ </Configurations>
+ <DeploymentInformation strategy="File">
+ <excludeFiles />
+ </DeploymentInformation>
+ <Contents>
+ <File name="./AssemblyInfo.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim" subtype="Directory" buildaction="Compile" />
+ <File name="./Deveel.Pim/Address.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/BaseConverter.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/BusinessDetail.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/BusyStatus.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Calendar.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/CalendarConverter.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Contact.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/ContactConverter.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/ContactDetail.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/ConverterException.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Email.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Event.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/EventRecurrence.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/FieldList.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/iCalParser.csc" subtype="Code" buildaction="Nothing" />
+ <File name="./Deveel.Pim/MeetingStatus.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Name.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Note.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/ParamList.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/PersonalDetail.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Phone.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Property.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/PropertyCollection.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/QuotedPrintable.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/RecurrenceDays.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/RecurrencePatternException.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/RecurrenceType.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Reminder.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/TimeUtils.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/TimeZone.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Title.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/Token.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/vCardParser.csc" subtype="Code" buildaction="Nothing" />
+ <File name="./Deveel.Pim/WebPage.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/XTag.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/XTagCollection.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/iCalParser.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/iCalParserConstants.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/iCalParserTokenManager.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/ParseException.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/SimpleCharStream.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/TokenMgrError.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/vCardParser.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/vCardParserConstants.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/vCardParserTokenManager.cs" subtype="Code" buildaction="Compile" />
+ <File name="./Deveel.Pim/ChangeLog" subtype="Code" buildaction="Compile" />
+ </Contents>
+ <References>
+ <ProjectReference type="Gac" localcopy="True" refto="System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ </References>
+</Project>
16 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim.mds
View
@@ -0,0 +1,16 @@
+<Combine name="Deveel.Pim" fileversion="2.0">
+ <Configurations active="Debug">
+ <Configuration name="Debug" ctype="CombineConfiguration">
+ <Entry build="True" name="Deveel.Pim" configuration="Debug" />
+ </Configuration>
+ <Configuration name="Release" ctype="CombineConfiguration">
+ <Entry build="True" name="Deveel.Pim" configuration="Debug" />
+ </Configuration>
+ </Configurations>
+ <StartMode startupentry="Deveel.Pim" single="True">
+ <Execute type="None" entry="Deveel.Pim" />
+ </StartMode>
+ <Entries>
+ <Entry filename="./Deveel.Pim.mdp" />
+ </Entries>
+</Combine>
99 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Address.cs
View
@@ -0,0 +1,99 @@
+//
+// Address.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Deveel.Pim {
+ public sealed class Address {
+ #region .ctor
+ public Address() {
+ postOfficeAddress = new Property();
+ roomNumber = new Property();
+ street = new Property();
+ city = new Property();
+ state = new Property();
+ postalCode = new Property();
+ country = new Property();
+ label = new Property();
+ extendedAddress = new Property();
+ }
+ #endregion
+
+ #region Fields
+ private Property postOfficeAddress;
+ private Property roomNumber;
+ private Property street;
+ private Property city;
+ private Property state;
+ private Property postalCode;
+ private Property country;
+ private Property label;
+ private Property extendedAddress;
+ #endregion
+
+ #region Properties
+ public Property PostOfficeAddress {
+ get { return postOfficeAddress; }
+ }
+
+ public Property RoomNumber {
+ get { return roomNumber; }
+ }
+
+ public Property Street {
+ get { return street; }
+ }
+
+ public Property City {
+ get { return city; }
+ }
+
+ public Property State {
+ get { return state; }
+ }
+
+ public Property PostalCode {
+ get { return postalCode; }
+ }
+
+ public Property Country {
+ get { return country; }
+ }
+
+ public Property Label {
+ get { return label; }
+ }
+
+ public Property ExtendedAddress {
+ get { return extendedAddress; }
+ }
+ #endregion
+ }
+}
214 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/BaseConverter.cs
View
@@ -0,0 +1,214 @@
+//
+// BaseConverter.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Deveel.Pim {
+ /// <summary>
+ /// Represent a converter base class. Provides some common methods.
+ /// </summary>
+ abstract class BaseConverter {
+ #region .ctor
+ public BaseConverter(TimeZone timezone, String charset) {
+ this.timezone = timezone;
+ this.charset = charset;
+ }
+ #endregion
+
+ #region Fields
+ public const string ENCODING_QT = "QUOTED-PRINTABLE";
+ public const string CHARSET_UTF8 = "UTF-8";
+ public const string ENCODING_B64 = "BASE64";
+ public const string PLAIN_CHARSET = "plain";
+
+ private TimeZone timezone = null;
+ private string charset = null;
+ #endregion
+
+ #region Properties
+ protected TimeZone TimeZone {
+ get { return timezone; }
+ }
+
+ protected string Charset {
+ get { return charset; }
+ }
+ #endregion
+
+ #region Protected Methods
+ protected string Encode(string value, string encoding, string charset) {
+ try {
+ if (value == null)
+ return null;
+
+ // If input charset is null then set it with default value as UTF-8
+ if (charset == null)
+ charset = "UTF-8";
+
+ if (encoding.Equals(ENCODING_B64)) {
+ //truncate the b64 encoded text into lines of no more that 76 chars
+ StringBuilder sb = new StringBuilder();
+ sb.Append("\r\n ");
+ while (value.Length > 75) {
+ sb.Append(value.Substring(0, 75));
+ sb.Append("\r\n");
+ sb.Append(" ");
+
+ value = value.Substring(75);
+ }
+ sb.Append(value);
+ sb.Append("\r\n");
+
+ value = sb.ToString();
+
+ } else if (encoding.Equals(ENCODING_QT)) {
+ value = QuotedPrintable.Encode(value, charset);
+ }
+
+ } catch (ArgumentException e) {
+ throw new ConverterException("The Character Encoding (" + charset + ") is not supported", e);
+ }
+
+ return value;
+ }
+
+ protected string GetEncoding(ArrayList properties) {
+ for (int i = 0; i < properties.Count; i++) {
+ if (((Property)properties[i]).Encoding != null) {
+ return ((Property)properties[i]).Encoding;
+ }
+ }
+ return null;
+ }
+
+ protected string GetCharset(ArrayList properties) {
+ for (int i = 0; i < properties.Count; i++) {
+ if (((Property)properties[i]).Charset != null) {
+ return ((Property)properties[i]).Charset;
+ }
+ }
+ return null;
+ }
+
+ protected string GetGrouping(ArrayList properties) {
+ for (int i = 0; i < properties.Count; i++) {
+ if (((Property)properties[i]).Group != null)
+ return ((Property)properties[i]).Group;
+ }
+ return null;
+ }
+
+ protected string GetLanguage(ArrayList properties) {
+ for (int i = 0; i < properties.Count; i++) {
+ if (((Property)properties[i]).Language != null) {
+ return ((Property)properties[i]).Language;
+ }
+ }
+ return null;
+ }
+
+ protected string GetValue(ArrayList properties) {
+ for (int i = 0; i < properties.Count; i++) {
+ if (((Property)properties[i]).Value != null)
+ return ((Property)properties[i]).Value;
+ }
+ return null;
+ }
+
+ protected string GetType(ArrayList properties) {
+ for (int i = 0; i < properties.Count; i++) {
+ if (((Property)properties[i]).PropertyType != null) {
+ return ((Property)properties[i]).PropertyType;
+ }
+ }
+ return null;
+ }
+
+ protected StringBuilder GetXParams(Property property) {
+ ArrayList properties = new ArrayList();
+ properties.Add(property);
+ return GetXParams(properties);
+ }
+
+ protected StringBuilder GetXParams(ArrayList properties) {
+ Hashtable hm;
+ IEnumerator it;
+ Property xtagProp;
+ string tag;
+ StringBuilder pars = new StringBuilder();
+
+ for (int i = 0; i < properties.Count; i++) {
+ xtagProp = (Property)properties[i];
+ hm = xtagProp.XParams;
+ it = hm.Keys.GetEnumerator();
+ while (it.MoveNext()) {
+ tag = (string)it.Current;
+ pars.Append(";");
+ pars.Append(tag);
+ pars.Append("=");
+ pars.Append((string)hm[tag]);
+ }
+ }
+ return pars;
+ }
+ #endregion
+
+ #region Protected Static Methods
+ protected static string HandleUTCDateConversion(string sDate, TimeZone timezone) {
+ try {
+ sDate = TimeUtils.convertLocalDateToUTC(sDate, timezone);
+ } catch (Exception) {
+ throw new ConverterException("Error handling date");
+ }
+ return sDate;
+ }
+
+ protected static string HandleLocalDateConversion(string sDate, TimeZone timezone) {
+ if (timezone == null)
+ return sDate;
+
+ try {
+ sDate = TimeUtils.convertUTCDateToLocal(sDate, timezone);
+ } catch (Exception) {
+ throw new ConverterException("Error handling date");
+ }
+
+ return sDate;
+ }
+ #endregion
+
+ #region Public Methods
+ public abstract string Convert(object obj);
+ #endregion
+ }
+}
134 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/BusinessDetail.cs
View
@@ -0,0 +1,134 @@
+//
+// BusinessDetail.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+
+namespace Deveel.Pim {
+ /// <summary>
+ /// An object containing the business details of a contact
+ /// </summary>
+ public class BusinessDetail : ContactDetail {
+ #region .ctor
+ public BusinessDetail()
+ : base() {
+ role = new Property();
+ titles = null;
+ address = new Address();
+ company = new Property();
+ department = new Property();
+ logo = new Property();
+ manager = null;
+ assistant = null;
+ officeLocation = null;
+ companies = null;
+ }
+ #endregion
+
+ #region Fields
+ private Address address;
+ private Property role;
+ private ArrayList titles;
+ private Property company; // the contact's company
+ private Property department;
+ private Property logo;
+ private String manager;
+ private String assistant;
+ private String officeLocation;
+ private String companies; // this differs from company since it is one or
+ // more companies associated to this company
+ #endregion
+
+ #region Properties
+ public Property Role {
+ get { return role; }
+ }
+
+ public ArrayList Titles {
+ get { return titles; }
+ set { titles = value; }
+ }
+
+ public void AddTitle(Title title) {
+ if (title == null) {
+ return;
+ }
+
+ if (titles == null) {
+ titles = new ArrayList();
+ }
+
+ int pos = titles.IndexOf(title);
+ if (pos < 0) {
+ titles.Add(title);
+ } else {
+ titles[pos] = title;
+ }
+ }
+
+ public Address Address {
+ get { return address; }
+ }
+
+ public Property Company {
+ get { return company; }
+ }
+
+ public Property Department {
+ get { return department; }
+ }
+
+ public string Manager {
+ get { return manager; }
+ set { manager = value; }
+ }
+
+ public string Assistant {
+ get { return assistant; }
+ set { assistant = value; }
+ }
+
+ public Property Logo {
+ get { return logo; }
+ }
+
+ public string OfficeLocation {
+ get { return officeLocation; }
+ set { officeLocation = value; }
+ }
+
+ public string Companies {
+ get { return companies; }
+ set { companies = value; }
+ }
+ #endregion
+ }
+}
41 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/BusyStatus.cs
View
@@ -0,0 +1,41 @@
+//
+// BusyStatus.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+
+namespace Deveel.Pim {
+ public enum BusyStatus {
+ Free = 0,
+ Tentative = 1,
+ Busy = 2,
+ OutOfOffice = 3
+ }
+}
94 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Calendar.cs
View
@@ -0,0 +1,94 @@
+//
+// Calendar.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.IO;
+
+namespace Deveel.Pim {
+ public class Calendar {
+ #region .ctor
+ public Calendar() {
+ calScale = new Property();
+ method = new Property();
+ prodId = new Property();
+ version = new Property();
+ calEvent = new Event();
+
+ xTags = new XTagCollection();
+ }
+ #endregion
+
+ #region Fields
+ private Property calScale;
+ private Property method;
+ private Property prodId;
+ private Property version;
+ private XTagCollection xTags;
+ private Event calEvent;
+ #endregion
+
+ #region Properties
+ public Property ProductId {
+ get { return prodId; }
+ set { prodId = value; }
+ }
+
+ public Property Version {
+ get { return version; }
+ set { version = value; }
+ }
+
+ public Property CalendarScale {
+ get { return calScale; }
+ set { calScale = value; }
+ }
+
+ public Property Method {
+ get { return method; }
+ set { method = value; }
+ }
+
+ public Event Event {
+ get { return calEvent; }
+ set { calEvent = value; }
+ }
+
+ public XTagCollection XTags {
+ get { return xTags; }
+ }
+ #endregion
+
+ public static Calendar ParseiCal(string s, string timeZone, string charset) {
+ iCalParser parser = new iCalParser(new StringReader(s), timeZone, charset);
+ return parser.iCal();
+ }
+ }
+}
742 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/CalendarConverter.cs
View
@@ -0,0 +1,742 @@
+//
+// CalendarConverter.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+using System.Globalization;
+using System.Text;
+
+namespace Deveel.Pim {
+ class CalendarConverter : BaseConverter {
+ #region .ctor
+ public CalendarConverter(TimeZone timezone, string charset)
+ : base(timezone, charset) {
+ }
+ #endregion
+
+ #region Fields
+ private const string BEGIN_VCALEN = "BEGIN:VCALENDAR\r\n";
+ private const string BEGIN_VEVENT = "BEGIN:VEVENT\r\n";
+ private const string END_VEVENT = "END:VEVENT\r\n";
+ private const string END_VCALEN = "END:VCALENDAR\r\n";
+
+ private Calendar calendar = null;
+ #endregion
+
+ #region Private Methods
+ private StringBuilder ComposeiCalTextComponent(Property property, String field) {
+ StringBuilder result = new StringBuilder(240); // Estimate 240 is needed
+ result.Append(field);
+ string propertyValue = property.Value;
+
+ try {
+ //
+ // Encode value as QUOTED-PRINTABLE and set encodingParam at the
+ // default value (at the moment we handle only ENCODING=QUOTED-PRINTABLE)
+ //
+ String encodingParam = ENCODING_QT;
+ String charsetParam = property.Charset;
+ if (charsetParam == null) {
+ if (Charset == null) {
+ charsetParam = CHARSET_UTF8;
+ } else {
+ charsetParam = Charset;
+ }
+ }
+
+ if (propertyValue == null) {
+ propertyValue = "";
+ } else {
+ if (String.Compare(PLAIN_CHARSET, charsetParam, true) != 0) {
+ //
+ // We encode the value only if the charset isn't PLAIN_CHARSET
+ //
+ propertyValue = Encode(propertyValue, encodingParam,
+ charsetParam);
+
+ if (propertyValue.IndexOf("=") != -1) {
+ result.Append(";ENCODING=").Append(encodingParam);
+ result.Append(";CHARSET=").Append(charsetParam);
+ }
+ }
+ }
+
+ string altrepParam = property.AlternateText;
+ if (altrepParam != null) {
+ result.Append(";ALTREP=");
+ result.Append(altrepParam);
+ }
+
+ string languageParam = property.Language;
+ if (languageParam != null) {
+ result.Append(";LANGUAGE=");
+ result.Append(languageParam);
+ }
+
+ string cnParam = property.CommonName;
+ if (cnParam != null) {
+ result.Append(";CN=");
+ result.Append(cnParam);
+ }
+
+ string cuttypeParam = property.CalendarUserType;
+ if (cuttypeParam != null) {
+ result.Append(";CUTYPE=");
+ result.Append(cuttypeParam);
+ }
+
+ string delegatedFromParam = property.DelegatedFrom;
+ if (delegatedFromParam != null) {
+ result.Append(";DELEGATED-FROM=");
+ result.Append(delegatedFromParam);
+ }
+
+ string delegatedToParam = property.DelegatedTo;
+ if (delegatedToParam != null) {
+ result.Append(";DELEGATED-TO=");
+ result.Append(delegatedToParam);
+ }
+
+ string dirParam = property.Directory;
+ if (dirParam != null) {
+ result.Append(";DIR=");
+ result.Append(dirParam);
+ }
+
+ string memberParam = property.Member;
+ if (memberParam != null) {
+ result.Append(";MEMBER=");
+ result.Append(memberParam);
+ }
+
+ string partstatParam = property.PartecipationStatus;
+ if (partstatParam != null) {
+ result.Append(";PARTSTAT=");
+ result.Append(partstatParam);
+ }
+
+ string relatedParam = property.Related;
+ if (relatedParam != null) {
+ result.Append(";RELATED=");
+ result.Append(relatedParam);
+ }
+
+ string sentbyParam = property.SentBy;
+ if (sentbyParam != null) {
+ result.Append(";SENT-BY=\"");
+ result.Append(sentbyParam).Append("\"");
+ }
+
+ string valueParam = property.Value;
+ if (valueParam != null) {
+ result.Append(";VALUE=");
+ result.Append(valueParam);
+ }
+
+ result.Append(GetXParams(property));
+
+ result.Append(":");
+ result.Append(propertyValue);
+ result.Append("\r\n");
+ } catch (Exception e) {
+ throw new ConverterException("Error to compose iCalendar component ", e);
+ }
+
+ return result;
+ }
+
+ // X-PROP:
+ private StringBuilder ComposeFieldXTag(XTagCollection xTags) {
+ StringBuilder output = new StringBuilder();
+
+ if (xTags == null || xTags.Count == 0)
+ return output;
+
+ Property xtag = null;
+ string value;
+
+ int size = xTags.Count;
+ for (int i = 0; i < size; i++) {
+
+ XTag xtagObj = xTags[i];
+
+ xtag = xtagObj.Tag;
+ value = xtag.Value;
+
+ output.Append(ComposeiCalTextComponent(xtag, xtagObj.TagValue));
+ }
+ return output;
+ }
+
+ // Added X-Param to the input list of the property parameters
+ // The buffer iterates throguh the parameters and adds the
+ // start parameter char ';' and then the parameter.
+ // Avoids the add the starting ';' by the caller and delete
+ // the trailing ';' here.
+ private void AddXParams(StringBuilder paramList, Property prop) {
+ if (prop.XParams != null && prop.XParams.Count > 0) {
+ foreach (DictionaryEntry entry in prop.XParams) {
+ paramList.Append(";");
+ paramList.Append(entry.Key); // the tag
+ paramList.Append("=\"");
+ paramList.Append(entry.Value);
+ paramList.Append("\"");
+ }
+ }
+ }
+
+ private StringBuilder ComposeFieldCalscale(Property calscale) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (calscale.Value != null) {
+ result.Append("CALSCALE");
+ AddXParams(result, calscale);
+ result.Append(':');
+ result.Append(calscale.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldMethod(Property method) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (method.Value != null) {
+ result.Append("METHOD");
+ AddXParams(result, method);
+ result.Append(':');
+ result.Append(method.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldProdId(Property prodid) {
+ if (prodid.Value == null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(prodid, "PRODID");
+ }
+
+ private StringBuilder ComposeFieldVersion(Property version) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (version.Value != null) {
+ result.Append("VERSION");
+ AddXParams(result, version);
+ result.Append(":");
+ result.Append(version.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldCategories(Property categories) {
+ if (categories.Value == null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(categories, "CATEGORIES");
+ }
+
+ private StringBuilder ComposeFieldClass(Property classEvent) {
+ if (classEvent.Value == null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(classEvent, "CLASS");
+ }
+
+ private StringBuilder ComposeFieldDescription(Property description) {
+ if (description.Value != null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(description, "DESCRIPTION");
+ }
+
+ private StringBuilder ComposeFieldGeo(Property latitude, Property longitude) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+
+ string outLat = latitude.Value;
+ string outLon = longitude.Value;
+
+ if (outLat != null && outLon != null) {
+ result.Append("GEO");
+ AddXParams(result, latitude);
+ AddXParams(result, longitude);
+ result.Append(":");
+ result.Append(outLat);
+ result.Append(";");
+ result.Append(outLon);
+ result.Append("\r\n");
+ }
+
+ return result;
+ }
+
+ private StringBuilder ComposeFieldLocation(Property location) {
+ if (location.Value != null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(location, "LOCATION");
+ }
+
+ private StringBuilder ComposeFieldPriority(Property priority) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (priority.Value != null) {
+ result.Append("PRIORITY");
+ AddXParams(result, priority);
+ result.Append(":");
+ result.Append(priority.Value);
+ result.Append("\r\n");
+ }
+
+ return result;
+ }
+
+ private StringBuilder ComposeFieldStatus(Property status) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (status.Value != null) {
+ result.Append("STATUS");
+ AddXParams(result, status);
+ result.Append(":");
+ result.Append(status.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldSummary(Property summary) {
+ if (summary.Value != null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(summary, "SUMMARY");
+ }
+
+ private StringBuilder ComposeFieldDtEnd(Property dtEnd) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (dtEnd.Value != null) {
+ result.Append("DTEND");
+
+ string valueParam = dtEnd.Value;
+ if (valueParam != null) {
+ result.Append(";VALUE=");
+ result.Append(valueParam);
+ }
+
+ AddXParams(result, dtEnd);
+
+ string dtEndVal = dtEnd.Value;
+
+ if (TimeUtils.isInAllDayFormat(dtEndVal))
+ dtEndVal = TimeUtils.convertDateFromInDayFormat(dtEndVal, "235900");
+
+ dtEndVal = HandleLocalDateConversion(dtEndVal, TimeZone);
+ result.Append(":");
+ result.Append(dtEndVal);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldDtStart(Property dtStart) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (dtStart.Value != null) {
+ result.Append("DTSTART");
+
+ String valueParam = dtStart.Value;
+ if (valueParam != null) {
+ result.Append(";VALUE=");
+ result.Append(valueParam);
+ }
+
+ AddXParams(result, dtStart);
+
+ string dtStartVal = dtStart.Value;
+
+ if (TimeUtils.isInAllDayFormat(dtStartVal))
+ dtStartVal = TimeUtils.convertDateFromInDayFormat(dtStartVal, "000000");
+
+ dtStartVal = HandleLocalDateConversion(dtStartVal, TimeZone);
+ result.Append(":");
+ result.Append(dtStartVal);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+
+ private StringBuilder ComposeFieldTransp(Property transp) {
+ if (transp.Value == null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(transp, "TRANSP");
+ }
+
+ private StringBuilder ComposeFieldOrganizer(Property org) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (org.Value != null) {
+ result.Append("ORGANIZER");
+
+ //building a properties string
+ string cnParam = org.CommonName;
+ string dirParam = org.Directory;
+ string sentbyParam = org.SentBy;
+ string languageParam = org.Language;
+
+ if (cnParam != null) {
+ result.Append(";CN=");
+ result.Append(cnParam);
+ }
+
+ if (dirParam != null) {
+ result.Append(";DIR=");
+ result.Append(dirParam);
+ }
+
+ if (sentbyParam != null) {
+ result.Append(";SENT-BY=\"");
+ result.Append(sentbyParam);
+ result.Append("\"");
+ }
+
+ if (languageParam != null) {
+ result.Append(";LANGUAGE=");
+ result.Append(languageParam);
+ }
+
+ AddXParams(result, org);
+ result.Append(":");
+ result.Append(org.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldUrl(Property url) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (url.Value != null) {
+ result.Append("URL");
+ AddXParams(result, url);
+ result.Append(":");
+ result.Append(url.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldUid(Property uid) {
+ if (uid.Value != null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(uid, "UID");
+ }
+
+ private StringBuilder ComposeFieldRrule(Property rrule) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (rrule.Value != null) {
+ result.Append("RRULE");
+ AddXParams(result, rrule);
+ result.Append(":");
+ result.Append(rrule.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldContact(Property contact) {
+ if (contact.Value != null)
+ return new StringBuilder(0);
+
+ return ComposeiCalTextComponent(contact, "CONTACT");
+ }
+
+ private StringBuilder composeFieldCreated(Property created) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (created.Value != null) {
+ result.Append(created.Tag);
+ AddXParams(result, created);
+
+ string createdVal = created.Value;
+ createdVal = HandleLocalDateConversion(createdVal, TimeZone);
+
+ result.Append(":");
+ result.Append(createdVal);
+ result.Append("\r\n");
+ }
+
+ return result;
+ }
+
+ private StringBuilder ComposeFieldDtstamp(Property dtStamp) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (dtStamp.Value != null) {
+ result.Append("DTSTAMP");
+ AddXParams(result, dtStamp);
+
+ String dtStampVal = dtStamp.Value;
+ dtStampVal = HandleLocalDateConversion(dtStampVal, TimeZone);
+
+ result.Append(":");
+ result.Append(dtStampVal);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldLastModified(Property lastModified) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (lastModified.Value != null) {
+ result.Append("LAST-MODIFIED");
+ AddXParams(result, lastModified);
+ result.Append(":");
+
+ string lastModifiedVal = lastModified.Value;
+ lastModifiedVal = HandleLocalDateConversion(lastModifiedVal, TimeZone);
+ result.Append(lastModifiedVal);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldSequence(Property sequence) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (sequence.Value != null) {
+ result.Append("SEQUENCE");
+ AddXParams(result, sequence);
+ result.Append(":");
+ result.Append(sequence.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldDAlarm(Property dalarm) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (dalarm.Value != null) {
+ result.Append("DALARM");
+ AddXParams(result, dalarm);
+ result.Append(":");
+ result.Append(dalarm.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldPAlarm(Property palarm) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ if (palarm.Value != null) {
+ result.Append("PALARM");
+ AddXParams(result, palarm);
+ result.Append(":");
+ result.Append(palarm.Value);
+ result.Append("\r\n");
+ }
+ return result;
+ }
+
+ private StringBuilder ComposeFieldReminder(Property dtStart, Reminder reminder) {
+ StringBuilder result = new StringBuilder(60); // Estimate 60 is needed
+ result.Append("AALARM");
+
+ string typeParam = reminder.PropertyType;
+ if (typeParam != null) {
+ result.Append(";TYPE=");
+ result.Append(typeParam);
+ }
+
+ string valueParam = reminder.Value;
+ if (valueParam != null) {
+ result.Append(";VALUE=");
+ result.Append(valueParam);
+ }
+
+ AddXParams(result, reminder);
+
+ DateTime dateStart;
+
+ string dtStartVal = dtStart.Value;
+ dtStartVal = HandleLocalDateConversion(dtStartVal, TimeZone);
+
+ try {
+ dateStart = DateTime.ParseExact(dtStartVal, TimeUtils.getDateFormat(dtStartVal), CultureInfo.InvariantCulture);
+ } catch (FormatException) {
+ //is not possible
+ //TODO: what to do now?
+ dateStart = DateTime.Now;
+ }
+
+ DateTime dtAlarm = dateStart.AddMinutes(-reminder.Minutes);
+ String dtAlarmVal = dtAlarm.ToString("yyyyMMdd'T'HHmmss'Z'");
+
+ result.Append(":");
+ result.Append(dtAlarmVal);
+ result.Append(";");
+
+ if (reminder.Interval != 0)
+ result.Append(TimeUtils.getIso8601Duration(reminder.Interval.ToString()));
+
+ result.Append(";");
+ result.Append(reminder.RepeatCount);
+
+ result.Append(";");
+ if (reminder.SoundFile != null)
+ result.Append(reminder.SoundFile);
+
+ result.Append("\r\n");
+
+ return result;
+ }
+ #endregion
+
+ #region Public Methods
+ public override string Convert(Object obj) {
+ calendar = (Calendar)obj;
+
+ StringBuilder output = new StringBuilder(BEGIN_VCALEN);
+
+ if (calendar.CalendarScale != null) {
+ output.Append(ComposeFieldCalscale(calendar.CalendarScale));
+ }
+ if (calendar.Method != null) {
+ output.Append(ComposeFieldMethod(calendar.Method));
+ }
+ if (calendar.ProductId != null) {
+ output.Append(ComposeFieldProdId(calendar.ProductId));
+ }
+ if (calendar.Version != null) {
+ output.Append(ComposeFieldVersion(calendar.Version));
+ }
+ // X-PROP
+ output.Append(ComposeFieldXTag(calendar.XTags));
+
+ //
+ // VEVENT
+ //
+ if (calendar.Event != null) {
+ output.Append(BEGIN_VEVENT);
+
+ if (calendar.Event.Categories != null) {
+ output.Append(ComposeFieldCategories(calendar.Event.Categories));
+ }
+ if (calendar.Event.ClassEvent != null) {
+ output.Append(ComposeFieldClass(calendar.Event.ClassEvent));
+ }
+ if (calendar.Event.Description != null) {
+ output.Append(ComposeFieldDescription(calendar.Event.Description));
+ }
+ if (calendar.Event.Latitude != null ||
+ calendar.Event.Longitude != null) {
+ output.Append(ComposeFieldGeo(calendar.Event.Latitude,
+ calendar.Event.Longitude
+ ));
+ }
+ if (calendar.Event.Location != null) {
+ output.Append(ComposeFieldLocation(calendar.Event.Location));
+ }
+ if (calendar.Event.Priority != null) {
+ output.Append(ComposeFieldPriority(calendar.Event.Priority));
+ }
+ if (calendar.Event.Status != null) {
+ output.Append(ComposeFieldStatus(calendar.Event.Status));
+ }
+ if (calendar.Event.Summary != null) {
+ output.Append(ComposeFieldSummary(calendar.Event.Summary));
+ }
+ if (calendar.Event.DateEnd != null) {
+ output.Append(ComposeFieldDtEnd(
+ calendar.Event.DateEnd));
+ }
+ if (calendar.Event.DateStart != null) {
+ output.Append(ComposeFieldDtStart(
+ calendar.Event.DateStart));
+ }
+
+ //
+ // NOTE: We decided not to store the duration but only Start and End
+ //
+
+ if (calendar.Event.Transport != null) {
+ output.Append(ComposeFieldTransp(calendar.Event.Transport));
+ }
+ if (calendar.Event.Organizer != null) {
+ output.Append(ComposeFieldOrganizer(calendar.Event.Organizer));
+ }
+ if (calendar.Event.Url != null) {
+ output.Append(ComposeFieldUrl(calendar.Event.Url));
+ }
+ if (calendar.Event.UID != null) {
+ output.Append(ComposeFieldUid(calendar.Event.UID));
+ }
+ if (calendar.Event.Rrule != null) {
+ output.Append(ComposeFieldRrule(calendar.Event.Rrule));
+ }
+ if (calendar.Event.Created != null) {
+ output.Append(composeFieldCreated(
+ calendar.Event.Created));
+ }
+ if (calendar.Event.DateStamp != null) {
+ output.Append(ComposeFieldDtstamp(
+ calendar.Event.DateStamp));
+ }
+ if (calendar.Event.LastModified != null) {
+ output.Append(ComposeFieldLastModified(
+ calendar.Event.LastModified));
+ }
+ if (calendar.Event.Sequence != null) {
+ output.Append(ComposeFieldSequence(calendar.Event.Sequence));
+ }
+ if (calendar.Event.Contact != null) {
+ output.Append(this.ComposeFieldContact(calendar.Event.Contact));
+ }
+ if (calendar.Event.DisplayAlarm != null) {
+ output.Append(ComposeFieldDAlarm(calendar.Event.DisplayAlarm));
+ }
+ if (calendar.Event.ProcedureAlarm != null) {
+ output.Append(ComposeFieldPAlarm(calendar.Event.ProcedureAlarm));
+ }
+ if (calendar.Event.Reminder != null &&
+ calendar.Event.Reminder.IsActive) {
+ output.Append(
+ ComposeFieldReminder(calendar.Event.DateStart,
+ calendar.Event.Reminder
+ )
+ );
+ }
+
+ // X-PROP
+ XTagCollection eventXTag = calendar.Event.XTags;
+ output.Append(ComposeFieldXTag(eventXTag));
+
+ output.Append(END_VEVENT);
+ }
+ output.Append(END_VCALEN);
+
+ return output.ToString();
+ }
+ #endregion
+ }
+}
220 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Contact.cs
View
@@ -0,0 +1,220 @@
+//
+// Contact.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+using System.IO;
+using System.Text;
+
+namespace Deveel.Pim {
+ /// <summary>
+ /// An object representing a contact.
+ /// </summary>
+ /// <remarks>
+ /// This class can be used to store and retrive such information as contact name,
+ /// telephone number, address and so on.
+ /// </remarks>
+ public sealed class Contact {
+ #region .ctor
+ public Contact() {
+ name = new Name();
+
+ notes = null;
+ xTags = null;
+
+ businessDetail = new BusinessDetail();
+ personalDetail = new PersonalDetail();
+ categories = new Property();
+ }
+ #endregion
+
+ #region Fields
+ private Name name;
+ private ArrayList notes;
+ private string uid;
+ private string timezone;
+ private string revision;
+ private BusinessDetail businessDetail;
+ private PersonalDetail personalDetail;
+ private ArrayList xTags;
+ private Property categories;
+ private string languages;
+ private short importance;
+ private short sensitivity;
+ private string subject;
+ private int mileage;
+ private string folder;
+ #endregion
+
+ #region Properties
+ public string UID {
+ get { return uid; }
+ set { uid = value; }
+ }
+
+ public string TimeZone {
+ get { return timezone; }
+ set { timezone = value; }
+ }
+
+ public ArrayList Notes {
+ get { return notes; }
+ set { notes = value; }
+ }
+
+ public ArrayList XTags {
+ get { return xTags; }
+ set { xTags = value; }
+ }
+
+ public string Revision {
+ get { return revision; }
+ set { revision = value; }
+ }
+
+ public Name Name {
+ get { return name; }
+ set { name = value; }
+ }
+
+ public BusinessDetail BusinessDetail {
+ get { return businessDetail; }
+ set { businessDetail = value; }
+ }
+
+ public PersonalDetail PersonalDetail {
+ get { return personalDetail; }
+ set { personalDetail = value; }
+ }
+
+ public Property Categories {
+ set { categories = value; }
+ get { return categories; }
+ }
+
+ public string Languages {
+ get { return languages; }
+ set { languages = value; }
+ }
+
+ public short Importance {
+ get { return importance; }
+ set { importance = value; }
+ }
+
+ public short Sensitivity {
+ get { return sensitivity; }
+ set { sensitivity = value; }
+ }
+
+ public string Subject {
+ get { return subject; }
+ set { subject = value; }
+ }
+
+ public int Mileage {
+ get { return mileage; }
+ set { mileage = value; }
+ }
+
+ public string Folder {
+ get { return folder; }
+ set { folder = value; }
+ }
+ #endregion
+
+ public void AddNote(Note note) {
+ if (note == null) {
+ return;
+ }
+
+ if (notes == null) {
+ notes = new ArrayList();
+ }
+
+ int pos = notes.IndexOf(note);
+ if (pos < 0) {
+ notes.Add(note);
+ } else {
+ notes[pos] = note;
+ }
+ }
+
+ public void AddXTag(XTag tag) {
+ if (tag == null)
+ return;
+
+ if (xTags == null)
+ xTags = new ArrayList();
+
+ int pos = xTags.IndexOf(tag);
+ if (pos < 0) {
+ xTags.Add(tag);
+ } else {
+ xTags[pos] = tag;
+ }
+ }
+
+ public string TovCardString(string timeZone, string charset) {
+ return TovCardString(Deveel.Pim.TimeZone.GetTimeZone(timeZone), charset);
+ }
+
+ public string TovCardString(string timeZone) {
+ return TovCardString(timeZone, Encoding.Default.EncodingName);
+ }
+
+ public string TovCardString() {
+ return TovCardString("GMT");
+ }
+
+ public string TovCardString(TimeZone timeZone, string charset) {
+ ContactConverter convert = new ContactConverter(timeZone, charset);
+ return convert.Convert(this);
+ }
+
+ public string TovCardString(TimeZone timeZone) {
+ return TovCardString(timeZone, Encoding.Default.EncodingName);
+ }
+
+ public static Contact ParsevCard(string s, string timeZone, string charset) {
+ vCardParser parser = new vCardParser(new StringReader(s), timeZone, charset);
+ return parser.vCard();
+ }
+
+ public static Contact ParsevCard(string s, string timeZone) {
+ return ParsevCard(s, timeZone, Encoding.Default.EncodingName);
+ }
+
+ public static Contact ParsevCard(string s) {
+ return ParsevCard(s, "GMT");
+ }
+ }
+}
698 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ContactConverter.cs
View
@@ -0,0 +1,698 @@
+//
+// ContactConverter.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Collections;
+using System.Text;
+
+namespace Deveel.Pim {
+ /// <summary>
+ /// This object is a converter from a Contact object model to a vCard string
+ /// </summary>
+ class ContactConverter : BaseConverter {
+ #region .ctor
+ public ContactConverter(TimeZone timezone, string charset)
+ : base(timezone, charset) {
+ }
+ #endregion
+
+ #region Fields
+ private static int INITIAL_CAPACITY = 1024; // 1 K bytes
+ #endregion
+
+ #region Private Methods
+ private StringBuilder ComposevCardComponent(string propertyValue, ArrayList properties, string field) {
+ StringBuilder result = new StringBuilder(120);
+
+ try {
+ string group = GetGrouping(properties);
+ if (group != null) {
+ result.Append(group);
+ result.Append(".");
+ }
+
+ result.Append(field);
+
+ string encodingParam = GetEncoding(properties);
+ if (encodingParam == null)
+ encodingParam = ENCODING_QT;
+
+ string charsetParam = GetCharset(properties);
+ if (charsetParam == null) {
+ if (Charset == null) {
+ charsetParam = CHARSET_UTF8;
+ } else {
+ charsetParam = Charset;
+ }
+ }
+
+ if (propertyValue == null) {
+ propertyValue = "";
+ } else {
+ if (String.Compare(PLAIN_CHARSET, charsetParam, true) != 0) {
+ // We encode the value only if the charset isn't PLAIN_CHARSET
+ //
+ // At this level we have always an ENCODING (at least QP)
+ propertyValue = Encode(propertyValue, encodingParam, charsetParam);
+
+ // We set the ENCODING and the CHARSET only if:
+ // 1. we are using the QP and the result doesn't contain any '='
+ // (the value doesn't contain chars to encode)
+ // or
+ // 2. we have a different encoding from QP
+ // (in this way we preserve the original property encoding)
+ if (String.Compare(ENCODING_QT, encodingParam, true) == 0 &&
+ propertyValue.IndexOf("=") != -1) {
+ result.Append(";ENCODING=");
+ result.Append(encodingParam);
+ result.Append(";CHARSET=");
+ result.Append(charsetParam);
+ } else if (String.Compare(ENCODING_QT, encodingParam, true) != 0) {
+ result.Append(";ENCODING=");
+ result.Append(encodingParam);
+ result.Append(";CHARSET=");
+ result.Append(charsetParam);
+ }
+ }
+ }
+
+ string languageParam = GetLanguage(properties);
+ if (languageParam != null) {
+ result.Append(";LANGUAGE=");
+ result.Append(languageParam);
+ }
+
+ string valueParam = GetValue(properties);
+ if (valueParam != null) {
+ result.Append(";VALUE=");
+ result.Append(valueParam);
+ }
+
+ string typeParam = GetType(properties);
+ if (typeParam != null) {
+ result.Append(";TYPE=");
+ result.Append(typeParam);
+ }
+
+ result.Append(GetXParams(properties));
+
+ result.Append(":");
+ result.Append(propertyValue);
+ result.Append("\r\n");
+ } catch (Exception e) {
+ throw new ConverterException("Error to compose vCard component ", e);
+ }
+
+ return result;
+ }
+
+ private StringBuilder ComposeFieldCategories(Property categories) {
+ if (categories.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(categories);
+
+ return ComposevCardComponent(categories.Value, properties, "CATEGORIES");
+ }
+
+ private StringBuilder ComposeFieldName(Name name) {
+ if (name.LastName.Value == null &&
+ name.FirstName.Value == null &&
+ name.MiddleName.Value == null &&
+ name.Salutation.Value == null &&
+ name.Suffix.Value == null) {
+ return new StringBuilder(0);
+ }
+
+ //TODO: optimize this to avoid inserting ';' character too many times...
+
+ StringBuilder output = new StringBuilder(120); // Estimate 120 as needed
+ ArrayList properties = new ArrayList();
+
+ if (name.LastName.Value != null) {
+ output.Append(name.LastName.Value);
+ properties.Add(name.LastName);
+ }
+
+ output.Append(";");
+
+ if (name.FirstName.Value != null) {
+ output.Append(name.FirstName.Value);
+ properties.Add(name.FirstName);
+ }
+
+ output.Append(";");
+
+ if (name.MiddleName.Value != null) {
+ output.Append(name.MiddleName.Value);
+ properties.Add(name.MiddleName);
+ }
+
+ output.Append(";");
+
+ if (name.Salutation.Value != null) {
+ output.Append(name.Salutation.Value);
+ properties.Add(name.Salutation);
+ }
+
+ output.Append(";");
+
+ if (name.Suffix.Value != null) {
+ output.Append(name.Suffix.Value);
+ properties.Add(name.Suffix);
+ }
+
+ return ComposevCardComponent(output.ToString(), properties, "N");
+ }
+
+ private StringBuilder ComposeFieldFormalName(Property displayName) {
+ if (displayName.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(displayName);
+
+ return ComposevCardComponent(displayName.Value, properties, "FN");
+ }
+
+ private StringBuilder ComposeFieldNickname(Property nickname) {
+ if (nickname.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(nickname);
+
+ return ComposevCardComponent(nickname.Value, properties, "NICKNAME");
+ }
+
+ private StringBuilder ComposeFieldAddress(Address address, String type) {
+ if ((address == null) ||
+ (address.PostOfficeAddress.Value == null &&
+ address.RoomNumber.Value == null &&
+ address.Street.Value == null &&
+ address.City.Value == null &&
+ address.State.Value == null &&
+ address.PostalCode.Value == null &&
+ address.Country.Value == null &&
+ address.ExtendedAddress.Value == null)) {
+ return new StringBuilder(0);
+ }
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ //TODO: optimize this to avoid inserting ';' character too many times...
+
+ if (address.PostOfficeAddress.Value != null) {
+ output.Append(address.PostOfficeAddress.Value);
+ properties.Add(address.PostOfficeAddress);
+ }
+
+ output.Append(";");
+ if (address.ExtendedAddress.Value != null) {
+ output.Append(address.ExtendedAddress.Value);
+ properties.Add(address.ExtendedAddress);
+ }
+
+ output.Append(";");
+ if (address.Street.Value != null) {
+ output.Append(address.Street.Value);
+ properties.Add(address.Street);
+ }
+
+ output.Append(";");
+ if (address.City.Value != null) {
+ output.Append(address.City.Value);
+ properties.Add(address.City);
+ }
+
+ output.Append(";");
+ if (address.State.Value != null) {
+ output.Append(address.State.Value);
+ properties.Add(address.State);
+ }
+
+ output.Append(";");
+ if (address.PostalCode.Value != null) {
+ output.Append(address.PostalCode.Value);
+ properties.Add(address.PostalCode);
+ }
+
+ output.Append(";");
+ if (address.Country.Value != null) {
+ output.Append(address.Country.Value);
+ properties.Add(address.Country);
+ }
+
+ if (type.Equals("HOME")) {
+ return ComposevCardComponent(output.ToString(), properties, "ADR;HOME");
+ } else if (type.Equals("OTHER")) {
+ return ComposevCardComponent(output.ToString(), properties, "ADR");
+ } else if (type.Equals("WORK")) {
+ return ComposevCardComponent(output.ToString(), properties, "ADR;WORK");
+ }
+
+ return new StringBuilder(0);
+ }
+
+ private StringBuilder ComposeFieldPhoto(Property photo) {
+ if (photo.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(photo);
+
+ return ComposevCardComponent(photo.Value, properties, "PHOTO");
+ }
+
+ private string ComposeFieldBirthday(String birthday) {
+ if (birthday == null)
+ return String.Empty;
+
+ try {
+ birthday = TimeUtils.NormalizeToISO8601(birthday, TimeZone);
+ } catch (Exception ex) {
+ throw new ConverterException("Error parsing birthday", ex);
+ }
+
+ return ("BDAY:" + birthday + "\r\n");
+ }
+
+ private string ComposeFieldTelephone(PropertyCollection phones) {
+ if (phones == null || phones.Count == 0)
+ return String.Empty;
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ int size = phones.Count;
+ for (int i = 0; i < size; i++) {
+ Phone telephone = (Phone)phones[i];
+ string phoneType = ComposePhoneType(telephone.PhoneType);
+
+ properties.Clear();
+ properties.Insert(0, telephone);
+
+ output.Append(ComposevCardComponent(telephone.Value, properties, "TEL" + phoneType));
+ }
+
+ return output.ToString();
+ }
+
+ private string ComposePhoneType(string type) {
+ if (type == null)
+ return String.Empty;
+
+ // Mobile phone
+ if (type.Equals("MobileTelephoneNumber")) {
+ return ";CELL";
+ } else if (type.Equals("MobileHomeTelephoneNumber")) {
+ return ";CELL;HOME";
+ } else if (type.Equals("MobileBusinessTelephoneNumber")) {
+ return ";CELL;WORK";
+ }
+
+ // Voice
+ if (type.Equals("OtherTelephoneNumber")) {
+ return ";VOICE";
+ } else if (type.Equals("HomeTelephoneNumber")) {
+ return ";VOICE;HOME";
+ } else if (type.Equals("BusinessTelephoneNumber")) {
+ return ";VOICE;WORK";
+ }
+
+ // FAX
+ if (type.Equals("OtherFaxNumber")) {
+ return ";FAX";
+ } else if (type.Equals("HomeFaxNumber")) {
+ return ";FAX;HOME";
+ } else if (type.Equals("BusinessFaxNumber")) {
+ return ";FAX;WORK";
+ }
+
+ // Pager
+ if (type.Equals("PagerNumber")) {
+ return ";PAGER";
+ }
+
+ for (int j = 2; j <= 10; j++) {
+ // Mobile phone
+ if (type.Equals("Mobile" + j + "TelephoneNumber")) {
+ return ";CELL";
+ } else if (type.Equals("MobileHome" + j + "TelephoneNumber")) {
+ return ";CELL;HOME";
+ } else if (type.Equals("MobileBusiness" + j + "TelephoneNumber")) {
+ return (";CELL;WORK");
+ }
+
+ // Voice
+ if (type.Equals("Other" + j + "TelephoneNumber")) {
+ return ";VOICE";
+ } else if (type.Equals("Home" + j + "TelephoneNumber")) {
+ return ";VOICE;HOME";
+ } else if (type.Equals("Business" + j + "TelephoneNumber")) {
+ return ";VOICE;WORK";
+ }
+
+ // Fax
+ if (type.Equals("Other" + j + "FaxNumber")) {
+ return ";FAX";
+ } else if (type.Equals("Home" + j + "FaxNumber")) {
+ return ";FAX;HOME";
+ } else if (type.Equals("Business" + j + "FaxNumber")) {
+ return ";FAX;WORK";
+ }
+
+ // Pager
+ if (type.Equals("PagerNumber" + j)) {
+ return (";PAGER");
+ }
+ }
+
+ // Others
+ if (type.Equals("CarTelephoneNumber")) {
+ return ";CAR;VOICE";
+ } else if (type.Equals("CompanyMainTelephoneNumber")) {
+ return ";WORK;PREF";
+ } else if (type.Equals("PrimaryTelephoneNumber")) {
+ return ";PREF;VOICE";
+ }
+
+ return String.Empty;
+ }
+
+ private string ComposeFieldEmail(PropertyCollection emails) {
+ if (emails == null || emails.Count == 0)
+ return String.Empty;
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ int size = emails.Count;
+ for (int i = 0; i < size; i++) {
+
+ Email email = (Email)emails[i];
+ string emailType = ComposeEmailType(email.EmailType);
+
+ properties.Clear();
+ properties.Add(email);
+
+ output.Append(ComposevCardComponent(email.Value, properties, "EMAIL" + emailType));
+ }
+
+ return output.ToString();
+ }
+
+ private string ComposeEmailType(String type) {
+ if (type == null)
+ return String.Empty;
+
+ if (type.Equals("Email1Address")) {
+ return ";INTERNET";
+ } else if (type.Equals("Email2Address")) {
+ return ";INTERNET;HOME";
+ } else if (type.Equals("Email3Address")) {
+ return ";INTERNET;WORK";
+ }
+
+ for (int j = 2; j <= 10; j++) {
+ if (type.Equals("Other" + j + "EmailAddress")) {
+ return ";INTERNET";
+ } else if (type.Equals("HomeEmail" + j + "Address")) {
+ return ";INTERNET;HOME";
+ } else if (type.Equals("BusinessEmail" + j + "Address")) {
+ return ";INTERNET;WORK";
+ }
+ }
+
+ return String.Empty;
+ }
+
+ private string ComposeFieldWebPage(PropertyCollection webpages) {
+ if (webpages == null || webpages.Count == 0)
+ return String.Empty;
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ int size = webpages.Count;
+ for (int i = 0; i < size; i++) {
+
+ WebPage address = (WebPage)webpages[i];
+ string webpageType = ComposeWebPageType(address.WebPageType);
+
+ properties.Insert(0, address);
+
+ output.Append(ComposevCardComponent(address.Value, properties, webpageType));
+ }
+
+ return output.ToString();
+ }
+
+ private string ComposeWebPageType(String type) {
+ if (type == null) {
+ return String.Empty;
+ } else if (type.Equals("WebPage")) {
+ return "URL";
+ } else if (type.Equals("HomeWebPage")) {
+ return "URL;HOME";
+ } else if (type.Equals("BusinessWebPage")) {
+ return "URL;WORK";
+ }
+
+ for (int j = 2; j <= 10; j++) {
+ if (type.Equals("WebPage" + j)) {
+ return "URL";
+ } else if (type.Equals("Home" + j + "WebPage")) {
+ return "URL;HOME";
+ } else if (type.Equals("Business" + j + "WebPage")) {
+ return "URL;WORK";
+ }
+ }
+
+ return String.Empty;
+ }
+
+ private StringBuilder ComposeFieldPersonalLabel(Property label) {
+ if (label.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(label);
+
+ return ComposevCardComponent(label.Value, properties, "LABEL;HOME");
+ }
+
+ private StringBuilder ComposeFieldOtherLabel(Property label) {
+ if (label.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(label);
+
+ return ComposevCardComponent(label.Value, properties, "LABEL;OTHER");
+ }
+
+ private StringBuilder ComposeFieldBusinessLabel(Property label) {
+ if (label.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(label);
+
+ return ComposevCardComponent(label.Value, properties, "LABEL;WORK");
+ }
+
+ private StringBuilder ComposeFieldRole(Property role) {
+ if (role.Value == null)
+ return new StringBuilder(0);
+
+ ArrayList properties = new ArrayList();
+ properties.Add(role);
+
+ return ComposevCardComponent(role.Value, properties, "ROLE");
+ }
+
+ private string ComposeFieldTitle(ArrayList titles) {
+ if (titles == null || titles.Count == 0)
+ return String.Empty;
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ int size = titles.Count;
+ for (int i = 0; i < size; i++) {
+ Title title = (Title)titles[i];
+ properties.Insert(0, title);
+
+ output.Append(ComposevCardComponent(title.Value, properties, "TITLE"));
+ }
+
+ return output.ToString();
+ }
+
+ private StringBuilder ComposeFieldOrg(Property company, Property department) {
+ if (company.Value == null && department.Value == null)
+ return new StringBuilder(0);
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ if (company.Value != null) {
+ output.Append(company.Value);
+ properties.Add(company);
+ }
+
+ output.Append(";");
+
+ if (department.Value != null) {
+ output.Append(department.Value);
+ properties.Add(department);
+ }
+
+ return ComposevCardComponent(output.ToString(), properties, "ORG");
+ }
+
+ private string ComposeFieldXTag(ArrayList xTags) {
+ if (xTags == null || xTags.Count == 0)
+ return String.Empty;
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ int size = xTags.Count;
+ for (int i = 0; i < size; i++) {
+
+ XTag xtagObj = (XTag)xTags[i];
+
+ Property xtag = xtagObj.Tag;
+ string value = xtag.Value;
+
+ properties.Clear();
+ properties.Add(xtag);
+
+ output.Append(ComposevCardComponent(xtag.Value, properties, xtagObj.TagValue));
+ }
+
+ return output.ToString();
+ }
+
+ private string ComposeFieldNote(ArrayList notes) {
+ if (notes == null || notes.Count == 0)
+ return "";
+
+ StringBuilder output = new StringBuilder();
+ ArrayList properties = new ArrayList();
+
+ int size = notes.Count;
+ for (int i = 0; i < size; i++) {
+
+ Note note = (Note)notes[i];
+ properties.Insert(0, note);
+
+ output.Append(ComposevCardComponent(note.Value, properties, "NOTE"));
+ }
+
+ return output.ToString();
+ }
+
+ private string composeFieldUid(String uid) {
+ if (uid == null)
+ return String.Empty;
+
+ return "UID:" + uid + "\r\n";
+ }
+
+ private string ComposeFieldTimezone(string tz) {
+ if (tz == null)
+ return String.Empty;
+
+ return "TZ:" + tz + "\r\n";
+ }
+
+ private String ComposeFieldRevision(String revision) {
+ if (revision == null)
+ return String.Empty;
+
+ return "REV:" + revision + "\r\n";
+ }
+ #endregion
+
+ #region Public Methods
+ public override string Convert(object obj) {
+ Contact contact = (Contact)obj;
+ StringBuilder output = new StringBuilder(INITIAL_CAPACITY);
+ output.Append("BEGIN:VCARD\r\nVERSION:2.1\r\n");
+
+ if (contact.Name != null) {
+ output.Append(ComposeFieldName(contact.Name));
+ output.Append(ComposeFieldFormalName(contact.Name.DisplayName));
+ output.Append(ComposeFieldNickname(contact.Name.Nickname));
+ }
+ if (contact.PersonalDetail != null) {
+ output.Append(ComposeFieldAddress(contact.PersonalDetail.Address, "HOME"));
+ output.Append(ComposeFieldAddress(contact.PersonalDetail.OtherAddress, "OTHER"));
+ output.Append(ComposeFieldBirthday(contact.PersonalDetail.Birthday));
+ output.Append(ComposeFieldPersonalLabel(contact.PersonalDetail.Address.Label));
+ output.Append(ComposeFieldOtherLabel(contact.PersonalDetail.OtherAddress.Label));
+ if (contact.PersonalDetail != null) {
+ output.Append(ComposeFieldTelephone(contact.PersonalDetail.Phones));
+ output.Append(ComposeFieldEmail(contact.PersonalDetail.Emails));
+ output.Append(ComposeFieldWebPage(contact.PersonalDetail.WebPages));
+ }
+ }
+ if (contact.BusinessDetail != null) {
+ output.Append(ComposeFieldAddress(contact.BusinessDetail.Address, "WORK"));
+ output.Append(ComposeFieldRole(contact.BusinessDetail.Role));
+ output.Append(ComposeFieldTitle(contact.BusinessDetail.Titles));
+ output.Append(ComposeFieldOrg(contact.BusinessDetail.Company, contact.BusinessDetail.Department));
+ output.Append(ComposeFieldBusinessLabel(contact.BusinessDetail.Address.Label));
+ if (contact.BusinessDetail != null) {
+ output.Append(ComposeFieldTelephone(contact.BusinessDetail.Phones));
+ output.Append(ComposeFieldEmail(contact.BusinessDetail.Emails));
+ output.Append(ComposeFieldWebPage(contact.BusinessDetail.WebPages));
+ }
+ }
+ output.Append(ComposeFieldNote(contact.Notes));
+ output.Append(ComposeFieldXTag(contact.XTags));
+ output.Append(ComposeFieldRevision(contact.Revision));
+ output.Append(ComposeFieldCategories(contact.Categories));
+ output.Append(ComposeFieldPhoto(contact.PersonalDetail.Photo));
+ output.Append(composeFieldUid(contact.UID));
+
+
+ output.Append("END:VCARD\r\n");
+ return output.ToString();
+ }
+ #endregion
+ }
+}
63 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ContactDetail.cs
View
@@ -0,0 +1,63 @@
+//
+// ContactDetail.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+
+namespace Deveel.Pim {
+ public class ContactDetail {
+ #region .ctor
+ public ContactDetail() {
+ phones = new PropertyCollection();
+ emails = new PropertyCollection();
+ webPages = new PropertyCollection();
+ }
+ #endregion
+
+ #region Fields
+ private PropertyCollection phones;
+ private PropertyCollection emails;
+ private PropertyCollection webPages;
+ #endregion
+
+ #region Properties
+ public PropertyCollection Phones {
+ get { return phones; }
+ }
+
+ public PropertyCollection Emails {
+ get { return emails; }
+ }
+
+ public PropertyCollection WebPages {
+ get { return webPages; }
+ }
+ #endregion
+ }
+}
48 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/ConverterException.cs
View
@@ -0,0 +1,48 @@
+//
+// ConverterException.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+
+namespace Deveel.Pim {
+ public sealed class ConverterException : ApplicationException {
+ internal ConverterException(string message, Exception innerException)
+ : base(message, innerException) {
+ }
+
+ internal ConverterException(string message)
+ : base(message) {
+ }
+
+ internal ConverterException()
+ : base() {
+ }
+ }
+}
77 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Email.cs
View
@@ -0,0 +1,77 @@
+//
+// Email.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+
+namespace Deveel.Pim {
+ public class Email : Property {
+ #region .ctor
+ public Email()
+ : base() {
+ }
+
+ public Email(string value)
+ : base(value) {
+ }
+ #endregion
+
+ #region Fields
+ private string emailType;
+ #endregion
+
+ #region Properties
+ public string EmailType {
+ get { return emailType; }
+ set { emailType = value; }
+ }
+ #endregion
+
+ #region Public Methods
+ public override bool Equals(object o) {
+ Email email = o as Email;
+ if (email == null)
+ return false;
+
+ if (emailType == null && email.emailType == null)
+ return true;
+
+ return String.Compare(emailType, email.EmailType, true) == 0;
+ }
+
+ public override int GetHashCode() {
+ if (emailType == null) {
+ return base.GetHashCode();
+ }
+ return emailType.GetHashCode();
+ }
+ #endregion
+ }
+}
359 acceptance-tests-ifolder/Deveel.Pim/Deveel.Pim/Event.cs
View
@@ -0,0 +1,359 @@
+//
+// Event.cs:
+//
+// Author:
+// Antonello Provenzano (antonello@deveel.com)
+//
+// (C) 2006, Deveel srl, (http://deveel.com)
+//
+
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+
+namespace Deveel.Pim {
+ public class Event {
+ #region .ctor
+ public Event() {
+ categories = new Property();
+ classEvent = new Property();
+ description = new Property();
+ latitude = new Property();
+ longitude = new Property();
+ location = new Property();
+ lastModified = new Property();
+ priority = new Property();
+ dtStamp = new Property();
+ sequence = new Property();
+ status = new Property();
+ summary = new Property();
+ uid = new Property();
+ url = new Property();
+ dtEnd = new Property();
+ dtStart = new Property();
+ replyTime = new Property();
+ duration = new Property();
+ transp = new Property();
+ organizer = new Property();
+ rrule = new Property();
+ contact = new Property();
+ created = new Property();
+ dalarm = new Property();
+ palarm = new Property();
+
+ xTags = new XTagCollection();
+
+ recurrence = null;
+ reminder = null;
+ }
+ #endregion
+
+ #region Fields
+ private Property dalarm;
+ private Property palarm;
+ private Property categories;
+ private Property classEvent;
+ private Property description;
+ private Property latitude;
+ private Property longitude;
+ private Property location;
+ private Property priority;
+ private Property status;
+ private Property summary;
+ private Property dtEnd;
+ private Property dtStart;
+ private Property replyTime;
+ private Property duration;
+ private Property transp;
+ private Property organizer;
+ private Property url;
+ private Property uid;
+ private Property rrule;
+ private Property contact;
+ private Property created;
+ private Property dtStamp;
+ private Property lastModified;
+ private Property sequence;
+ private XTagCollection xTags;
+
+ // Because these properties are not part of the iCal specifications,
+ // we do not need to use the Property object