ldif.h

Go to the documentation of this file.
00001 ///
00002 /// \file       ldif.h
00003 ///             Routines for reading and writing LDAP LDIF data.
00004 ///
00005 
00006 /*
00007     Copyright (C) 2005-2012, Net Direct Inc. (http://www.netdirect.ca/)
00008 
00009     This program is free software; you can redistribute it and/or modify
00010     it under the terms of the GNU General Public License as published by
00011     the Free Software Foundation; either version 2 of the License, or
00012     (at your option) any later version.
00013 
00014     This program is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00017 
00018     See the GNU General Public License in the COPYING file at the
00019     root directory of this project for more details.
00020 */
00021 
00022 #ifndef __BARRY_LDIF_H__
00023 #define __BARRY_LDIF_H__
00024 
00025 #include "dll.h"
00026 #include <string>
00027 #include <map>
00028 
00029 // forward declarations
00030 namespace Barry {
00031         class Contact;
00032 }
00033 
00034 namespace Barry {
00035 
00036 //
00037 // ContactLdif
00038 //
00039 /// Class for generating LDIF output based on a Barry::Contact record object.
00040 /// This class supports LDIF attribute mapping, and a heuristics mechanism
00041 /// for parsing LDIF fields that may not have consistent data.
00042 ///
00043 /// To use this class, create an instance of it, then call DumpLdif(), passing
00044 /// the Contact record object to base the work on.  Output will be written
00045 /// to the stream you provide.  ReadLdif() goes in the other direction.
00046 ///
00047 /// To override LDIF attribute mapping, call Map() or Unmap() as appropriate.
00048 ///
00049 /// To get a list of supported Barry::Contact field names, call GetFieldNames().
00050 /// This function returns a pointer to an array of ContactLdif::NameToFunc
00051 /// structures, ending with NameToFunc::name as null.  You can cycle through the
00052 /// array with code like this:
00053 ///
00054 /// <pre>
00055 ///     for( ContactLdif::NameToFunc *n = o.GetFieldNames(); n->name; n++ ) {
00056 ///             ...
00057 ///     }
00058 /// </pre>
00059 ///
00060 /// Note that all Get/Set functions used in attribute mapping are virtual,
00061 /// and can be overridden by a derived class.  This includes the heuristics
00062 /// functions, which are called by DumpLdif().
00063 ///
00064 class BXEXPORT ContactLdif
00065 {
00066 public:
00067         typedef std::string (ContactLdif::*GetFunctionType)(const Barry::Contact&) const;
00068         typedef void (ContactLdif::*SetFunctionType)(Barry::Contact&, const std::string &) const;
00069 
00070         /// Used to create a List of supported Barry field names, including
00071         /// calculated names, such as full postal address.
00072         struct NameToFunc
00073         {
00074                 const char *name;
00075                 const char *description;
00076                 GetFunctionType read;
00077                 SetFunctionType write;
00078         };
00079 
00080         struct LdifAttribute
00081         {
00082                 std::string name;
00083                 std::string objectClass;
00084                 int order;
00085 
00086                 LdifAttribute() : order(0) {}
00087                 LdifAttribute(const char *name, const std::string &oc = "")
00088                         : name(name), objectClass(oc), order(0)
00089                         {}
00090                 LdifAttribute(const std::string &name, const std::string &oc = "")
00091                         : name(name), objectClass(oc), order(0)
00092                         {}
00093 
00094                 bool operator<(const LdifAttribute &other) const;
00095                 bool operator==(const LdifAttribute &other) const;
00096         };
00097 
00098         struct AccessPair
00099         {
00100                 GetFunctionType read;
00101                 SetFunctionType write;
00102 
00103                 AccessPair() : read(0), write(0) {}
00104                 AccessPair(GetFunctionType r, SetFunctionType w)
00105                         : read(r), write(w)
00106                         {}
00107         };
00108 
00109         typedef std::map<LdifAttribute, AccessPair>   AccessMapType;
00110         typedef std::map<std::string, std::string*>   HookMapType;
00111 
00112 protected:
00113         static const NameToFunc FieldMap[];
00114         AccessMapType m_map;
00115         std::string m_baseDN;
00116         HookMapType m_hookMap;
00117         LdifAttribute m_dnAttr;
00118 
00119         void DoWrite(Barry::Contact &con, const std::string &attr,
00120                 const std::string &data);
00121 
00122         // Array getter state
00123         mutable unsigned int m_emailIndex;
00124 
00125         // name heuristics
00126         std::string m_cn, m_displayName, m_sn, m_givenName;
00127 
00128         // heuristics hooking - saves each found value in the variable
00129         // pointed at by var
00130         void Hook(const std::string &ldifname, std::string *var);
00131 
00132 public:
00133         explicit ContactLdif(const std::string &baseDN);
00134         virtual ~ContactLdif();
00135 
00136         const NameToFunc* GetFieldNames() const { return FieldMap; }
00137         const NameToFunc* GetField(const std::string &fieldname) const;
00138         std::string GetFieldReadName(GetFunctionType read) const;
00139         std::string GetFieldWriteName(SetFunctionType write) const;
00140 
00141         bool Map(const LdifAttribute &ldifname, const std::string &readField,
00142                 const std::string &writeField);
00143         void Map(const LdifAttribute &ldifname, GetFunctionType read,
00144                 SetFunctionType write);
00145         void Unmap(const LdifAttribute &ldifname);
00146 
00147         void SetBaseDN(const std::string &baseDN) { m_baseDN = baseDN; }
00148         bool SetDNAttr(const LdifAttribute &name);
00149         bool SetObjectClass(const LdifAttribute &name, const std::string &objectClass);
00150         bool SetObjectOrder(const LdifAttribute &name, int order);
00151 
00152         //
00153         // Access functions
00154         //
00155 
00156         virtual std::string Email(const Barry::Contact &con) const;
00157         virtual std::string Phone(const Barry::Contact &con) const;
00158         virtual std::string Fax(const Barry::Contact &con) const;
00159         virtual std::string WorkPhone(const Barry::Contact &con) const;
00160         virtual std::string HomePhone(const Barry::Contact &con) const;
00161         virtual std::string MobilePhone(const Barry::Contact &con) const;
00162         virtual std::string Pager(const Barry::Contact &con) const;
00163         virtual std::string PIN(const Barry::Contact &con) const;
00164         virtual std::string FirstName(const Barry::Contact &con) const;
00165         virtual std::string LastName(const Barry::Contact &con) const;
00166         virtual std::string Company(const Barry::Contact &con) const;
00167         virtual std::string DefaultCommunicationsMethod(const Barry::Contact &con) const;
00168         virtual std::string WorkAddress1(const Barry::Contact &con) const;
00169         virtual std::string WorkAddress2(const Barry::Contact &con) const;
00170         virtual std::string WorkAddress3(const Barry::Contact &con) const;
00171         virtual std::string WorkCity(const Barry::Contact &con) const;
00172         virtual std::string WorkProvince(const Barry::Contact &con) const;
00173         virtual std::string WorkPostalCode(const Barry::Contact &con) const;
00174         virtual std::string WorkCountry(const Barry::Contact &con) const;
00175         virtual std::string JobTitle(const Barry::Contact &con) const;
00176         virtual std::string PublicKey(const Barry::Contact &con) const;
00177         virtual std::string Notes(const Barry::Contact &con) const;
00178         virtual std::string Image(const Barry::Contact &con) const;
00179         // calculated values...
00180         virtual std::string WorkPostalAddress(const Barry::Contact &con) const;
00181         virtual std::string HomePostalAddress(const Barry::Contact &con) const;
00182         virtual std::string FullName(const Barry::Contact &con) const;
00183         virtual std::string FQDN(const Barry::Contact &con) const;
00184 
00185         //
00186         // Array modifier functions for above Access functions
00187         //
00188 
00189         virtual bool IsArrayFunc(GetFunctionType getf) const;
00190         void ClearArrayState() const;
00191 
00192         //
00193         // Write functions
00194         //
00195 
00196         virtual void SetEmail(Barry::Contact &con, const std::string &val) const;
00197         virtual void SetPhone(Barry::Contact &con, const std::string &val) const;
00198         virtual void SetFax(Barry::Contact &con, const std::string &val) const;
00199         virtual void SetWorkPhone(Barry::Contact &con, const std::string &val) const;
00200         virtual void SetHomePhone(Barry::Contact &con, const std::string &val) const;
00201         virtual void SetMobilePhone(Barry::Contact &con, const std::string &val) const;
00202         virtual void SetPager(Barry::Contact &con, const std::string &val) const;
00203         virtual void SetPIN(Barry::Contact &con, const std::string &val) const;
00204         virtual void SetFirstName(Barry::Contact &con, const std::string &val) const;
00205         virtual void SetLastName(Barry::Contact &con, const std::string &val) const;
00206         virtual void SetCompany(Barry::Contact &con, const std::string &val) const;
00207         virtual void SetDefaultCommunicationsMethod(Barry::Contact &con, const std::string &val) const;
00208         virtual void SetWorkAddress1(Barry::Contact &con, const std::string &val) const;
00209         virtual void SetWorkAddress2(Barry::Contact &con, const std::string &val) const;
00210         virtual void SetWorkAddress3(Barry::Contact &con, const std::string &val) const;
00211         virtual void SetWorkCity(Barry::Contact &con, const std::string &val) const;
00212         virtual void SetWorkProvince(Barry::Contact &con, const std::string &val) const;
00213         virtual void SetWorkPostalCode(Barry::Contact &con, const std::string &val) const;
00214         virtual void SetWorkCountry(Barry::Contact &con, const std::string &val) const;
00215         virtual void SetJobTitle(Barry::Contact &con, const std::string &val) const;
00216         virtual void SetPublicKey(Barry::Contact &con, const std::string &val) const;
00217         virtual void SetNotes(Barry::Contact &con, const std::string &val) const;
00218         virtual void SetImage(Barry::Contact &con, const std::string &val) const;
00219         virtual void SetWorkPostalAddress(Barry::Contact &con, const std::string &val) const;
00220         virtual void SetHomePostalAddress(Barry::Contact &con, const std::string &val) const;
00221         virtual void SetFullName(Barry::Contact &con, const std::string &val) const;
00222         virtual void SetFQDN(Barry::Contact &con, const std::string &val) const;
00223 
00224 
00225         //
00226         // Name heuristics
00227         //
00228 
00229         virtual void ClearHeuristics();
00230         virtual bool RunHeuristics(Barry::Contact &con);
00231 
00232         //
00233         // Operations
00234         //
00235 
00236         void DumpLdif(std::ostream &os, const Barry::Contact &contact) const;
00237         bool ReadLdif(std::istream &is, Barry::Contact &contact);
00238                                                         // returns true on success
00239         void DumpMap(std::ostream &os) const;
00240 
00241 
00242         static std::string MakeLdifData(const std::string &str);
00243         static bool NeedsEncoding(const std::string &str);
00244 };
00245 
00246 BXEXPORT inline std::ostream& operator<< (std::ostream &os, const ContactLdif &ldif) {
00247         ldif.DumpMap(os);
00248         return os;
00249 }
00250 
00251 } // namespace Barry
00252 
00253 #endif
00254