pax_global_header00006660000000000000000000000064126253165140014517gustar00rootroot0000000000000052 comment=5181f6fd0b8cafc6e33dfc18381b7b6582c2dd31 libkolabxml-1.1.2/000077500000000000000000000000001262531651400140205ustar00rootroot00000000000000libkolabxml-1.1.2/.gitignore000066400000000000000000000003431262531651400160100ustar00rootroot00000000000000*~ CMakeFiles CMakeCache.txt moc_* *.moc *.pyc .*.swp .*.kate-swp configure config.status config.log Makefile Makefile.in ChangeLog autom4te.cache aclocal.m4 libkolabxml-*.tar.gz libkolabxml-*.*/ libkolabxml.spec build *kdev4* libkolabxml-1.1.2/AUTHORS000066400000000000000000000002271262531651400150710ustar00rootroot00000000000000Authors of libkolabxml: - Christian Mollekopf (Kolab Systems) - Jeroen van Meeuwen (Kolab Systems) libkolabxml-1.1.2/CMakeLists.txt000066400000000000000000000204531262531651400165640ustar00rootroot00000000000000# The special language NONE is not available in cmake 2.6 if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 6) project(Libkolabxml NONE) else() project(Libkolabxml C) endif() cmake_minimum_required(VERSION 2.6) option( BUILD_TESTS "Build the tests" TRUE ) option( BUILD_UTILS "Build optional utils" FALSE ) option( DIST_ONLY "Build dist targets only (does not require a compiler)" FALSE ) option( PYTHON_BINDINGS "Build bindings for python" FALSE ) option( PHP_BINDINGS "Build bindings for php" FALSE ) option( CSHARP_BINDINGS "Build bindings for csharp" FALSE ) option( JAVA_BINDINGS "Build bindings for java" FALSE ) option( QT5_BUILD "Build libkolabxml using the Qt5 framework" FALSE) set(Libkolabxml_MODULE_DIR ${Libkolabxml_SOURCE_DIR}/cmake/modules) set(CMAKE_MODULE_PATH ${Libkolabxml_MODULE_DIR}) # only available from cmake-2.8.0 if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7) cmake_policy(SET CMP0012 NEW) endif() # only available from cmake-2.8.4 if(${CMAKE_MAJOR_VERSION} EQUAL 2 AND ${CMAKE_MINOR_VERSION} GREATER 7 AND ${CMAKE_PATCH_VERSION} GREATER 3) cmake_policy(SET CMP0017 NEW) endif() # Versioning # x.y.z scheme # Development versions are only x.y # # i.e. # 0.1 (0.1 development version) # 0.1.0 (first release) # 0.1.1 (patch release for 0.1.0) # 0.2 (0.2 development version) set (Libkolabxml_VERSION_MAJOR 1) set (Libkolabxml_VERSION_MINOR 1) # Enable the full x.y.z version only for release versions set (Libkolabxml_VERSION_PATCH 2) set (Libkolabxml_VERSION "${Libkolabxml_VERSION_MAJOR}.${Libkolabxml_VERSION_MINOR}.${Libkolabxml_VERSION_PATCH}" ) #set (Libkolabxml_VERSION "${Libkolabxml_VERSION_MAJOR}.${Libkolabxml_VERSION_MINOR}" ) set (Libkolabxml_VERSION_STRING ${CMAKE_PROJECT_NAME}-${Libkolabxml_VERSION}) set (KOLAB_FORMAT_VERSION "3.1.0") message("Building DIST targets (make dist, make snapshot)") #make dist requires a tag with ${ARCHIVE_NAME} (e.g. libkolabxml-0.2.0) set(ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${Libkolabxml_VERSION}) add_custom_target(dist COMMAND git archive --prefix=${ARCHIVE_NAME}/ ${ARCHIVE_NAME} | bzip2 > ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.bz2 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) #snapshot of current development version set(SNAPSHOTARCHIVE_NAME "${CMAKE_PROJECT_NAME}-${Libkolabxml_VERSION}-HEAD") add_custom_target(snapshot COMMAND git archive --prefix=${SNAPSHOTARCHIVE_NAME}/ HEAD | bzip2 > ${CMAKE_BINARY_DIR}/${SNAPSHOTARCHIVE_NAME}.tar.bz2 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) #It's possible to make dist targets only using: #cmake -DDIST_ONLY=TRUE .. if (DIST_ONLY) message("Building DIST targets ONLY (cmake -DDIST_ONLY=FALSE .. for full build)") return() endif() #C++ is required from here on enable_language(CXX) set(LIB_INSTALL_DIR lib${LIB_SUFFIX} CACHE STRING "The directories where to install libraries to") set(INCLUDE_INSTALL_DIR include CACHE STRING "The directory where to install headers to") set(INCLUDE_INSTALL_DIR ${INCLUDE_INSTALL_DIR}/kolabxml) set(CMAKECONFIG_INSTALL_DIR ${LIB_INSTALL_DIR}/cmake/Libkolabxml ) # Make relative paths absolute (needed later on) foreach(p LIB INCLUDE CMAKECONFIG) set(var ${p}_INSTALL_DIR) if(NOT IS_ABSOLUTE "${${var}}") set(${var} "${CMAKE_INSTALL_PREFIX}/${${var}}") endif() endforeach() configure_file(libkolabxml-version.h.cmake "${CMAKE_BINARY_DIR}/libkolabxml-version.h" @ONLY) set(Boost_USE_MULTITHREADED ON) find_package(Boost REQUIRED COMPONENTS thread system) if (Boost_FOUND) message("Found boost in ${Boost_INCLUDE_DIRS}") endif (Boost_FOUND) find_package(LibkolabxmlDependencies REQUIRED) # Must be after findboost set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION) if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7) message(STATUS "GCC Version >= 4.7, applying unqualified lookup workaround") # gcc 4.7 no longer performs unqualified lookups by default, see: http://gcc.gnu.org/gcc-4.7/porting_to.html. # This workaround is added for xsd code, which fails otherwise to compile. -fpermissive turns the errors into warnings. # It's only temporary, and should be removed once xsd is fixed. set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive" ) endif() file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bindings) set( SCHEMA_DIR ${CMAKE_SOURCE_DIR}/schemas ) # Generate bindings # WARNING: The inclusion order in SCHEMAS matters with xerces < 3.1.0. It seems without XMLUni::fgXercesHandleMultipleImports at least kolabformat-xcard.xsd MUST be before xCard.xsd, # otherwise the compiled schema will simply lack the definitions of kolabformat-xcard.xsd (this affects xsdbin only). set( SCHEMAS ${SCHEMA_DIR}/ical/kolabformat-xcal.xsd ${SCHEMA_DIR}/ical/iCalendar-params.xsd ${SCHEMA_DIR}/ical/iCalendar-props.xsd ${SCHEMA_DIR}/ical/iCalendar-valtypes.xsd ${SCHEMA_DIR}/kolabformat-xcard.xsd ${SCHEMA_DIR}/xCard.xsd ${SCHEMA_DIR}/kolabformat.xsd ) set( SCHEMA_SOURCEFILES ${CMAKE_BINARY_DIR}/bindings/kolabformat.cxx ${CMAKE_BINARY_DIR}/bindings/xCard.cxx ${CMAKE_BINARY_DIR}/bindings/kolabformat-xcal.cxx ${CMAKE_BINARY_DIR}/bindings/kolabformat-xcard.cxx ${CMAKE_BINARY_DIR}/bindings/iCalendar-params.cxx ${CMAKE_BINARY_DIR}/bindings/iCalendar-props.cxx ${CMAKE_BINARY_DIR}/bindings/iCalendar-valtypes.cxx # bindings/iCalendar-link-extension.cxx # bindings/iCalendar-bw-extensions.cxx # bindings/iCalendar-ms-extensions.cxx ) #xsdcxx cxx-tree --generate-xml-schema --generate-serialization --custom-type date_time --hxx-epilogue '#include "bindings/customtypes/xml-schema-custom.hxx"' xml-schema.xsd # --generate-inline --extern-xml-schema xml-schema.xsd # --cxx-suffix .cpp --hxx-suffix .h add_custom_command(OUTPUT ${SCHEMA_SOURCEFILES} COMMAND ${XSDCXX} cxx-tree --generate-polymorphic --generate-serialization --namespace-map http://kolab.org=KolabXSD --root-element icalendar --root-element vcards --root-element note --root-element configuration --root-element file --output-dir ${CMAKE_BINARY_DIR}/bindings ${SCHEMAS} COMMENT "Generating XSD bindings" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} DEPENDS ${SCHEMAS} VERBATIM ) # Compile xsdbin if not found if (NOT XSDBIN_FOUND) add_executable(xsdbin compiled/xsdbin.cxx) target_link_libraries(xsdbin ${XERCES_C}) set(XSDBIN ${CMAKE_BINARY_DIR}/xsdbin) endif () # Compile Schemas add_custom_command(OUTPUT kolabformat-xcal-schema.cxx COMMAND ${XSDBIN} --verbose --array-name iCalendar_schema --output-dir ${CMAKE_BINARY_DIR} ${SCHEMAS} COMMENT "Compiling Kolab XSD schema" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} DEPENDS ${SCHEMAS} ${XSDBIN} VERBATIM ) set( SCHEMA_SOURCEFILES ${SCHEMA_SOURCEFILES} ${CMAKE_BINARY_DIR}/kolabformat-xcal-schema.cxx) # --------- SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1) ADD_CUSTOM_TARGET(generate_bindings ALL DEPENDS ${SCHEMA_SOURCEFILES}) include_directories( ./ compiled src/containers ${CMAKE_CURRENT_BINARY_DIR} ${Boost_INCLUDE_DIRS} ${XSDCXX_INCLUDE_DIRS} ${XERCES_C_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ) add_subdirectory(src) if (BUILD_UTILS) add_subdirectory(utils) endif() if (BUILD_TESTS) enable_testing() add_subdirectory(tests) endif() #Get the include directory relative to CMAKECONFIG_INSTALL_DIR file(RELATIVE_PATH REL_INCLUDE_DIR "${CMAKECONFIG_INSTALL_DIR}" "${INCLUDE_INSTALL_DIR}") #Assemble the full relative path. This will be used in the LibkolabxmlConfig.cmake, which will be installed in CMAKECONFIG_INSTALL_DIR set(CONF_INCLUDE_DIRS "\${Libkolabxml_CMAKE_DIR}/${REL_INCLUDE_DIR}") install(EXPORT LibkolabxmlExport DESTINATION ${CMAKECONFIG_INSTALL_DIR} FILE LibkolabxmlTargets.cmake ) configure_file(${Libkolabxml_MODULE_DIR}/LibkolabxmlConfig.cmake.in ${Libkolabxml_BINARY_DIR}/LibkolabxmlConfig.cmake @ONLY ) configure_file(${Libkolabxml_MODULE_DIR}/LibkolabxmlConfigVersion.cmake.in ${Libkolabxml_BINARY_DIR}/LibkolabxmlConfigVersion.cmake @ONLY ) # Install these two files into the same directory as the generated exports-file. install(FILES ${Libkolabxml_BINARY_DIR}/LibkolabxmlConfig.cmake ${Libkolabxml_BINARY_DIR}/LibkolabxmlConfigVersion.cmake DESTINATION ${CMAKECONFIG_INSTALL_DIR} ) libkolabxml-1.1.2/COPYING000066400000000000000000000004341262531651400150540ustar00rootroot00000000000000schemas/*: Apache v2 (see http://www.calconnect.org/artifacts/ical-art.shtml) compiled/xsdbin.cxx: not copyrighted - public domain compiled/grammar-input-stream.*: not copyrighted - public domain src/base64.*: Copyright (C) 2004-2008 René Nyffenegger everything else: LGPLv3 or laterlibkolabxml-1.1.2/COPYING.apachev2000066400000000000000000000261351262531651400165520ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. libkolabxml-1.1.2/COPYING.lgplv3000066400000000000000000001045221262531651400162650ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . libkolabxml-1.1.2/DEVELOPMENT000066400000000000000000000006041262531651400155250ustar00rootroot00000000000000Branch layout: master The latest and greatest. libkolabxml. Version branch for the . product series. dev/* Temporary development branches. Versioning: According to http://wiki.kolab.org/KEP:5 .. Where major stands for the major format version, minor for larger releases and teeny for bugfix releases. libkolabxml-1.1.2/NEWS000066400000000000000000000000001262531651400145050ustar00rootroot00000000000000libkolabxml-1.1.2/README000066400000000000000000000033411262531651400147010ustar00rootroot00000000000000= About = Libkolabxml is the reference implementation of the Kolab XML Format as defined in http://wiki.kolab.org/User:Mollekopf/Drafts/KEP:17. It provides serialization/deserialization from/to in-memory representations for all Kolab Objects, including input validation. = Bindings = Based on SWIG (www.swig.org) various language-bindings are provided. = Usage = For more information about the usage please see src/kolabformat.h = Building = Build with: $ mkdir build $ cd build $ cmake .. $ make == CMake options == Options can either be supplied on the commandline or edited in the cmake cache. Library installation path: LIB_INSTALL_DIR=/usr/lib Note that LIB_SUFFIX is honored since version 1.0.2 Set the installation prefix: CMAKE_INSTALL_PREFIX=/usr Installation location for header files: INCLUDE_INSTALL_DIR=/usr/include Building of bindings can be controlled using cmake configuration options: PYTHON_BINDINGS PHP_BINDINGS JAVA_BINDINGS CSHARP_BINDINGS The path to install the bindings: PYTHON_INSTALL_DIR PHP_INSTALL_DIR JAVA_INSTALL_DIR CSHARP_INSTALL_DIR === Example === Find libraries in lib64, install to /usr/lib64, build python and phpbindings: $ cmake -DCMAKE_INSTALL_PREFIX=/usr -DLIB_INSTALL_DIR=/usr/lib64 \ -DPYTHON_BINDINGS=TRUE \ -DPYTHON_INSTALL_DIR=/usr/lib64/python$x.$y/site-packages/ \ -DPHP_BINDINGS=TRUE .. == Requirements == Minimum requirements are: - cmake 2.6 - boost >= 1.41 - xerces-c >= 3.0 - cxx >= 3.0 (http://www.codesynthesis.com/products/xsd/) - libcurl For further features: - SWIG >= 2.0 For building test (controlled by -DBUILD_TESTS=TRUE): - Qt >= 4.7 For further information see src/DEVELOPMENT. libkolabxml-1.1.2/README-Mac.txt000066400000000000000000000015161262531651400162170ustar00rootroot00000000000000# The following commands are used to bild libkolabxml on Mac OS X (Lion) # with most of the required libraries installed via macports: # > sudo port install cmake boost xercesc3 swig swig-php # # The cxx/xsd library has to be downlaoded from http://www.codesynthesis.com/products/xsd/download.xhtml # and manually copied into /usr/bin and /usr/include/xsd/ rm -rf build/ mkdir -p build cd build cmake -DPHP_BINDINGS=TRUE -DPHP_INSTALL_DIR:PATH=/usr/lib/php/extensions/no-debug-non-zts-20090626 -DCMAKE_INCLUDE_PATH:PATH=/opt/local/include -DCMAKE_INSTALL_PREFIX:PATH=/usr .. make sudo make install # This will install kolabformat.dylib and kolabform.php to the KOLAB_PHP_INSTALL_DIR # You probably have to symlink kolabformat.dylib to kolabformat.so and move # kolabform.php to a location which is in the include_path of your PHP installation. libkolabxml-1.1.2/RELEASE-NOTES000066400000000000000000000004051262531651400157100ustar00rootroot00000000000000 == Attention to Distributors == * 0.7: Headers are now installed into $INCLUDE_INSTALL_DIR/kolabxml * 0.7: libkolabxml now depends on libcurl == 0.7.0 == * The Licence situation has been clarified, see COPYING for further information * Added F/B Container libkolabxml-1.1.2/autogen-mingw32.sh000077500000000000000000000002031262531651400173000ustar00rootroot00000000000000#!/bin/bash # Rebuilds the entire foo in one go. One shot, one kill. rm -rf build/ mkdir -p build cd build mingw32-cmake .. make libkolabxml-1.1.2/autogen.sh000077500000000000000000000057041262531651400160270ustar00rootroot00000000000000#!/bin/bash dobuild=0 doprep=0 dotest=0 doinstall=0 srcdir=$(pwd) while [ $# -gt 0 ]; do case "$1" in --build|-b) dobuild=1 shift ;; --prep|-p) doprep=1 shift ;; --test|-t) dotest=1 shift ;; --install|-i) doinstall=1 shift ;; esac done if [ ${dobuild} -eq 0 -a ${doprep} -eq 0 -a ${dotest} -eq 0 -a ${doinstall} -eq 0 ]; then dobuild=1 doprep=1 dotest=1 doinstall=1 fi version_major=`grep -E "^set \(Libkolabxml_VERSION_MAJOR [0-9]+\)" CMakeLists.txt | sed -r -e 's/^set \(Libkolabxml_VERSION_MAJOR ([0-9]+)\)/\1/g'` version_minor=`grep -E "^set \(Libkolabxml_VERSION_MINOR [0-9]+\)" CMakeLists.txt | sed -r -e 's/^set \(Libkolabxml_VERSION_MINOR ([0-9]+)\)/\1/g'` version_patch=`grep -E "^set \(Libkolabxml_VERSION_PATCH [0-9]+\)" CMakeLists.txt | sed -r -e 's/^set \(Libkolabxml_VERSION_PATCH ([0-9]+)\)/\1/g'` if [ -z "${version_patch}" ]; then version="${version_major}.${version_minor}" else version="${version_major}.${version_minor}.${version_patch}" fi # Rebuilds the entire foo in one go. One shot, one kill. if [ ${doprep} -eq 1 ]; then rm -rf build/ mkdir -p build fi cd build if [ ${doprep} -eq 1 ]; then cmake \ -DCMAKE_COLOR_MAKEFILE=OFF \ -DCMAKE_VERBOSE_MAKEFILE=ON \ -DCMAKE_INSTALL_PREFIX=/usr \ -DINCLUDE_INSTALL_DIR=/usr/include \ -DLIB_INSTALL_DIR=/usr/lib64 \ -DCSHARP_BINDINGS=ON \ -DJAVA_BINDINGS=ON \ -DPHP_BINDINGS=ON \ -DPYTHON_BINDINGS=ON \ .. || exit 1 fi if [ ${dobuild} -eq 1 ]; then make || exit 1 fi if [ ${dotest} -eq 1 ]; then # Execute some tests? retval=0 pushd tests ./bindingstest ; retval=$(( ${retval} + $? )) ./conversiontest ; retval=$(( ${retval} + $? )) ./parsingtest ; retval=$(( ${retval} + $? )) popd if [ -f "${srcdir}/build/src/csharp/test.exe" ]; then LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$(pwd)/build/src/csharp/ MONO_LOG_LEVEL=debug mono ${srcdir}/build/src/csharp/test.exe ; retval=$(( ${retval} + $? )) fi if [ -f "${srcdir}/build/src/php/test.php" ]; then php -d enable_dl=On -dextension=${srcdir}/build/src/php/kolabformat.so ${srcdir}/build/src/php/test.php ; retval=$(( ${retval} + $? )) fi if [ -f "${srcdir}/build/src/python/test.py" ]; then python ${srcdir}/build/src/python/test.py ; retval=$(( ${retval} + $? )) fi if [ ${retval} -ne 0 ]; then echo "FAILED: Accumulated errors." exit ${retval} fi fi if [ ${doinstall} -eq 1 ]; then make install DESTDIR=${TMPDIR:-/tmp} fi cd .. rm -rf libkolabxml-${version}.tar.gz git archive --prefix=libkolabxml-${version}/ HEAD | gzip -c > libkolabxml-${version}.tar.gz rm -rf `rpm --eval='%{_sourcedir}'`/libkolabxml-${version}.tar.gz cp libkolabxml-${version}.tar.gz `rpm --eval='%{_sourcedir}'` libkolabxml-1.1.2/cmake/000077500000000000000000000000001262531651400151005ustar00rootroot00000000000000libkolabxml-1.1.2/cmake/modules/000077500000000000000000000000001262531651400165505ustar00rootroot00000000000000libkolabxml-1.1.2/cmake/modules/FindLibkolabxmlDependencies.cmake000066400000000000000000000032101262531651400251160ustar00rootroot00000000000000# Find some dependencies # Instead of having multiple findscripts, we use a single to find everything we need # find_package(PkgConfig) include(FindPackageHandleStandardArgs) if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.43) find_library(UUID NAMES ossp-uuid) find_package_handle_standard_args(UUID DEFAULT_MSG UUID) if (UUID) set(UUID_LIBRARY_FOUND TRUE) endif() else() #Make sure that we either have the boost or ossp uuid lib set(UUID_LIBRARY_FOUND TRUE) endif() find_program(XSDCXX NAMES xsdcxx xsd /usr/bin/) if (XSDCXX) find_path(XSDCXX_INCLUDE_DIRS NAMES xsd/cxx/version.hxx) endif() find_package_handle_standard_args(XSDCXX DEFAULT_MSG XSDCXX XSDCXX_INCLUDE_DIRS) find_library(XERCES_C NAMES xerces-c xerces-c_2) if (XERCES_C) find_path(XERCES_C_INCLUDE_DIRS NAMES xercesc/framework/XMLGrammarPool.hpp) endif() find_package_handle_standard_args(Xerces DEFAULT_MSG XERCES_C XERCES_C_INCLUDE_DIRS) find_library(CURL NAMES curl) if (CURL) find_path(CURL_INCLUDE_DIRS NAMES curl/curl.h) endif() find_package_handle_standard_args(Curl DEFAULT_MSG CURL CURL_INCLUDE_DIRS) find_program(SWIG swig /usr/bin/) if(SWIG) set(SWIG_FOUND ON) message("SWIG found") endif() find_program(XSDBIN xsdbin) if(XSDBIN) set(XSDBIN_FOUND ON) message("XSDBIN found") endif() #abort if any of the requireds are missing find_package_handle_standard_args(LibkolabxmlDependencies DEFAULT_MSG UUID_LIBRARY_FOUND XSDCXX XERCES_C CURL) libkolabxml-1.1.2/cmake/modules/LibkolabxmlConfig.cmake.in000066400000000000000000000012621262531651400235460ustar00rootroot00000000000000get_filename_component(Libkolabxml_CMAKE_DIR ${CMAKE_CURRENT_LIST_FILE} PATH) #get the directory where this *Config.cmake file is installed # set the version set(Libkolabxml_VERSION_MAJOR @Libkolabxml_VERSION_MAJOR@) set(Libkolabxml_VERSION_MINOR @Libkolabxml_VERSION_MINOR@) set(Libkolabxml_VERSION_PATCH @Libkolabxml_VERSION_PATCH@) set(Libkolabxml_VERSION ${Libkolabxml_VERSION_MAJOR}.${Libkolabxml_VERSION_MINOR}.${Libkolabxml_VERSION_PATCH}) # Set the include directory set(Libkolabxml_INCLUDES "@CONF_INCLUDE_DIRS@") # import the exported targets include(${Libkolabxml_CMAKE_DIR}/LibkolabxmlTargets.cmake) # set the expected library variable set(Libkolabxml_LIBRARIES kolabxml) libkolabxml-1.1.2/cmake/modules/LibkolabxmlConfigVersion.cmake.in000066400000000000000000000017621262531651400251210ustar00rootroot00000000000000# Sets PACKAGE_VERSION_EXACT if the current version string and the requested # version string are exactly the same and it sets PACKAGE_VERSION_COMPATIBLE # if the current version is >= requested version. set(PACKAGE_VERSION @Libkolabxml_VERSION_MAJOR@.@Libkolabxml_VERSION_MINOR@.@Libkolabxml_VERSION_PATCH@) set(PACKAGE_VERSION_MAJOR @Libkolabxml_VERSION_MAJOR@) if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) set(PACKAGE_VERSION_COMPATIBLE FALSE) elseif(NOT "${PACKAGE_FIND_VERSION_MAJOR}" VERSION_EQUAL "${PACKAGE_VERSION_MAJOR}" ) #Major versions are incompatible and require an explicit switch set(PACKAGE_VERSION_COMPATIBLE FALSE) else("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) set(PACKAGE_VERSION_COMPATIBLE TRUE) if( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") set(PACKAGE_VERSION_EXACT TRUE) endif( "${PACKAGE_FIND_VERSION}" STREQUAL "${PACKAGE_VERSION}") endif("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}" ) libkolabxml-1.1.2/compiled/000077500000000000000000000000001262531651400156145ustar00rootroot00000000000000libkolabxml-1.1.2/compiled/README000066400000000000000000000014041262531651400164730ustar00rootroot00000000000000Code needed to compile schemas so they can be embeeded into the binary. According to the xsd example in xsd/examples/cxx/tree/embedded/ xsdbin.cxx Tool for converting one or more XML Schema files to the compressed binary representation. The output is written as a pair of C++ source files containing the array with the binary data. Use the --help option to see the tool's usage information. library-schema.hxx library-schema.cxx Binary representation of the library.xsd schema. These files are generated by the xsdbin tool. grammar-input-stream.hxx grammar-input-stream.cxx Input stream implementation with the special-purpose schema grammar decompression algorithm. It is used to load the binary schema representation produced by the xsdbin tool. libkolabxml-1.1.2/compiled/XMLParserWrapper.cpp000066400000000000000000000216141262531651400215020ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "XMLParserWrapper.h" #include // std::auto_ptr #include #include #include #include // chLatin_* #include #include // xercesc::Grammar #include #if _XERCES_VERSION >= 30000 # include #else # include #endif #include #include #include #include #include #include #include "kolabformat-xcal-schema.hxx" #include "grammar-input-stream.hxx" XMLParserWrapper::XMLParserWrapper() : ehp(eh), parser(0), gp(0) { // We need to initialize the Xerces-C++ runtime because we // are doing the XML-to-DOM parsing ourselves. // xercesc::XMLPlatformUtils::Initialize (); init(); } XMLParserWrapper::~XMLParserWrapper() { delete parser; delete gp; xercesc::XMLPlatformUtils::Terminate (); } boost::thread_specific_ptr ptr; XMLParserWrapper& XMLParserWrapper::inst() { XMLParserWrapper *t = ptr.get(); if (!t) { t = new XMLParserWrapper(); ptr.reset(t); } return *t; } void XMLParserWrapper::init() { using namespace std; if (parser) { return; } try { using namespace xercesc; namespace xml = xsd::cxx::xml; namespace tree = xsd::cxx::tree; // Create and load the grammar pool. // MemoryManager* mm (XMLPlatformUtils::fgMemoryManager); gp = new XMLGrammarPoolImpl (mm); try { grammar_input_stream is (iCalendar_schema, sizeof (iCalendar_schema)); gp->deserializeGrammars(&is); } catch(const XSerializationException& e) { cerr << "unable to load schema: " << xml::transcode (e.getMessage ()) << endl; return; } // Lock the grammar pool. This is necessary if we plan to use the // same grammar pool in multiple threads (this way we can reuse the // same grammar in multiple parsers). Locking the pool disallows any // modifications to the pool, such as an attempt by one of the threads // to cache additional schemas. // gp->lockPool (); // Get an implementation of the Load-Store (LS) interface. // const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull}; DOMImplementation* impl ( DOMImplementationRegistry::getDOMImplementation (ls_id)); #if _XERCES_VERSION >= 30000 // Xerces-C++ 3.0.0 and later. // parser = impl->createLSParser ( DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp); DOMConfiguration* conf (parser->getDomConfig ()); // Discard comment nodes in the document. // conf->setParameter (XMLUni::fgDOMComments, false); // Enable datatype normalization. // conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true); // Do not create EntityReference nodes in the DOM tree. No // EntityReference nodes will be created, only the nodes // corresponding to their fully expanded substitution text // will be created. // conf->setParameter (XMLUni::fgDOMEntities, false); // Perform namespace processing. // conf->setParameter (XMLUni::fgDOMNamespaces, true); // Do not include ignorable whitespace in the DOM tree. // conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false); // Enable validation. // conf->setParameter (XMLUni::fgDOMValidate, true); conf->setParameter (XMLUni::fgXercesSchema, true); conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false); // Xerces-C++ 3.1.0 is the first version with working multi import // support. // #if _XERCES_VERSION >= 30100 conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true); #endif // Use the loaded grammar during parsing. // conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true); // Disable loading schemas via other means (e.g., schemaLocation). // conf->setParameter (XMLUni::fgXercesLoadSchema, false); // We will release the DOM document ourselves. // conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true); // Set error handler. // // tree::error_handler eh; // xml::dom::bits::error_handler_proxy ehp (eh); conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp); //TODO does conf take a copy or should the ehp object live on? #else // _XERCES_VERSION >= 30000 // Same as above but for Xerces-C++ 2 series. // parser = impl->createDOMBuilder( DOMImplementationLS::MODE_SYNCHRONOUS, 0, mm, gp); parser->setFeature (XMLUni::fgDOMComments, false); parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true); parser->setFeature (XMLUni::fgDOMEntities, false); parser->setFeature (XMLUni::fgDOMNamespaces, true); parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false); parser->setFeature (XMLUni::fgDOMValidation, true); parser->setFeature (XMLUni::fgXercesSchema, true); parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false); parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true); parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true); //tree::error_handler eh; // xml::dom::bits::error_handler_proxy ehp (eh); parser->setErrorHandler (&ehp); #endif // _XERCES_VERSION >= 30000 // Parse XML documents. // } catch (const xml_schema::exception& e) { cout << "schema exception" << endl; cerr << e << endl; } catch (const std::ios_base::failure&) { cerr << ": unable to open or read failure" << endl; } } xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseFile(const std::string& url) { try { std::ifstream ifs; ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit); //TODO handle exceptions ifs.open (url.c_str()); return parse(ifs, url); } catch (const std::ios_base::failure&) { std::cerr << ": unable to open or read failure" << std::endl; } return xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument >(); } xsd::cxx::xml::dom::auto_ptr< xercesc::DOMDocument > XMLParserWrapper::parseString(const std::string& s) { std::istringstream is(s); return parse(is, ""); //TODO set identifier? } xml_schema::dom::auto_ptr XMLParserWrapper::parse(std::istream &ifs, const std::string &name) { using namespace std; try { using namespace xercesc; namespace xml = xsd::cxx::xml; namespace tree = xsd::cxx::tree; // Parse XML documents. // { // Wrap the standard input stream. // xml::sax::std_input_source isrc (ifs, name); Wrapper4InputSource wrap (&isrc, false); // Parse XML to DOM. // #if _XERCES_VERSION >= 30000 xml_schema::dom::auto_ptr doc (parser->parse (&wrap)); #else xml_schema::dom::auto_ptr doc (parser->parse (wrap)); #endif eh.throw_if_failed (); return doc; } } catch (const xml_schema::exception& e) { cerr << "schema exception" << endl; cerr << e << endl; } catch (const std::ios_base::failure&) { cerr << ": unable to open or read failure" << endl; } catch (...) { cerr << ": unknown exception thrown" << endl; } eh.reset(); return xml_schema::dom::auto_ptr(); } libkolabxml-1.1.2/compiled/XMLParserWrapper.h000066400000000000000000000053621262531651400211510ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef XMLPARSER_WRAPPER_H #define XMLPARSER_WRAPPER_H #include #include #include #include #include #include #if _XERCES_VERSION >= 30000 # include # include #else # include #endif #include /** * This wrapper controls the lifetime of the parser object. * * Initializing the parser is much more expensive than parsing a single XML document, therefore the parser should be reused if possible. * * It might make sense to use a singleton internally to keep the parser alive between usages. Alternatively this object can be kept alive for as long as it makes sense. * * This class also encapsulates the initialization of the whole parser, which must be done manually because precomiled schemas are used (which greatly improves the initialization performance). * * Writing the document is static and doesn't need any initialization and is therefore not wrapped by this object. * */ class XMLParserWrapper { public: XMLParserWrapper(); ~XMLParserWrapper(); /** * Threadsafe singleton. One Xerces instance is created per thread (threadlocal). * Access via singleton to reuse parser. */ static XMLParserWrapper &inst(); xml_schema::dom::auto_ptr parseFile(const std::string &url); xml_schema::dom::auto_ptr parseString(const std::string &s); xml_schema::dom::auto_ptr parse(std::istream &ifs, const std::string &name); private: void init(); xsd::cxx::tree::error_handler eh; xsd::cxx::xml::dom::bits::error_handler_proxy ehp; #if _XERCES_VERSION >= 30000 xercesc::DOMLSParser *parser; #else xercesc::DOMBuilder *parser; #endif xercesc::XMLGrammarPool *gp; }; #endif libkolabxml-1.1.2/compiled/grammar-input-stream.cxx000066400000000000000000000044471262531651400224250ustar00rootroot00000000000000// file : examples/cxx/tree/embedded/grammar-input-stream.cxx // author : Boris Kolpackov // copyright : not copyrighted - public domain #include #include "grammar-input-stream.hxx" grammar_input_stream:: grammar_input_stream (const XMLByte* data, std::size_t size) : data_ (data), size_ (size), pos_ (0), vpos_ (0), cseq_ (0), add_zero_ (false) { } #if _XERCES_VERSION >= 30000 XMLFilePos grammar_input_stream:: curPos () const { return static_cast (vpos_); } #else unsigned int grammar_input_stream:: curPos () const { return static_cast (vpos_); } #endif #if _XERCES_VERSION >= 30000 XMLSize_t grammar_input_stream:: readBytes (XMLByte* const buf, const XMLSize_t size) #else unsigned int grammar_input_stream:: readBytes (XMLByte* const buf, const unsigned int size) #endif { std::size_t i (0); // Add a zero from the alternating sequence if it didn't // fit on the previous read. // if (add_zero_) { buf[i++] = 0; add_zero_ = false; } // If have an unfinished sequential sequence, output it now. // if (cseq_ != 0 && !alt_) { for (; cseq_ != 0 && i < size; --cseq_) buf[i++] = 0; } for (; i < size && pos_ < size_;) { XMLByte b = buf[i++] = data_[pos_++]; // See if we are in a compression sequence. // if (cseq_ != 0) { if (i < size) buf[i++] = 0; else add_zero_ = true; // Add it on the next read. cseq_--; continue; } // If we are not in a compression sequence and this byte is // not zero then we are done. // if (b != 0) continue; // We have a zero. // assert (pos_ < size_); // There has to be another byte. unsigned char v (static_cast (data_[pos_++])); alt_ = (v & 128) != 0; cseq_ = v & 127; // If it is a sequential sequence, output as many zeros as // we can. // if (!alt_) { for (; cseq_ != 0 && i < size; --cseq_) buf[i++] = 0; } } vpos_ += i; #if _XERCES_VERSION >= 30000 return static_cast (i); #else return static_cast (i); #endif } #if _XERCES_VERSION >= 30000 const XMLCh* grammar_input_stream:: getContentType () const { return 0; } #endif libkolabxml-1.1.2/compiled/grammar-input-stream.hxx000066400000000000000000000022701262531651400224220ustar00rootroot00000000000000// file : examples/cxx/tree/embedded/grammar-input-stream.hxx // author : Boris Kolpackov // copyright : not copyrighted - public domain #ifndef GRAMMAR_INPUT_STREAM_HXX #define GRAMMAR_INPUT_STREAM_HXX #include #include // Memory buffer input stream with the special-purpose schema // grammar decompression. // class grammar_input_stream: public xercesc::BinInputStream { public : grammar_input_stream (const XMLByte* data, std::size_t size); #if _XERCES_VERSION >= 30000 virtual XMLFilePos curPos () const; virtual XMLSize_t readBytes (XMLByte* const buf, const XMLSize_t size); virtual const XMLCh* getContentType () const; #else virtual unsigned int curPos () const; virtual unsigned int readBytes (XMLByte* const buf, const unsigned int size); #endif private : const XMLByte* data_; std::size_t size_; std::size_t pos_; std::size_t vpos_; // Compression data. // size_t cseq_; // Number of bytes left in a compression sequence. bool alt_; // Alternating or sequential sequence. bool add_zero_; // Add a zero on the next read. }; #endif // GRAMMAR_INPUT_STREAM_HXX libkolabxml-1.1.2/compiled/xsdbin.cxx000066400000000000000000000263351262531651400176400ustar00rootroot00000000000000// file : examples/cxx/tree/embedded/xsdbin.cxx // author : Boris Kolpackov // copyright : not copyrighted - public domain // This program loads the XML Schema file(s) and converts them to // the Xerces-C++ binary schema format which can then be embedded // into C++ programs and used to validate XML documents. The output // is written as a C++ source file containing the array with the // binary data. // #include #include // std::auto_ptr #include // std::size_t #include #include #include #include #include #include #include #include #include #include #include #include #if _XERCES_VERSION >= 30000 # include #else # include #endif using namespace std; using namespace xercesc; class error_handler: public ErrorHandler { public: error_handler () : failed_ (false) { } bool failed () const { return failed_; } enum severity {s_warning, s_error, s_fatal}; virtual void warning (const SAXParseException&); virtual void error (const SAXParseException&); virtual void fatalError (const SAXParseException&); virtual void resetErrors () { failed_ = false; } void handle (const SAXParseException&, severity); private: bool failed_; }; void cxx_escape (string&); int main (int argc, char* argv[]) { const char* hxx_suffix = "-schema.hxx"; const char* cxx_suffix = "-schema.cxx"; string name; string base; string outdir; class usage {}; int argi (1); bool help (false); bool multi_import (true); bool verbose (false); try { for (; argi < argc; ++argi) { string a (argv[argi]); if (a == "--help") { help = true; throw usage (); } else if (a == "--verbose") { verbose = true; } else if (a == "--hxx-suffix") { if (++argi >= argc) throw usage (); hxx_suffix = argv[argi]; } else if (a == "--cxx-suffix") { if (++argi >= argc) throw usage (); cxx_suffix = argv[argi]; } else if (a == "--output-dir") { if (++argi >= argc) throw usage (); outdir = argv[argi]; } else if (a == "--array-name") { if (++argi >= argc) throw usage (); name = argv[argi]; } else if (a == "--disable-multi-import") { multi_import = false; } else break; } if (argi >= argc) { cerr << "no input file specified" << endl; throw usage (); } base = argv[argi]; } catch (usage const&) { cerr << "Usage: " << argv[0] << " [options] " << endl << "Options:" << endl << " --help Print usage information and exit." << endl << " --verbose Print progress information." << endl << " --output-dir Write generated files to ." << endl << " --hxx-suffix Header file suffix instead of '-schema.hxx'." << endl << " --cxx-suffix Source file suffix instead of '-schema.cxx'." << endl << " --array-name Binary data array name." << endl << " --disable-multi-import Disable multiple import support." << endl << endl; return help ? 0 : 1; } XMLPlatformUtils::Initialize (); { MemoryManager* mm (XMLPlatformUtils::fgMemoryManager); auto_ptr gp (new XMLGrammarPoolImpl (mm)); // Load the schemas into grammar pool. // { auto_ptr parser ( XMLReaderFactory::createXMLReader (mm, gp.get ())); parser->setFeature (XMLUni::fgSAX2CoreNameSpaces, true); parser->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true); parser->setFeature (XMLUni::fgSAX2CoreValidation, true); parser->setFeature (XMLUni::fgXercesSchema, true); parser->setFeature (XMLUni::fgXercesSchemaFullChecking, true); parser->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true); // Xerces-C++ 3.1.0 is the first version with working multi import // support. // #if _XERCES_VERSION >= 30100 parser->setFeature (XMLUni::fgXercesHandleMultipleImports, multi_import); #endif error_handler eh; parser->setErrorHandler (&eh); for (; argi < argc; ++argi) { if (verbose) cerr << "loading " << argv[argi] << endl; if (!parser->loadGrammar (argv[argi], Grammar::SchemaGrammarType, true)) { cerr << argv[argi] << ": error: unable to load" << endl; return 1; } if (eh.failed ()) return 1; } } // Get the binary representation. // BinMemOutputStream data; try { gp->serializeGrammars (&data); } catch (const XSerializationException& e) { char* msg (XMLString::transcode (e.getMessage ())); cerr << "error: " << msg << endl; XMLString::release (&msg); return 1; } size_t n (static_cast (data.curPos ())); const unsigned char* buf ( static_cast (data.getRawBuffer ())); if (verbose) cerr << "uncomressed data size " << n << " bytes" << endl; // Compress zeros. // size_t cn (0); unsigned char* cbuf = new unsigned char[n]; size_t cseq (0); // Number of bytes left in a compression sequence. bool alt (false); // Alternating or sequential sequence. for (size_t i (0); i < n;) { unsigned char v (buf[i++]); // See if we are in a compression sequence. // if (cseq != 0) { // See if this byte needs to be copied. // if (alt && cseq % 2 == 0) cbuf[cn++] = v; cseq--; continue; } // If we are not in a compression sequence and this byte is // not zero then simply copy it. // if (v != 0) { cbuf[cn++] = v; continue; } // We have a zero. // cbuf[cn++] = 0; // See if we can start a new compression sequence. // if (i < n) { if (buf[i] == 0) { // Sequential sequence. See how far it runs. // alt = false; for (cseq = 1; cseq < 127 && cseq + i < n; cseq++) if (buf[cseq + i] != 0) break; } else if (i + 1 < n && buf[i + 1] == 0) { // Alternating sequence. See how far it runs. // alt = true; for (cseq = 1; cseq < 127 && cseq * 2 + i + 1 < n; cseq++) { if (buf[cseq * 2 + i + 1] != 0) break; // For longer sequences prefer sequential to alternating. // if (cseq > 2 && buf[cseq * 2 + i] == 0 && buf[(cseq - 1) * 2 + i] == 0 && buf[(cseq - 2) * 2 + i] == 0) { cseq -= 2; break; } } cseq *= 2; } } if (cseq != 0) { cbuf[cn++] = static_cast ( alt ? (128 | cseq / 2) : cseq); } else cbuf[cn++] = 0; } if (verbose) cerr << "comressed data size " << cn << " bytes" << endl; buf = cbuf; n = cn; // Figure out the file names. // string::size_type p (base.rfind ('/')), p1 (base.rfind ('\\')); if (p1 != string::npos && p1 > p) p = p1; if (p != string::npos) base = string (base, p + 1); p = base.rfind ('.'); if (p != string::npos) base.resize (p); string hxx (base + hxx_suffix); string cxx (base + cxx_suffix); if (!outdir.empty ()) { #if defined (WIN32) || defined (__WIN32__) hxx = outdir + '\\' + hxx; cxx = outdir + '\\' + cxx; #else hxx = outdir + '/' + hxx; cxx = outdir + '/' + cxx; #endif } if (name.empty ()) { name = base + "_schema"; cxx_escape (name); } // Write header. // { ofstream os (hxx.c_str ()); if (!os.is_open ()) { cerr << hxx << ": error: unable to open" << endl; return 1; } os << "// Automatically generated. Do not edit." << endl << "//" << endl << endl << "#include " << endl << endl << "extern const XMLByte " << name << "[" << n << "UL];" << endl; } { ofstream os (cxx.c_str ()); if (!os.is_open ()) { cerr << cxx << ": error: unable to open" << endl; return 1; } os << "// Automatically generated. Do not edit." << endl << "//" << endl << endl << "#include " << endl << "#include " << endl << endl << "#if XERCES_GRAMMAR_SERIALIZATION_LEVEL != " << XERCES_GRAMMAR_SERIALIZATION_LEVEL << endl << "# error incompatible Xerces-C++ version detected" << endl << "#endif" << endl << endl << "extern const XMLByte " << name << "[" << n << "UL] =" << endl << "{"; for (size_t i (0); i < n; ++i) { if (i != 0) os << ','; os << (i % 12 == 0 ? "\n " : " ") << "0x"; os.width (2); os.fill ('0'); os << hex << static_cast (buf[i]); } os << endl << "};" << endl << endl; } delete[] cbuf; } XMLPlatformUtils::Terminate (); } void cxx_escape (string& s) { for (string::size_type i (0); i < s.size (); ++i) { char& c (s[i]); if (i == 0) { if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_')) c = '_'; } else { if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) c = '_'; } } } void error_handler:: warning (const SAXParseException& e) { handle (e, s_warning); } void error_handler:: error (const SAXParseException& e) { failed_ = true; handle (e, s_error); } void error_handler:: fatalError (const SAXParseException& e) { failed_ = true; handle (e, s_fatal); } void error_handler:: handle (const SAXParseException& e, severity s) { const XMLCh* xid (e.getPublicId ()); if (xid == 0) xid = e.getSystemId (); char* id (XMLString::transcode (xid)); char* msg (XMLString::transcode (e.getMessage ())); cerr << id << ":"; #if _XERCES_VERSION >= 30000 cerr << e.getLineNumber () << ":" << e.getColumnNumber () << " "; #else XMLSSize_t l (e.getLineNumber ()); XMLSSize_t c (e.getColumnNumber ()); cerr << (l == -1 ? 0 : l) << ":" << (c == -1 ? 0 : c) << " "; #endif cerr << (s == s_warning ? "warning: " : "error: ") << msg << endl; XMLString::release (&id); XMLString::release (&msg); } libkolabxml-1.1.2/libkolabxml-version.h.cmake000066400000000000000000000020041262531651400212270ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef LIBKOLABXML_VERSION_H #define LIBKOLABXML_VERSION_H #define KOLAB_LIBNAME "@CMAKE_PROJECT_NAME@" #define KOLAB_LIB_VERSION "@Libkolabxml_VERSION@" #define KOLAB_LIB_VERSION_STRING "@Libkolabxml_VERSION_STRING@" #define KOLAB_FORMAT_VERSION "@KOLAB_FORMAT_VERSION@" #endif libkolabxml-1.1.2/schemas/000077500000000000000000000000001262531651400154435ustar00rootroot00000000000000libkolabxml-1.1.2/schemas/Makefile.am000066400000000000000000000000741262531651400175000ustar00rootroot00000000000000EXTRA_DIST = \ $(wildcard *.xsd) \ $(wildcard ical/*.xsd) libkolabxml-1.1.2/schemas/ical/000077500000000000000000000000001262531651400163535ustar00rootroot00000000000000libkolabxml-1.1.2/schemas/ical/iCalendar-availability-extension.xsd000066400000000000000000000076031262531651400254450ustar00rootroot00000000000000 encodingparam = "ENCODING" "=" ( "8BIT" ; "8bit" text encoding is defined in [RFC2045] / "BASE64" ; "BASE64" binary encoding format is defined in [RFC4648] ) busytypevalue = "BUSY" / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE" / iana-token / x-name ; Default is "BUSY-UNAVAILABLE". libkolabxml-1.1.2/schemas/ical/iCalendar-bw-extensions.xsd000066400000000000000000000060761262531651400235710ustar00rootroot00000000000000 libkolabxml-1.1.2/schemas/ical/iCalendar-link-extension.xsd000066400000000000000000000047321262531651400237300ustar00rootroot00000000000000 libkolabxml-1.1.2/schemas/ical/iCalendar-ms-extensions.xsd000066400000000000000000000037201262531651400235710ustar00rootroot00000000000000 libkolabxml-1.1.2/schemas/ical/iCalendar-params.xsd000066400000000000000000000401621262531651400222410ustar00rootroot00000000000000 cutypeparam = "CUTYPE" "=" ("INDIVIDUAL" ; An individual / "GROUP" ; A group of individuals / "RESOURCE" ; A physical resource / "ROOM" ; A room resource / "UNKNOWN" ; Otherwise not known / x-name ; Experimental type / iana-token) ; Other IANA-registered ; type ; Default is INDIVIDUAL encodingparam = "ENCODING" "=" ( "8BIT" ; "8bit" text encoding is defined in [RFC2045] / "BASE64" ; "BASE64" binary encoding format is defined in [RFC4648] ) fbtypeparam = "FBTYPE" "=" ("FREE" / "BUSY" / "BUSY-UNAVAILABLE" / "BUSY-TENTATIVE" / x-name ; Some experimental iCalendar free/busy type. / iana-token) ; Some other IANA-registered iCalendar free/busy type. ; Default is BUSY partstat-event = ("NEEDS-ACTION" ; Event needs action / "ACCEPTED" ; Event accepted / "DECLINED" ; Event declined / "TENTATIVE" ; Event tentatively ; accepted / "DELEGATED" ; Event delegated / x-name ; Experimental status / iana-token) ; Other IANA-registered ; status ; These are the participation statuses for a "VEVENT". ; Default is NEEDS-ACTION. partstat-todo = ("NEEDS-ACTION" ; To-do needs action / "ACCEPTED" ; To-do accepted / "DECLINED" ; To-do declined / "TENTATIVE" ; To-do tentatively ; accepted / "DELEGATED" ; To-do delegated / "COMPLETED" ; To-do completed ; COMPLETED property has ; DATE-TIME completed / "IN-PROCESS" ; To-do in process of ; being completed / x-name ; Experimental status / iana-token) ; Other IANA-registered ; status ; These are the participation statuses for a "VTODO". ; Default is NEEDS-ACTION. partstat-jour = ("NEEDS-ACTION" ; Journal needs action / "ACCEPTED" ; Journal accepted / "DECLINED" ; Journal declined / x-name ; Experimental status / iana-token) ; Other IANA-registered ; status ; These are the participation statuses for a "VJOURNAL". ; Default is NEEDS-ACTION. trigrelparam = "RELATED" "=" ("START" ; Trigger off of start / "END") ; Trigger off of end reltypeparam = "RELTYPE" "=" ("PARENT" ; Parent relationship - Default / "CHILD" ; Child relationship / "SIBLING" ; Sibling relationship / iana-token ; Some other IANA-registered ; iCalendar relationship type / x-name) ; A non-standard, experimental ; relationship type Ws-Calendar adds the values / "FINISHTOSTART" / "FINISHTOFINISH" / "STARTTOFINISH" / "STARTTOSTART" ; Default is PARENT Standard values "CHAIR" "REQ-PARTICIPANT" "OPT-PARTICIPANT" "NON-PARTICIPANT" scheduleagentparam = "SCHEDULE-AGENT" "=" ("SERVER" ; The server handles scheduling / "CLIENT" ; The client handles scheduling / "NONE" ; No automatic scheduling / x-name ; Experimental type / iana-token) ; Other IANA registered type ; ; Default is SERVER scheduleforcesendparam = "SCHEDULE-FORCE-SEND" "=" ("REQUEST" ; Force a "REQUEST" / "REPLY" ; Force a "REPLY" / iana-token) ; IANA registered method libkolabxml-1.1.2/schemas/ical/iCalendar-props.xsd000066400000000000000000000662321262531651400221270ustar00rootroot00000000000000 classvalue = "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token / x-name ;Default is PUBLIC status = "STATUS" statparam ":" statvalue CRLF statparam = *(";" other-param) statvalue = (statvalue-event / statvalue-todo / statvalue-jour) statvalue-event = "TENTATIVE" ;Indicates event is tentative. / "CONFIRMED" ;Indicates event is definite. / "CANCELLED" ;Indicates event was cancelled. ;Status values for a "VEVENT" statvalue-todo = "NEEDS-ACTION" ;Indicates to-do needs action. / "COMPLETED" ;Indicates to-do completed. / "IN-PROCESS" ;Indicates to-do in process of. / "CANCELLED" ;Indicates to-do was cancelled. ;Status values for "VTODO". statvalue-jour = "DRAFT" ;Indicates journal is draft. / "FINAL" ;Indicates journal is final. / "CANCELLED" ;Indicates journal is removed. ;Status values for "VJOURNAL". transvalue = "OPAQUE" ;Blocks or opaque on busy time searches. / "TRANSPARENT" ;Transparent on busy time searches. ;Default value is OPAQUE actionvalue = "AUDIO" / "DISPLAY" / "EMAIL" / iana-token / x-name libkolabxml-1.1.2/schemas/ical/iCalendar-valtypes.xsd000066400000000000000000000231661262531651400226320ustar00rootroot00000000000000 Durations are a problem: XML schema types allow Years, Months, Days, Hours, Minutes, Seconds Ical allows Weeks, Days, Hours, Minutes, Seconds These overlap and we really need a combination of both. So the compromise is to have a pattern restricted String type and note that if data is to be exported into the icalendar world it cannot have years or months. Ultimately it is to be hoped the two worlds can be aligned. RFC5545 (icalendar) specifies dur-value = (["+"] / "-") "P" (dur-date / dur-time / dur-week) dur-date = dur-day [dur-time] dur-time = "T" (dur-hour / dur-minute / dur-second) dur-week = 1*DIGIT "W" dur-hour = 1*DIGIT "H" [dur-minute] dur-minute = 1*DIGIT "M" [dur-second] dur-second = 1*DIGIT "S" dur-day = 1*DIGIT "D" So P5W is valid: P5WT10M is not. If weeks re specified nothing else can be XML specifies PnYnMnDTnHnMnS The elements must appear in the order specified and the 'T' is omitted if hours minutes and seconds are absent. libkolabxml-1.1.2/schemas/ical/iCalendar-wscal-extensions.xsd000066400000000000000000000162451262531651400242710ustar00rootroot00000000000000 A tolerance value is a set of durations which indicate the allowed tolerance for the indicated value, e.g. startafter=PT5M indicates that 5 minutes late is acceptable. A gluon takes vavailability. An interval takes no sub-components. types the content of the xCal attach element The artifact is here to handle elements that are not proper extensions of wsCalendar. The artifact Base is here for use in extending by other specifications allowing attributes from other namespaces to be added to ws-calendar-based schemas. The artifact Base is here for use in extending by other specifications, to to allow attributes from other namespaces to be added to ws-calendar-based schemas. libkolabxml-1.1.2/schemas/ical/iCalendar.rng000066400000000000000000000431771262531651400207610ustar00rootroot00000000000000# Relax NG Schema for iCalendar in XML default namespace = "urn:ietf:params:xml:ns:icalendar-2.0" # 3.2 Property Parameters # 3.2.1 Alternate Text Representation altrepparam = element altrep { value-uri } # 3.2.2 Common Name cnparam = element cn { value-text } # 3.2.3 Calendar User Type cutypeparam = element cutype { element text { "INDIVIDUAL" | "GROUP" | "RESOURCE" | "ROOM" | "UNKNOWN" } } # 3.2.4 Delegators delfromparam = element delegated-from { value-cal-address+ } # 3.2.5 Delegatees deltoparam = element delegated-to { value-cal-address+ } # 3.2.6 Directory Entry Reference dirparam = element dir { value-uri } # 3.2.7 Inline Encoding encodingparam = element encoding { element text { "8BIT" | "BASE64" } } # 3.2.8 Format Type fmttypeparam = element fmttype { value-text } # 3.2.9 Free/Busy Time Type fbtypeparam = element fbtype { element text { "FREE" | "BUSY" | "BUSY-UNAVAILABLE" | "BUSY-TENTATIVE" } } # 3.2.10 Language languageparam = element language { value-text } # 3.2.11 Group or List Membership memberparam = element member { value-cal-address+ } # 3.2.12 Participation Status partstatparam = element partstat { type-partstat-event | type-partstat-todo | type-partstat-jour } type-partstat-event = ( element text { "NEEDS-ACTION" | "ACCEPTED" | "DECLINED" | "TENTATIVE" | "DELEGATED" } ) type-partstat-todo = ( element text { "NEEDS-ACTION" | "ACCEPTED" | "DECLINED" | "TENTATIVE" | "DELEGATED" | "COMPLETED" | "IN-PROCESS" } ) type-partstat-jour = ( element text { "NEEDS-ACTION" | "ACCEPTED" | "DECLINED" } ) # 3.2.13 Recurrence Identifier Range rangeparam = element range { element text { "THISANDFUTURE" } } # 3.2.14 Alarm Trigger Relationship trigrelparam = element related { element text { "START" | "END" } } # 3.2.15 Relationship Type reltypeparam = element reltype { element text { "PARENT" | "CHILD" | "SIBLING" } } # 3.2.16 Participation Role roleparam = element role { element text { "CHAIR" | "REQ-PARTICIPANT" | "OPT-PARTICIPANT" | "NON-PARTICIPANT" } } # 3.2.17 RSVP Expectation rsvpparam = element rsvp { value-boolean } # 3.2.18 Sent By sentbyparam = element sent-by { value-cal-address } # 3.2.19 Time Zone Identifier tzidparam = element tzid { value-text } # 3.3 Property Value Data Types # 3.3.1 BINARY value-binary = element binary { xsd:string } # 3.3.2 BOOLEAN value-boolean = element boolean { xsd:boolean } # 3.3.3 CAL-ADDRESS value-cal-address = element cal-address { xsd:anyURI } # 3.3.4 DATE pattern-date = xsd:string { pattern = "\d\d\d\d-\d\d-\d\d" } value-date = element date { pattern-date } # 3.3.5 DATE-TIME pattern-date-time = xsd:string { pattern = "\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\dZ?" } value-date-time = element date-time { pattern-date-time } # 3.3.6 DURATION pattern-duration = xsd:string { pattern = "[+\-]?P(\d+W)|(\d+D)?" ~ "(T(\d+H(\d+M)?(\d+S)?)|" ~ "(\d+M(\d+S)?)|" ~ "(\d+S))?" } value-duration = element duration { pattern-duration } # 3.3.7 FLOAT value-float = element float { xsd:float } # 3.3.8 INTEGER value-integer = element integer { xsd:integer } # 3.3.9 PERIOD value-period = element period { element start { pattern-date-time }, ( element end { pattern-date-time } | element duration { pattern-duration } ) } # 3.3.10 RECUR value-recur = element recur { type-freq, (type-until | type-count)?, element interval { xsd:positiveInteger }?, type-bysecond*, type-byminute*, type-byhour*, type-byday*, type-bymonthday*, type-byyearday*, type-byweekno*, type-bymonth*, type-bysetpos*, element wkst { type-weekday }? } type-freq = element freq { "SECONDLY" | "MINUTELY" | "HOURLY" | "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY" } type-until = element until { type-date | type-date-time } type-count = element count { xsd:positiveInteger } type-bysecond = element bysecond { xsd:positiveInteger } type-byminute = element byminute { xsd:positiveInteger } type-byhour = element byhour { xsd:positiveInteger } type-weekday = ( "SU" | "MO" | "TU" | "WE" | "TH" | "FR" | "SA" ) type-byday = element byday { xsd:integer?, type-weekday } type-bymonthday = element bymonthday { xsd:integer } type-byyearday = element byyearday { xsd:integer } type-byweekno = element byweekno { xsd:integer } type-bymonth = element bymonth { xsd:positiveInteger } type-bysetpos = element bysetpos { xsd:integer } # 3.3.11 TEXT value-text = element text { xsd:string } # 3.3.12 TIME pattern-time = xsd:string { pattern = "\d\d:\d\d:\d\dZ?" } value-time = element time { pattern-time } # 3.3.13 URI value-uri = element uri { xsd:anyURI } # 3.3.14 UTC-OFFSET value-utc-offset = element utc-offset { xsd:string { pattern = "[+\-]\d\d:\d\d" } } # UNKNOWN value-unknown = element unknown { xsd:string } # 3.4 iCalendar Stream start = element icalendar { vcalendar+ } # 3.6 Calendar Components vcalendar = element vcalendar { type-calprops, type-component } type-calprops = element properties { property-prodid & property-version & property-calscale? & property-method? } type-component = element components { ( component-vevent | component-vtodo | component-vjournal | component-vfreebusy | component-vtimezone )* } # 3.6.1 Event Component component-vevent = element vevent { type-eventprop, element components { component-valarm+ }? } type-eventprop = element properties { property-dtstamp & property-dtstart & property-uid & property-class? & property-created? & property-description? & property-geo? & property-last-mod? & property-location? & property-organizer? & property-priority? & property-seq? & property-status-event? & property-summary? & property-transp? & property-url? & property-recurid? & property-rrule? & (property-dtend | property-duration)? & property-attach* & property-attendee* & property-categories* & property-comment* & property-contact* & property-exdate* & property-rstatus* & property-related* & property-resources* & property-rdate* } # 3.6.2 To-do Component component-vtodo = element vtodo { type-todoprop, element components { component-valarm+ }? } type-todoprop = element properties { property-dtstamp & property-uid & property-class? & property-completed? & property-created? & property-description? & property-geo? & property-last-mod? & property-location? & property-organizer? & property-percent? & property-priority? & property-recurid? & property-seq? & property-status-todo? & property-summary? & property-url? & property-rrule? & ( (property-dtstart?, property-dtend? ) | (property-dtstart, property-duration)? ) & property-attach* & property-attendee* & property-categories* & property-comment* & property-contact* & property-exdate* & property-rstatus* & property-related* & property-resources* & property-rdate* } # 3.6.3 Journal Component component-vjournal = element vjournal { type-jourprop } type-jourprop = element properties { property-dtstamp & property-uid & property-class? & property-created? & property-dtstart? & property-last-mod? & property-organizer? & property-recurid? & property-seq? & property-status-jour? & property-summary? & property-url? & property-rrule? & property-attach* & property-attendee* & property-categories* & property-comment* & property-contact* & property-description? & property-exdate* & property-related* & property-rdate* & property-rstatus* } # 3.6.4 Free/Busy Component component-vfreebusy = element vfreebusy { type-fbprop } type-fbprop = element properties { property-dtstamp & property-uid & property-contact? & property-dtstart? & property-dtend? & property-duration? & property-organizer? & property-url? & property-attendee* & property-comment* & property-freebusy* & property-rstatus* } # 3.6.5 Time Zone Component component-vtimezone = element vtimezone { element properties { property-tzid & property-last-mod? & property-tzuurl? }, element components { (component-standard | component-daylight) & component-standard* & component-daylight* } } component-standard = element standard { type-tzprop } component-daylight = element daylight { type-tzprop } type-tzprop = element properties { property-dtstart & property-tzoffsetto & property-tzoffsetfrom & property-rrule? & property-comment* & property-rdate* & property-tzname* } # 3.6.6 Alarm Component component-valarm = element valarm { audioprop | dispprop | emailprop } type-audioprop = element properties { property-action & property-trigger & (property-duration, property-repeat)? & property-attach? } type-dispprop = element properties { property-action & property-description & property-trigger & property-summary & property-attendee+ & (property-duration, property-repeat)? & property-attach* } type-emailprop = element properties { property-action & property-description & property-trigger & (property-duration, property-repeat)? } # 3.7 Calendar Properties # 3.7.1 Calendar Scale property-calscale = element calscale { element parameters { empty }?, element text { "GREGORIAN" } } # 3.7.2 Method property-method = element method { element parameters { empty }?, value-text } # 3.7.3 Product Identifier property-prodid = element prodid { element parameters { empty }?, value-text } # 3.7.4 Version property-version = element version { element parameters { empty }?, element text { "2.0" } } # 3.8 Component Properties # 3.8.1 Descriptive Component Properties # 3.8.1.1 Attachment property-attach = element attach { element parameters { fmttypeparam? & encodingparam? }?, value-uri | value-binary } # 3.8.1.2 Categories property-categories = element categories { element parameters { languageparam? & }?, value-text+ } # 3.8.1.3 Classification property-class = element class { element parameters { empty }?, element text { "PUBLIC" | "PRIVATE" | "CONFIDENTIAL" } } # 3.8.1.4 Comment property-comment = element comment { element parameters { altrepparam? & languageparam? }?, value-text } # 3.8.1.5 Description property-description = element description { element parameters { altrepparam? & languageparam? }?, value-text } # 3.8.1.6 Geographic Position property-geo = element geo { element parameters { empty }?, element latitude { xsd:float }, element longitude { xsd:float } } # 3.8.1.7 Location property-location = element location { element parameters { altrepparam? & languageparam? }?, value-text } # 3.8.1.8 Percent Complete property-percent = element percent-complete { element parameters { empty }?, value-integer } # 3.8.1.9 Priority property-priority = element priority { element parameters { empty }?, value-integer } # 3.8.1.10 Resources property-resources = element resources { element parameters { altrepparam? & languageparam? }?, value-text+ } # 3.8.1.11 Status property-status-event = element status { element parameters { empty }?, element text { "TENTATIVE" | "CONFIRMED" | "CANCELLED" } } property-status-todo = element status { element parameters { empty }?, element text { "NEEDS-ACTION" | "COMPLETED" | "IN-PROCESS" | "CANCELLED" } } property-status-jour = element status { element parameters { empty }?, element text { "DRAFT" | "FINAL" | "CANCELLED" } } # 3.8.1.12 Summary property-summary = element summary { element parameters { altrepparam? & languageparam? }?, value-text } # 3.8.2 Date and Time Component Properties # 3.8.2.1 Date/Time Completed property-completed = element completed { element parameters { empty }?, value-date-time } # 3.8.2.2 Date/Time End property-dtend = element dtend { element parameters { tzidparam? }?, value-date-time | value-date } # 3.8.2.3 Date/Time Due property-due = element due { element parameters { tzidparam? }?, value-date-time | value-date } # 3.8.2.4 Date/Time Start property-dtstart = element dtstart { element parameters { tzidparam? }?, value-date-time | value-date } # 3.8.2.5 Duration property-duration = element duration { element parameters { empty }?, value-duration } # 3.8.2.6 Free/Busy Time property-freebusy = element freebusy { element parameters { fbtypeparam? }?, value-period+ } # 3.8.2.7 Time Transparency property-transp = element transp { element parameters { empty }?, element text { "OPAQUE" | "TRANSPARENT" } } # 3.8.3 Time Zone Component Properties # 3.8.3.1 Time Zone Identifier property-tzid = element tzid { element parameters { empty }?, value-text } # 3.8.3.2 Time Zone Name property-tzname = element tzname { element parameters { languageparam? }?, value-text } # 3.8.3.3 Time Zone Offset From property-tzoffsetfrom = element tzoffsetfrom { element parameters { empty }?, value-utc-offset } # 3.8.3.4 Time Zone Offset To property-tzoffsetto = element tzoffsetto { element parameters { empty }?, value-utc-offset } # 3.8.3.5 Time Zone URL property-tzurl = element tzurl { element parameters { empty }?, value-uri } # 3.8.4 Relationship Component Properties # 3.8.4.1 Attendee property-attendee = element attendee { element parameters { cutypeparam? & memberparam? & roleparam? & partstatparam? & rsvpparam? & deltoparam? & delfromparam? & sentbyparam? & cnparam? & dirparam? & languageparam? }?, value-cal-address } # 3.8.4.2 Contact property-contact = element contact { element parameters { altrepparam? & languageparam? }?, value-text } # 3.8.4.3 Organizer property-organizer = element organizer { element parameters { cnparam? & dirparam? & sentbyparam? & languageparam? }?, value-cal-address } # 3.8.4.4 Recurrence ID property-recurid = element recurrence-id { element parameters { tzidparam? & rangeparam? }?, value-date-time | value-date } # 3.8.4.5 Related-To property-related = element related-to { element parameters { reltypeparam? }?, value-text } # 3.8.4.6 Uniform Resource Locator property-url = element url { element parameters { empty }?, value-uri } # 3.8.4.7 Unique Identifier property-uid = element uid { element parameters { empty }?, value-text } # 3.8.5 Recurrence Component Properties # 3.8.5.1 Exception Date/Times property-exdate = element exdate { element parameters { tzidparam? }?, value-date-time+ | value-date+ } # 3.8.5.2 Recurrence Date/Times property-rdate = element rdate { element parameters { tzidparam? }?, value-date-time+ | value-date+ | value-period+ } # 3.8.5.3 Recurrence Rule property-rrule = element rrule { element parameters { empty }?, value-recur } # 3.8.6 Alarm Component Properties # 3.8.6.1 Action property-action = element action { element parameters { empty }?, element text { "AUDIO" | "DISPLAY" | "EMAIL" } } # 3.8.6.2 Repeat Count property-repeat = element repeat { element parameters { empty }?, value-integer } # 3.8.6.3 Trigger property-trigger = element trigger { ( element parameters { trigrelparam? }?, value-duration ) | ( element parameters { empty }?, value-date-time ) } # 3.8.7 Change Management Component Properties # 3.8.7.1 Date/Time Created property-created = element created { element parameters { empty }?, value-date-time } # 3.8.7.2 Date/Time Stamp property-dtstamp = element dtstamp { element parameters { empty }?, value-date-time } # 3.8.7.3 Last Modified property-last-mod = element last-modified { element parameters { empty }?, value-date-time } # 3.8.7.4 Sequence Number property-seq = element sequence { element parameters { empty }?, value-integer } # 3.8.8 Miscellaneous Component Properties # 3.8.8.3 Request Status property-rstatus = element request-status { element parameters { languageparam? }?, element code { xsd:string }, element description { xsd:string }, element data { xsd:string }? } libkolabxml-1.1.2/schemas/ical/iCalendar.xsd000066400000000000000000000215131262531651400207570ustar00rootroot00000000000000 This type is the basis for all components and provides a base class for applications. Essentially it states that a component is a set of properties. This type is the basis for all components and provides a base class for applications. This type is the basis for all components that can be contained within a vcalendar component Events and todos only contain alarms Journal components contain no other components Freebusy components contain no other components Timezones only contain daylight and standard Standard components contain no other components Daylight components contain no other components Alarms contain no components libkolabxml-1.1.2/schemas/ical/kolabformat-xcal.xsd000066400000000000000000000323071262531651400223260ustar00rootroot00000000000000 libkolabxml-1.1.2/schemas/kolabformat-xcard.xsd000066400000000000000000000142621262531651400215700ustar00rootroot00000000000000 libkolabxml-1.1.2/schemas/kolabformat.xsd000066400000000000000000000165371262531651400205000ustar00rootroot00000000000000 libkolabxml-1.1.2/schemas/xCard.xsd000066400000000000000000000332411262531651400172270ustar00rootroot00000000000000 libkolabxml-1.1.2/src/000077500000000000000000000000001262531651400146075ustar00rootroot00000000000000libkolabxml-1.1.2/src/CMakeLists.txt000066400000000000000000000064521262531651400173560ustar00rootroot00000000000000 #This property is not available anymore here, although present in the parent file. SET_SOURCE_FILES_PROPERTIES(${SCHEMA_SOURCEFILES} PROPERTIES GENERATED 1) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -Wp,-D_FORTIFY_SOURCE=2 -O2" ) #always generate shared libraries with -fPIC, -D_FORTIFY_SOURCE=2 enables some extra checking # Library with serialization/deserialization code and kolab-containers add_library(kolabxml SHARED kolabformat.cpp objectvalidation.cpp containers/kolabcontainers.cpp containers/kolabnote.cpp containers/kolabevent.cpp containers/kolabtodo.cpp containers/kolabjournal.cpp containers/kolabcontact.cpp containers/kolabconfiguration.cpp containers/kolabfreebusy.cpp containers/kolabfile.cpp utils.cpp base64.cpp uriencode.cpp ../compiled/XMLParserWrapper.cpp ../compiled/grammar-input-stream.cxx ${SCHEMA_SOURCEFILES} ) add_dependencies(kolabxml generate_bindings) target_link_libraries(kolabxml ${XERCES_C} ${Boost_LIBRARIES} ${UUID} ${CURL}) # For the core library we can be stricter when compiling. This doesn't work with the auto generated code though. if (${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.42) # We can't be as strict on with older versions of boost it seems (not sure if this is the exact version number where it breaks) # Since this is only for el5 compatibility we relax the rules (resulting in a couple of warning but a working build) #for development add here -Werror -Wfatal-errors (but don't for releases) set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Wconversion") else() #then normal case #for development add here -Werror -Wfatal-errors (but don't for releases) set_target_properties(kolabxml PROPERTIES COMPILE_FLAGS "-Wall -Wextra -Wconversion -Wl,--no-undefined") endif() set_target_properties(kolabxml PROPERTIES VERSION ${Libkolabxml_VERSION} SOVERSION ${Libkolabxml_VERSION_MAJOR}) install(TARGETS kolabxml EXPORT LibkolabxmlExport RUNTIME DESTINATION ${BIN_INSTALL_DIR} LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} ) install( FILES kolabformat.h containers/kolabevent.h containers/kolabevent_p.h containers/incidence_p.h containers/kolabtodo.h containers/kolabjournal.h containers/kolabcontact.h containers/kolabnote.h containers/kolabcontainers.h containers/kolabconfiguration.h containers/kolabfreebusy.h containers/kolabfile.h global_definitions.h DESTINATION ${INCLUDE_INSTALL_DIR}) #-----------------------SWIG-------------------- # Building of the bindings can be controlled using the switches along the lines of: cmake -DPHP_BINDINGS=TRUE -DCSHARP_BINDINGS=FALSE .. if (SWIG_FOUND) if(CSHARP_BINDINGS) message("building csharp bindings") add_subdirectory(csharp) endif(CSHARP_BINDINGS) if(JAVA_BINDINGS) message("building java bindings") add_subdirectory(java) endif(JAVA_BINDINGS) if(PYTHON_BINDINGS) message("building python bindings") add_subdirectory(python) endif(PYTHON_BINDINGS) if(PHP_BINDINGS) message("building php bindings") add_subdirectory(php) endif(PHP_BINDINGS) else() message(WARNING "Could not build SWIG bindings, because SWIG is missing.") endif() libkolabxml-1.1.2/src/DEVELOPMENT000066400000000000000000000155471262531651400163300ustar00rootroot00000000000000== General Design Notes== * Although many values are optional, the library doesn't differentiate between set and not set values. The approach taken is to not write out values which are still on the default value in order to keep objects small. The downside of this is that an xml object could be modified although no values have been modified (because default values are not written out again). == Libraries == === libkolabxml === Dependencies: * boost * xerces The core library providing the xml-serialization functions and containers for all types. === libkolabkcal === Dependencies: * libkolabxml * kcalcore * kdecore Library to provide converters to KCalCore containers as well as advanced functionality from KCalCore (such as expansion of recurrences) through SWIG bindings. === kolabxmlkcal (deprecated) === First approach which does a direct mapping from xml to KCalCore containers. It turned out to be quite complicated to write generic enough code which would work for both, the Kolab containers and the KCalCore containers. Also the performance and memory overhead of the additional intermediate representation should be minimal, therefore this approach was abandonend. == Code architecture == Care was taken to implement each conversion/mapping only once. The code makes heavy use of templates to achieve this. Due to the different formats the conversion functions were split up among formats (not much to share between those). xCal: genericxcalconversions.h, xcalconversions.h (genericxcalconversions are implementations which work for both Kolab Containers and KCalCore containers) xCard: kolabxcardconversions.h kolab: kolabconversions.h (TODO) All conversions are typesafe as far as possible (i.e. a conversion from uint to int is always done through a numeric cast), to make sure there are no hard-to-track-down edge cases (such as an overflow). == Kolab Containers == While SWIG can handle all possible return values, the resulting code uses either a newly allocated object (return by value / or return by const reference), or passes back a pointer (return by reference/pointer). So return by const reference doesn't save anything for the bindings (it could potentially for c++ code). Returning references contains the danger of dangling pointers if the reference outlives the object. Datamembers are not directly exposed to provide binary compatibilty through the d-pointer. Providing non-const references to the value through an accessor function doesn't work because it couldn't be called on const objects (even to read the value). Therefore providing a setter + a getter which returns by copy seems the safest way. A const ref getter could be provided if needed (I doubt it would ever help). The containers do not use inheritance to ensure maximum compatibilty with SWIG (although SWIG provides inheritance for some languages). They were also designed to be easily copieable and make therefore minimal use of pointers. Due to this design taking a copy of a container should be very efficient and problems like object slicing can not occur. The containers are meant to not contain any logic, all logic should be implemented in the serialization functions. The validity of the containers can be checked using the isValid() function. This function is used to check if a value has been set, and does not really verifiy the validity of the values in terms of what ranges/combinations are allowed. === Why KCalCore containers were not directly used === KCalCore provides containers for all ical based functionality (events/todos/journals). They were not directly used because: - dependencies: depends on kdelibs and qt (event qt gui). Some serious work would be needed to be able to ship those containers with a minimum set of dependencies. - SWIG: It seems difficult to properly wrap those containers using SWIG (inheritance heavily used, Qt containers (for which we have no bindings), not easily copiable (special copy memberfucntion is needed due to internal use of pointers)) - Consistency: because we anyways have containers out of the scope of KCalCore, we can provide this way a consistent interface, which represents exactly the Kolab defined functionality (while KCalCore would be a close, but not a perfect match). Overall using our own containers seems like the safer and more flexible approach. This way it's also possible to provide a reading/writing library with a minimum set of dependencies. == SWIG language bindings == Bindings for PHP and Python are provided through SWIG. "make install" produces two directories with the necessary files in build/lib/pythonbindings and build/lib/phpbindings. The test script should show the usage of the bindings. == Performance == The biggest performance hog is the initialization of the parser. First, when loading the schema from disk upon initialization, parsing a single file took ~16ms on my machine (just for comparison). After compiling the schema to a binary representation, it still took ~7ms. By reusing the parser it went down to ~0.35ms. Writing the files is not validating and therefore always fast (doesn't need a special parser or alike). Once the parser is initialized, reading is roughly as fast as writing. Currently the parser is kept in a singleton (XMLParserWrapper). Alternatively one could control the lifetime from the bindings through an initialization object which keeps the parser alive through a shared pointer. This way the parser could be initialized on demand and the memory used by the parser could be freed between runs. For further performance improvements read this: http://xerces.apache.org/xerces2-j/faq-performance.html == Thread safety == Thread safety is achieved through thread-local storage, which was tested to work under C++ and Python. == Error Handling == All exceptions which could be thrown are caught within the serializing functions. There shouldn't be any uncaught exceptions because the bindings code doesn't handle that. If an error occurs a message is printed to the standard error output and a default constructed value is returned. Writing doesn't provide any validation (as it is hardly useful for the reason that it's anyways not possible to correct the mistake). For debugging purposes the document can be parsed again after writing. Validity is only ensured by typesafety, but range errors are easily possible. === The XSD based development checklist === -Don't forget to add an element for each attribute in the style off: Otherwise you won't get the serialization/deserialization code (or respectively just wrong code), which still compiles though and looks correct from the outside. -If you have modified the xsd's make sure to run "make clean && make" in the toplevel make directory, otherwise the schema is not recompiles => parsing errors -Make sure you add new .xsd to the compiled schemas, otherwise you'll get "no declaration found" errors. libkolabxml-1.1.2/src/base64.cpp000066400000000000000000000075711262531651400164110ustar00rootroot00000000000000/* base64.cpp and base64.h Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this source code must not be misrepresented; you must not claim that you wrote the original source code. If you use this source code in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original source code. 3. This notice may not be removed or altered from any source distribution. René Nyffenegger rene.nyffenegger@adp-gmbh.ch */ #include "base64.h" #include static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz" "0123456789+/"; static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); } std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) { std::string ret; int i = 0; int j = 0; unsigned char char_array_3[3]; unsigned char char_array_4[4]; while (in_len--) { char_array_3[i++] = *(bytes_to_encode++); if (i == 3) { char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = (unsigned char)(((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4)); char_array_4[2] = (unsigned char)(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6)); char_array_4[3] = char_array_3[2] & 0x3f; for(i = 0; (i <4) ; i++) ret += base64_chars[char_array_4[i]]; i = 0; } } if (i) { for(j = i; j < 3; j++) char_array_3[j] = '\0'; char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; char_array_4[1] = (unsigned char)(((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4)); char_array_4[2] = (unsigned char)(((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6)); char_array_4[3] = char_array_3[2] & 0x3f; for (j = 0; (j < i + 1); j++) ret += base64_chars[char_array_4[j]]; while((i++ < 3)) ret += '='; } return ret; } std::string base64_decode(std::string const& encoded_string) { std::string::size_type in_len = encoded_string.size(); int i = 0; int j = 0; int in_ = 0; unsigned char char_array_4[4], char_array_3[3]; std::string ret; while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) { char_array_4[i++] = encoded_string[in_]; in_++; if (i ==4) { for (i = 0; i <4; i++) char_array_4[i] = (unsigned char)(base64_chars.find(char_array_4[i])); char_array_3[0] = (unsigned char)((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4)); char_array_3[1] = (unsigned char)(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2)); char_array_3[2] = (unsigned char)(((char_array_4[2] & 0x3) << 6) + char_array_4[3]); for (i = 0; (i < 3); i++) ret += char_array_3[i]; i = 0; } } if (i) { for (j = i; j <4; j++) char_array_4[j] = 0; for (j = 0; j <4; j++) char_array_4[j] = (unsigned char)(base64_chars.find(char_array_4[j])); char_array_3[0] = (unsigned char)((char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4)); char_array_3[1] = (unsigned char)(((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2)); char_array_3[2] = (unsigned char)(((char_array_4[2] & 0x3) << 6) + char_array_4[3]); for (j = 0; (j < i - 1); j++) ret += char_array_3[j]; } return ret; } libkolabxml-1.1.2/src/base64.h000066400000000000000000000021671262531651400160520ustar00rootroot00000000000000/* base64.cpp and base64.h Copyright (C) 2004-2008 René Nyffenegger This source code is provided 'as-is', without any express or implied warranty. In no event will the author be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this source code must not be misrepresented; you must not claim that you wrote the original source code. If you use this source code in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original source code. 3. This notice may not be removed or altered from any source distribution. René Nyffenegger rene.nyffenegger@adp-gmbh.ch */ #include std::string base64_encode(unsigned char const* , unsigned int len); std::string base64_decode(std::string const& s); libkolabxml-1.1.2/src/containers/000077500000000000000000000000001262531651400167545ustar00rootroot00000000000000libkolabxml-1.1.2/src/containers/incidence_p.h000066400000000000000000000037001262531651400213650ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef INCIDENCE_P #define INCIDENCE_P #include "kolabcontainers.h" namespace Kolab { struct PrivateIncidence { PrivateIncidence() : sequence(0), classification(ClassPublic), thisAndFuture(false), priority(0), status(StatusUndefined){} std::string uid; cDateTime created; cDateTime lastModified; int sequence; Classification classification; std::vector< std::string > categories; std::vector< std::string > relatedTo; cDateTime start; cDateTime recurrenceID; bool thisAndFuture; std::string summary; std::string description; std::string comment; std::string location; int priority; Status status; RecurrenceRule rrule; std::vector< cDateTime > recurrenceDates; std::vector< cDateTime > exceptionDates; ContactReference organizer; Duration duration; std::vector attendees; std::vector attachments; std::vector customProperties; std::vector alarms; std::string url; }; } #endif libkolabxml-1.1.2/src/containers/kolabconfiguration.cpp000066400000000000000000000062771262531651400233540ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabconfiguration.h" namespace Kolab { struct Configuration::Private { Private(): type(Invalid){} std::vector categoryColor; Dictionary dictionary; SnippetsCollection snippets; Relation relation; FileDriver fileDriver; ConfigurationType type; std::string uid; cDateTime created; cDateTime lastModified; }; Configuration::Configuration() : d(new Configuration::Private) { } Configuration::Configuration(const std::vector &c) : d(new Configuration::Private) { d->categoryColor = c; d->type = TypeCategoryColor; } Configuration::Configuration(const Dictionary &dict) : d(new Configuration::Private) { d->dictionary = dict; d->type = TypeDictionary; } Configuration::Configuration(const SnippetsCollection &snippets) : d(new Configuration::Private) { d->snippets = snippets; d->type = TypeSnippet; } Configuration::Configuration(const Relation &relation) : d(new Configuration::Private) { d->relation = relation; d->type = TypeRelation; } Configuration::Configuration(const FileDriver &fileDriver) : d(new Configuration::Private) { d->fileDriver = fileDriver; d->type = TypeFileDriver; } Configuration::Configuration(const Configuration &other) : d(new Configuration::Private) { *d = *other.d; } Configuration::~Configuration() { } void Configuration::operator=(const Configuration &other) { *d = *other.d; } bool Configuration::isValid() const { return d->type != Invalid; } void Configuration::setUid(const std::string &uid) { d->uid = uid; } std::string Configuration::uid() const { return d->uid; } void Configuration::setCreated(const cDateTime &created) { d->created = created; } cDateTime Configuration::created() const { return d->created; } void Configuration::setLastModified(const cDateTime &lastModified) { d->lastModified = lastModified; } cDateTime Configuration::lastModified() const { return d->lastModified; } Configuration::ConfigurationType Configuration::type() const { return d->type; } std::vector Configuration::categoryColor() const { return d->categoryColor; } Dictionary Configuration::dictionary() const { return d->dictionary; } SnippetsCollection Configuration::snippets() const { return d->snippets; } Relation Configuration::relation() const { return d->relation; } FileDriver Configuration::fileDriver() const { return d->fileDriver; } } //Namespace libkolabxml-1.1.2/src/containers/kolabconfiguration.h000066400000000000000000000165221262531651400230130ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABCONFIGURATION_H #define KOLABCONFIGURATION_H #include #include #include #include "kolabcontainers.h" namespace Kolab { struct Dictionary { Dictionary(){} Dictionary(const std::string &c): mLanguage(c){} bool operator==(const Dictionary &other) const { return mLanguage == other.mLanguage && mEntries == other.mEntries; } std::string language() const { return mLanguage; } void setEntries(const std::vector &e){ mEntries = e; } std::vector entries() const { return mEntries; } private: std::string mLanguage; std::vector mEntries; }; struct CategoryColor { CategoryColor(){} CategoryColor(const std::string &c): mCategory(c) {} bool operator==(const CategoryColor &other) const { return mCategory == other.mCategory && mColor == other.mColor && mSubcategories == other.mSubcategories; } std::string category() const { return mCategory; } void setColor(const std::string &c) { mColor = c; } std::string color() const { return mColor; } void setSubcategories(const std::vector &c) { mSubcategories = c; } std::vector subcategories() const { return mSubcategories; } private: std::string mCategory; std::string mColor; std::vector mSubcategories; }; struct Snippet { enum TextType { Plain, HTML }; Snippet(): mTextType(Plain) {} Snippet(const std::string &name, const std::string &text): mName(name), mText(text), mTextType(Plain) {} bool operator==(const Snippet &other) const { return mName == other.mName && mText == other.mText && mTextType == other.mTextType && mShortcut == other.mShortcut; } std::string name() const { return mName; } std::string text() const { return mText; } void setTextType(TextType type) { mTextType = type; } TextType textType() const { return mTextType; } void setShortCut(const std::string &shortcut) { mShortcut = shortcut; } std::string shortCut() const { return mShortcut; } private: std::string mName; std::string mText; TextType mTextType; std::string mShortcut; }; struct SnippetsCollection { SnippetsCollection() {} SnippetsCollection(const std::string &name): mName(name) {} bool operator==(const SnippetsCollection &other) const { return mName == other.mName && mSnippets == other.mSnippets; } std::string name() const { return mName; } void setSnippets(const std::vector &snippets) { mSnippets = snippets; } std::vector snippets() const { return mSnippets; } private: std::string mName; std::vector mSnippets; }; struct Relation { Relation(){} Relation(const std::string &name, const std::string &type): mName(name), mType(type) {} bool operator==(const Relation &other) const { return mName == other.mName && mType == other.mType && mColor == other.mColor && mIconName == other.mIconName && mParent == other.mParent && mMembers == other.mMembers; } std::string name() const { return mName; } std::string type() const { return mType; } void setColor(const std::string &color) { mColor = color; } std::string color() const { return mColor; } void setIconName(const std::string &icon) { mIconName = icon; } std::string iconName() const { return mIconName; } void setParent(const std::string &parent) { mParent = parent; } std::string parent() const { return mParent; } void setPriority(int priority) { mPriority = priority; } int priority() const { return mPriority; } void setMembers(const std::vector &members) { mMembers = members; } std::vector members() const { return mMembers; } private: std::string mName; std::string mType; std::string mColor; std::string mIconName; std::string mParent; int mPriority; std::vector mMembers; }; struct FileDriver { FileDriver(): mEnabled(false) {} FileDriver(const std::string &driver, const std::string &title): mDriver(driver), mTitle(title), mEnabled(true) {} bool operator==(const FileDriver &other) const { return mDriver == other.mDriver && mTitle == other.mTitle && mEnabled == other.mEnabled && mHost == other.mHost && mPort == other.mPort && mUsername == other.mUsername && mPassword == other.mPassword; } void setDriver(const std::string &driver) { mDriver = driver; } std::string driver() const { return mDriver; } void setTitle(const std::string &title) { mTitle = title; } std::string title() const { return mTitle; } void setEnabled(bool enabled) { mEnabled = enabled; } bool enabled() const { return mEnabled; } void setHost(const std::string &host) { mHost = host; } std::string host() const { return mHost; } void setPort(int port) { mPort = port; } int port() const { return mPort; } void setUsername(const std::string &username) { mUsername = username; } std::string username() const { return mUsername; } void setPassword(const std::string &password) { mPassword = password; } std::string password() const { return mPassword; } private: std::string mDriver; std::string mTitle; bool mEnabled; std::string mHost; int mPort; std::string mUsername; std::string mPassword; }; class Configuration { public: Configuration(); Configuration(const std::vector &); Configuration(const Dictionary &); Configuration(const SnippetsCollection &); Configuration(const Relation &); Configuration(const FileDriver &); Configuration(const Configuration &); ~Configuration(); void operator=(const Configuration &); bool isValid() const; void setUid(const std::string &); std::string uid() const; void setCreated(const cDateTime &); cDateTime created() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; enum ConfigurationType { Invalid, TypeDictionary, TypeCategoryColor, TypeSnippet, TypeRelation, TypeFileDriver }; ConfigurationType type() const; std::vector categoryColor() const; Dictionary dictionary() const; SnippetsCollection snippets() const; Relation relation() const; FileDriver fileDriver() const; private: struct Private; boost::scoped_ptr d; }; } //Namespace #endif // KOLABCONFIGURATION_H libkolabxml-1.1.2/src/containers/kolabcontact.cpp000066400000000000000000000207271262531651400221340ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabcontact.h" namespace Kolab { struct DistList::Private { Private() {} std::string uid; cDateTime lastModified; std::vector< std::string > categories; std::string name; std::vector members; std::vector customProperties; }; DistList::DistList() : d(new DistList::Private()) { } DistList::DistList(const DistList &other) : d(new DistList::Private()) { *d = *other.d; } DistList::~DistList() { } void DistList::operator=(const Kolab::DistList &other) { *d = *other.d; } bool DistList::isValid() const { return !d->uid.empty(); } void DistList::setUid(const std::string &uid) { d->uid = uid; } std::string DistList::uid() const { return d->uid; } void DistList::setLastModified(const Kolab::cDateTime &dt) { d->lastModified = dt; } cDateTime DistList::lastModified() const { return d->lastModified; } void DistList::setName(const std::string &name) { d->name = name; } std::string DistList::name() const { return d->name; } void DistList::setMembers(const std::vector< ContactReference > &members) { d->members = members; } std::vector< ContactReference > DistList::members() const { return d->members; } void DistList::setCustomProperties(const std::vector< CustomProperty >& c) { d->customProperties = c; } std::vector< CustomProperty > DistList::customProperties() const { return d->customProperties; } struct Contact::Private { Private() : addressPreferredIndex(-1), gender(NotSet), telephonesPreferredIndex(-1), imAddressPreferredIndex(-1), emailAddressPreferredIndex(-1) {} std::string uid; cDateTime created; cDateTime lastModified; std::vector< std::string > categories; std::string name; NameComponents nameComponents; std::string note; std::string freeBusyUrl; std::vector< std::string > titles; std::vector affiliations; std::vector urls; std::vector
addresses; int addressPreferredIndex; std::vector nickNames; std::vector relateds; cDateTime bDay; cDateTime anniversary; std::string photo; std::string photoMimetype; Gender gender; std::vector languages; std::vector telephones; int telephonesPreferredIndex; std::vector imAddresses; int imAddressPreferredIndex; std::vector emailAddresses; int emailAddressPreferredIndex; std::vector gpsPos; std::vector keys; Crypto crypto; std::vector customProperties; }; Contact::Contact() : d(new Contact::Private()) { } Contact::Contact(const Contact &other) : d(new Contact::Private()) { *d = *other.d; } Contact::~Contact() { } void Contact::operator=(const Kolab::Contact &other) { *d = *other.d; } bool Contact::isValid() const { return !d->uid.empty(); } void Contact::setUid(const std::string &uid) { d->uid = uid; } std::string Contact::uid() const { return d->uid; } void Contact::setLastModified(const Kolab::cDateTime &dt) { d->lastModified = dt; } cDateTime Contact::lastModified() const { return d->lastModified; } void Contact::setCategories(const std::vector< std::string > &cat) { d->categories = cat; } void Contact::addCategory(const std::string &cat) { d->categories.push_back(cat); } std::vector< std::string > Contact::categories() const { return d->categories; } void Contact::setName(const std::string &name) { d->name = name; } std::string Contact::name() const { return d->name; } void Contact::setNameComponents(const Kolab::NameComponents &nc) { d->nameComponents = nc; } NameComponents Contact::nameComponents() const { return d->nameComponents; } void Contact::setNote(const std::string ¬e) { d->note = note; } std::string Contact::note() const { return d->note; } void Contact::setFreeBusyUrl(const std::string &url) { d->freeBusyUrl = url; } std::string Contact::freeBusyUrl() const { return d->freeBusyUrl; } void Contact::setTitles(const std::vector< std::string >& titles) { d->titles = titles; } std::vector< std::string > Contact::titles() const { return d->titles; } void Contact::setAffiliations(const std::vector< Affiliation > &a) { d->affiliations = a; } std::vector< Affiliation > Contact::affiliations() const { return d->affiliations; } void Contact::setUrls(const std::vector &urls) { d->urls = urls; } std::vector< Url > Contact::urls() const { return d->urls; } void Contact::setAddresses(const std::vector< Address > &ad, int preferred) { d->addresses = ad; d->addressPreferredIndex = preferred; } std::vector< Address > Contact::addresses() const { return d->addresses; } int Contact::addressPreferredIndex() const { return d->addressPreferredIndex; } void Contact::setNickNames(const std::vector< std::string > &n) { d->nickNames = n; } std::vector< std::string > Contact::nickNames() const { return d->nickNames; } void Contact::setRelateds(const std::vector< Related > &relateds) { d->relateds = relateds; } std::vector< Related > Contact::relateds() const { return d->relateds; } void Contact::setBDay(const Kolab::cDateTime &bday) { d->bDay = bday; } cDateTime Contact::bDay() const { return d->bDay; } void Contact::setAnniversary(const Kolab::cDateTime& dt) { d->anniversary = dt; } cDateTime Contact::anniversary() const { return d->anniversary; } void Contact::setPhoto(const std::string& data, const std::string& mimetype) { d->photo = data; d->photoMimetype = mimetype; } std::string Contact::photo() const { return d->photo; } std::string Contact::photoMimetype() const { return d->photoMimetype; } void Contact::setGender(Contact::Gender g) { d->gender = g; } Contact::Gender Contact::gender() const { return d->gender; } void Contact::setLanguages(const std::vector< std::string >& l) { d->languages = l; } std::vector< std::string > Contact::languages() const { return d->languages; } void Contact::setTelephones(const std::vector< Telephone >& tel, int preferredIndex) { d->telephonesPreferredIndex = preferredIndex; d->telephones = tel; } std::vector< Telephone > Contact::telephones() const { return d->telephones; } int Contact::telephonesPreferredIndex() const { return d->telephonesPreferredIndex; } void Contact::setIMaddresses(const std::vector< std::string > &adr, int preferredIndex) { d->imAddresses = adr; d->imAddressPreferredIndex = preferredIndex; } std::vector< std::string > Contact::imAddresses() const { return d->imAddresses; } int Contact::imAddressPreferredIndex() const { return d->imAddressPreferredIndex; } void Contact::setEmailAddresses(const std::vector< Email >& email, int preferredIndex) { d->emailAddresses = email; d->emailAddressPreferredIndex = preferredIndex; } std::vector< Email > Contact::emailAddresses() const { return d->emailAddresses; } int Contact::emailAddressPreferredIndex() const { return d->emailAddressPreferredIndex; } void Contact::setGPSpos(const std::vector< Geo >& pos) { d->gpsPos = pos; } std::vector< Geo > Contact::gpsPos() const { return d->gpsPos; } void Contact::setKeys(const std::vector &keys) { d->keys = keys; } std::vector Contact::keys() const { return d->keys; } void Contact::setCrypto(const Kolab::Crypto& c) { d->crypto = c; } Crypto Contact::crypto() const { return d->crypto; } void Contact::setCustomProperties(const std::vector< CustomProperty >& c) { d->customProperties = c; } std::vector< CustomProperty > Contact::customProperties() const { return d->customProperties; } } //Namespace libkolabxml-1.1.2/src/containers/kolabcontact.h000066400000000000000000000335731262531651400216040ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABCONTACT_H #define KOLABCONTACT_H #include #include #include #include "kolabcontainers.h" namespace Kolab { struct NameComponents { bool operator==(const NameComponents &other) const { return mSurnames == other.mSurnames && mGiven == other.mGiven && mAdditional == other.mAdditional && mPrefixes == other.mPrefixes && mSuffixes == other.mSuffixes; }; void setSurnames(const std::vector &s) { mSurnames = s; }; std::vector surnames() const { return mSurnames; }; void setGiven(const std::vector &s) { mGiven = s; }; std::vector given() const { return mGiven; }; void setAdditional(const std::vector &s) { mAdditional = s; }; std::vector additional() const { return mAdditional; }; void setPrefixes(const std::vector &s) { mPrefixes = s; }; std::vector prefixes() const { return mPrefixes; }; void setSuffixes(const std::vector &s) { mSuffixes = s; }; std::vector suffixes() const { return mSuffixes; }; bool isValid() const { return !(mSurnames.empty() && mGiven.empty() && mAdditional.empty() && mPrefixes.empty() && mSuffixes.empty()); }; private: std::vector mSurnames; std::vector mGiven; std::vector mAdditional; std::vector mPrefixes; std::vector mSuffixes; }; struct Related { enum DescriptionType { Invalid, Text, Uid }; Related(): mType(Invalid), mRelationType(NoRelation) {}; Related(DescriptionType t, const std::string &textOrUri, int relationType = NoRelation) : mType(t), mRelationType(relationType) { if (t == Text) { mText = textOrUri; } else { mUri = textOrUri; } }; bool operator==(const Related &other) const { return mType == other.mType && mUri == other.mUri && mText == other.mText && mRelationType == other.mRelationType; }; DescriptionType type() const { return mType; }; std::string uri() const { return mUri; }; std::string text() const { return mText; }; enum RelationType { NoRelation = 0, Child = 0x01, Spouse = 0x02, Manager = 0x04, Assistant = 0x08, }; void setRelationTypes(int t) { mRelationType = t; }; int relationTypes() const { return mRelationType; }; private: DescriptionType mType; std::string mUri; std::string mText; int mRelationType; }; struct Address { Address(): mTypes(0) {}; enum Type { Work = 0x01, Home = 0x02 }; bool operator==(const Address &other) const { return mTypes == other.mTypes && mLabel == other.mLabel && mStreet == other.mStreet && mLocality == other.mLocality && mRegion == other.mRegion && mCode == other.mCode && mCountry == other.mCountry; }; void setTypes(int t) { mTypes = t; }; int types() const { return mTypes; }; void setLabel(const std::string &s) { mLabel = s; }; std::string label() const { return mLabel; } void setStreet(const std::string &s) { mStreet = s; }; std::string street() const { return mStreet; }; void setLocality(const std::string &s) { mLocality = s; }; std::string locality() const { return mLocality; }; void setRegion(const std::string &s) { mRegion = s; }; std::string region() const { return mRegion; }; void setCode(const std::string &s) { mCode = s; }; std::string code() const { return mCode; }; void setCountry(const std::string &s) { mCountry = s; }; std::string country() const { return mCountry; }; private: int mTypes; std::string mLabel; std::string mStreet; std::string mLocality; std::string mRegion; std::string mCode; std::string mCountry; }; struct Affiliation { bool operator==(const Affiliation &other) const { return mOrg == other.mOrg && mOrgUnits == other.mOrgUnits && mLogo == other.mLogo && mLogoMimetype == other.mLogoMimetype && mRoles == other.mRoles && mRelateds == other.mRelateds && mOffices == other.mOffices; }; void setOrganisation(const std::string &org) { mOrg = org; }; std::string organisation() const { return mOrg; }; void setOrganisationalUnits(const std::vector &units) { mOrgUnits = units; }; std::vector organisationalUnits() const { return mOrgUnits; }; void setLogo(const std::string &l, const std::string mimetype) { mLogo = l; mLogoMimetype = mimetype; }; std::string logo() const { return mLogo; }; std::string logoMimetype() const { return mLogoMimetype; }; void setRoles(const std::vector &roles) { mRoles = roles; }; std::vector roles() const { return mRoles; }; void setRelateds(const std::vector &relateds) { mRelateds = relateds; }; std::vector relateds() const { return mRelateds; }; void setAddresses(const std::vector
&offices) { mOffices = offices; }; std::vector
addresses() const { return mOffices; }; private: std::string mOrg; std::vector mOrgUnits; std::string mLogo; std::string mLogoMimetype; std::vector mRoles; std::vector mRelateds; std::vector
mOffices; }; struct Telephone { enum Type { Work = 0x01, Home = 0x02, Text = 0x04, Voice = 0x08, Fax = 0x10, Cell = 0x20, Video = 0x40, Pager = 0x80, Textphone = 0x100, Car = 0x200 }; Telephone(): mType(0){}; bool operator==(const Telephone &other) const { return mNumber == other.mNumber && mType == other.mType; }; void setTypes(int t) { mType = t; }; int types() const { return mType; }; void setNumber(const std::string &n) { mNumber = n; }; std::string number() const { return mNumber; }; private: std::string mNumber; int mType; }; struct Email { enum Type { NoType = 0, Work = 0x01, Home = 0x02 }; Email(): mType(NoType){}; Email(const std::string &a, int t = NoType): mAddress(a), mType(t) {}; bool operator==(const Email &other) const { return mAddress == other.mAddress && mType == other.mType; }; void setTypes(int t) { mType = t; }; int types() const { return mType; }; void setAddress(const std::string &n) { mAddress = n; }; std::string address() const { return mAddress; }; private: std::string mAddress; int mType; }; struct Crypto { enum CryptoTypes { PGPinline = 0x01, PGPmime = 0x02, SMIME = 0x04, SMIMEopaque = 0x08 }; enum CryptoPref { Ask, Never, Always, IfPossible }; Crypto(): mCryptoTypes(0), mSignPref(Ask), mEncryptPref(Ask){}; bool operator==(const Crypto &other) const { return mCryptoTypes == other.mCryptoTypes && mSignPref == other.mSignPref && mEncryptPref == other.mEncryptPref; }; bool isValid() const { return mCryptoTypes; }; void setAllowed(int cryptoTypes) { mCryptoTypes = cryptoTypes; }; int allowed() const { return mCryptoTypes; }; void setSignPref(CryptoPref p) { mSignPref = p; }; CryptoPref signPref() const { return mSignPref; }; void setEncryptPref(CryptoPref p) { mEncryptPref = p; }; CryptoPref encryptPref() const { return mEncryptPref; }; private: int mCryptoTypes; CryptoPref mSignPref; CryptoPref mEncryptPref; }; struct Geo { Geo(): latitude(0.0), longitude(0.0) {}; Geo(double lat, double lon) : latitude(lat), longitude(lon) {}; bool operator==(const Geo &other) const{ return (longitude == other.longitude && latitude == other.latitude);}; double latitude; double longitude; }; struct Url { enum UrlTypes { NoType = 0, Blog }; Url(): mType(NoType) {}; Url(const std::string &u, int t = NoType): mUrl(u), mType(t) {}; bool operator==(const Url &other) const{ return (mType == other.mType && mUrl == other.mUrl);}; int type() const { return mType; }; std::string url() const { return mUrl; }; private: std::string mUrl; int mType; }; struct Key { enum KeyType { Invalid, PGP, PKCS7_MIME }; Key(): keytype(Invalid) {}; Key(const std::string &k, KeyType type) : mKey(k), keytype(type) {}; bool operator==(const Key &other) const{ return (mKey == other.mKey && keytype == other.keytype);}; KeyType type() const { return keytype; }; std::string key() const { return mKey; }; private: std::string mKey; KeyType keytype; }; class DistList { public: DistList(); ~DistList(); DistList(const DistList &); void operator=(const DistList &); bool isValid() const; void setUid(const std::string &); std::string uid() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setName(const std::string &); std::string name() const; void setMembers(const std::vector &); std::vector members() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; private: struct Private; boost::scoped_ptr d; }; class Contact { public: Contact(); ~Contact(); Contact(const Contact &); void operator=(const Contact &); bool isValid() const; void setUid(const std::string &); std::string uid() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setCategories(const std::vector &); void addCategory(const std::string &); std::vector categories() const; void setName(const std::string &); std::string name() const; void setNameComponents(const NameComponents &); NameComponents nameComponents() const; void setNote(const std::string &); std::string note() const; void setFreeBusyUrl(const std::string &); std::string freeBusyUrl() const; void setTitles(const std::vector &titles); std::vector titles() const; void setAffiliations(const std::vector &); std::vector affiliations() const; void setUrls(const std::vector &); std::vector urls() const; void setAddresses(const std::vector
&, int preferred = -1); std::vector
addresses() const; int addressPreferredIndex() const; void setNickNames(const std::vector< std::string > &); std::vector< std::string > nickNames() const; void setRelateds(const std::vector &); std::vector relateds() const; void setBDay(const cDateTime &); cDateTime bDay() const; void setAnniversary(const cDateTime &); cDateTime anniversary() const; void setPhoto(const std::string &data, const std::string &mimetype); std::string photo() const; std::string photoMimetype() const; enum Gender { NotSet, NotSpecified, Male, Female }; void setGender(Gender); Gender gender() const; void setLanguages(const std::vector &); std::vector languages() const; void setTelephones(const std::vector &, int preferredIndex = -1); std::vector telephones() const; int telephonesPreferredIndex() const; void setIMaddresses(const std::vector &, int preferredIndex = -1); std::vector imAddresses() const; int imAddressPreferredIndex() const; void setEmailAddresses(const std::vector &, int preferredIndex = -1); std::vector emailAddresses() const; int emailAddressPreferredIndex() const; void setGPSpos(const std::vector &); std::vector gpsPos() const; void setKeys(const std::vector &); std::vector keys() const; void setCrypto(const Crypto &); Crypto crypto() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; private: struct Private; boost::scoped_ptr d; }; } //Namespace #endif // KOLABCONTACT_H libkolabxml-1.1.2/src/containers/kolabcontainers.cpp000066400000000000000000000326271262531651400226500ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabcontainers.h" #include "incidence_p.h" namespace Kolab { struct cDateTime::Private { Private() : year(-1), month(-1), day(-1), hour(-1), minute(-1), second(-1), isUtc(false){} int year; int month; int day; int hour; int minute; int second; bool isUtc; std::string timezone; }; cDateTime::cDateTime() : d(new cDateTime::Private()) { } cDateTime::cDateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc) : d(new cDateTime::Private()) { d->year = year; d->month = month; d->day = day; d->hour = hour; d->minute = minute; d->second = second; d->isUtc = isUtc; } cDateTime::cDateTime(const std::string& timezone, int year, int month, int day, int hour, int minute, int second) : d(new cDateTime::Private()) { d->year = year; d->month = month; d->day = day; d->hour = hour; d->minute = minute; d->second = second; d->timezone = timezone; } cDateTime::cDateTime(int year, int month, int day) : d(new cDateTime::Private()) { d->year = year; d->month = month; d->day = day; } cDateTime::cDateTime(const Kolab::cDateTime &other) : d(new cDateTime::Private()) { *d = *other.d; } cDateTime::~cDateTime() { } void cDateTime::operator=(const Kolab::cDateTime &other) { *d = *other.d; } bool cDateTime::operator==(const Kolab::cDateTime &other) const { if ( d->year == other.year() && d->month == other.month() && d->day == other.day() && d->hour == other.hour() && d->minute == other.minute() && d->second== other.second() && d->isUtc== other.isUTC() && d->timezone== other.timezone()) { return true; } return false; } int cDateTime::year() const { return d->year; } int cDateTime::month() const { return d->month; } int cDateTime::day() const { return d->day; } int cDateTime::hour() const { return d->hour; } int cDateTime::minute() const { return d->minute; } int cDateTime::second() const { return d->second; } bool cDateTime::isDateOnly() const { if ((d->hour < 0) && (d->minute < 0) && (d->second < 0)) { return true; } return false; } void cDateTime::setDate(int year, int month, int day) { d->year = year; d->month = month; d->day = day; } void cDateTime::setTime(int hour, int minute, int second) { d->hour = hour; d->minute = minute; d->second = second; } void cDateTime::setTimezone(const std::string &tz) { d->timezone = tz; } void cDateTime::setUTC(bool utc) { d->isUtc = utc; } bool cDateTime::isUTC() const { return d->isUtc; } std::string cDateTime::timezone() const { return d->timezone; } bool cDateTime::isValid() const { return (d->year >= 0 && d->month >= 0 && d->day >= 0); } struct RecurrenceRule::Private { Private() : freq(FreqNone), weekstart(Monday), count(-1), interval(1){}; Frequency freq; Weekday weekstart; cDateTime end; int count; int interval; std::vector bysecond; std::vector byminute; std::vector byhour; std::vector byday; std::vector bymonthday; std::vector byyearday; std::vector byweekno; std::vector bymonth; }; RecurrenceRule::RecurrenceRule() : d(new RecurrenceRule::Private) { } RecurrenceRule::RecurrenceRule(const Kolab::RecurrenceRule &other) : d(new RecurrenceRule::Private) { *d = *other.d; } void RecurrenceRule::operator=(const Kolab::RecurrenceRule &other) { *d = *other.d; } bool RecurrenceRule::operator==(const Kolab::RecurrenceRule &other) const { if ( d->freq == other.frequency() && d->weekstart == other.weekStart() && d->end == other.end() && d->count == other.count() && d->interval == other.interval() && d->bysecond == other.bysecond() && d->byminute == other.byminute() && d->byhour == other.byhour() && d->byday == other.byday() && d->bymonthday == other.bymonthday() && d->byyearday == other.byyearday() && d->byweekno == other.byweekno() && d->bymonth == other.bymonth()) { return true; } return false; } RecurrenceRule::~RecurrenceRule() { } void RecurrenceRule::setFrequency(RecurrenceRule::Frequency freq) { d->freq = freq; } RecurrenceRule::Frequency RecurrenceRule::frequency() const { return d->freq; } void RecurrenceRule::setWeekStart(Kolab::Weekday weekstart) { d->weekstart = weekstart; } Kolab::Weekday RecurrenceRule::weekStart() const { return d->weekstart; } void RecurrenceRule::setEnd(const Kolab::cDateTime &end) { d->end = end; } cDateTime RecurrenceRule::end() const { return d->end; } void RecurrenceRule::setCount(int count) { d->count = count; } int RecurrenceRule::count() const { return d->count; } void RecurrenceRule::setInterval(int interval) { d->interval = interval; } int RecurrenceRule::interval() const { return d->interval; } void RecurrenceRule::setBysecond(const std::vector< int >&by) { d->bysecond = by; } std::vector< int > RecurrenceRule::bysecond() const { return d->bysecond; } void RecurrenceRule::setByminute(const std::vector< int > &by) { d->byminute = by; } std::vector< int > RecurrenceRule::byminute() const { return d->byminute; } void RecurrenceRule::setByhour(const std::vector< int > &by) { d->byhour = by; } std::vector< int > RecurrenceRule::byhour() const { return d->byhour; } void RecurrenceRule::setByday(const std::vector< DayPos > &by) { d->byday = by; } std::vector< DayPos > RecurrenceRule::byday() const { return d->byday; } void RecurrenceRule::setBymonthday(const std::vector< int > &by) { d->bymonthday = by; } std::vector< int > RecurrenceRule::bymonthday() const { return d->bymonthday; } void RecurrenceRule::setByyearday(const std::vector< int > &by) { d->byyearday = by; } std::vector< int > RecurrenceRule::byyearday() const { return d->byyearday; } void RecurrenceRule::setByweekno(const std::vector< int > &by) { d->byweekno = by; } std::vector< int > RecurrenceRule::byweekno() const { return d->byweekno; } void RecurrenceRule::setBymonth(const std::vector< int > &by) { d->bymonth = by; } std::vector< int > RecurrenceRule::bymonth() const { return d->bymonth; } bool RecurrenceRule::isValid() const { if (d->freq == FreqNone) { return false; } return true; } struct Attendee::Private { Private() : partStat(PartNeedsAction), role(Required), rsvp(false), cutype(CutypeIndividual) {}; ContactReference contact; PartStatus partStat; Role role; bool rsvp; std::vector delegatedTo; std::vector delegatedFrom; Cutype cutype; }; Attendee::Attendee() : d(new Attendee::Private) { } Attendee::Attendee(const ContactReference& contact) : d(new Attendee::Private) { d->contact = contact; } Attendee::Attendee(const Kolab::Attendee &other) : d(new Attendee::Private) { *d = *other.d; } void Attendee::operator=(const Kolab::Attendee &other) { *d = *other.d; } Attendee::~Attendee() { } bool Attendee::operator==(const Kolab::Attendee &other) const { if ( d->contact == other.contact() && d->partStat == other.partStat() && d->role == other.role() && d->rsvp == other.rsvp() && d->delegatedTo == other.delegatedTo() && d->delegatedFrom == other.delegatedFrom() && d->cutype == other.cutype() ) { return true; } return false; } bool Attendee::isValid() const { return d->contact.isValid(); }; void Attendee::setContact(const ContactReference &c) { d->contact = c; } ContactReference Attendee::contact() const { return d->contact; } void Attendee::setPartStat(PartStatus partStat) { d->partStat = partStat; } PartStatus Attendee::partStat() const { return d->partStat; } void Attendee::setRole(Role role) { d->role = role; } Role Attendee::role() const { return d->role; } void Attendee::setRSVP(bool rsvp) { d->rsvp = rsvp; } bool Attendee::rsvp() const { return d->rsvp; } void Attendee::setDelegatedTo(const std::vector< ContactReference > &del) { d->delegatedTo = del; } std::vector< ContactReference > Attendee::delegatedTo() const { return d->delegatedTo; } void Attendee::setDelegatedFrom(const std::vector< ContactReference > &del) { d->delegatedFrom = del; } std::vector< ContactReference > Attendee::delegatedFrom() const { return d->delegatedFrom; } void Attendee::setCutype(Cutype type) { d->cutype = type; } Cutype Attendee::cutype() const { return d->cutype; } struct Attachment::Private { std::string uri; std::string data; std::string mimetype; std::string label; bool isValid; }; Attachment::Attachment() : d(new Attachment::Private) { d->isValid = false; } Attachment::Attachment(const Kolab::Attachment &other) : d(new Attachment::Private) { *d = *other.d; } void Attachment::operator=(const Kolab::Attachment &other) { *d = *other.d; } Attachment::~Attachment() { } bool Attachment::operator==(const Kolab::Attachment &other) const { return ( d->uri == other.uri() && d->data == other.data() && d->label == other.label() && d->mimetype == other.mimetype() ); } void Attachment::setUri(const std::string &uri, const std::string& mimetype) { d->isValid = true; d->uri = uri; d->mimetype = mimetype; } std::string Attachment::uri() const { return d->uri; } std::string Attachment::mimetype() const { return d->mimetype; } void Attachment::setLabel(const std::string &label) { d->label = label; } std::string Attachment::label() const { return d->label; } void Attachment::setData(const std::string &data, const std::string& mimetype) { d->isValid = true; d->data = data; d->mimetype = mimetype; } std::string Attachment::data() const { return d->data; } bool Attachment::isValid() const { return d->isValid; } struct Alarm::Private { Private(): relativeTo(Start), numrepeat(0), type(Alarm::InvalidAlarm) {}; std::string text; Attachment audioFile; std::string summary; std::vector attendees; cDateTime start; Duration relativeDuration; Relative relativeTo; Duration duration; int numrepeat; Type type; }; Alarm::Alarm() : d(new Alarm::Private) { } Alarm::Alarm(const std::string &text) : d(new Alarm::Private) { d->text = text; d->type = DisplayAlarm; } Alarm::Alarm(const Kolab::Attachment& audio) : d(new Alarm::Private) { d->audioFile = audio; d->type = AudioAlarm; } Alarm::Alarm(const std::string& summary, const std::string& description, const std::vector attendees) : d(new Alarm::Private) { d->summary = summary; d->text = description; d->attendees = attendees; d->type = EMailAlarm; } Alarm::Alarm(const Kolab::Alarm &other) : d(new Alarm::Private) { *d = *other.d; } void Alarm::operator=(const Kolab::Alarm &other) { *d = *other.d; } Alarm::~Alarm() { } bool Alarm::operator==(const Kolab::Alarm &other) const { return ( d->text == other.description() && d->text == other.description() && d->audioFile == other.audioFile() && d->summary == other.summary() && d->attendees == other.attendees() && d->start == other.start() && d->relativeDuration == other.relativeStart() && d->relativeTo == other.relativeTo() && d->duration == other.duration() && d->numrepeat == other.numrepeat() ); } std::string Alarm::text() const { return d->text; } Attachment Alarm::audioFile() const { return d->audioFile; } std::string Alarm::summary() const { return d->summary; } std::string Alarm::description() const { return d->text; } std::vector Alarm::attendees() const { return d->attendees; } void Alarm::setStart(const Kolab::cDateTime &start) { d->start = start; } cDateTime Alarm::start() const { return d->start; } void Alarm::setRelativeStart(const Kolab::Duration &duration, Relative relativeTo) { d->relativeDuration = duration; d->relativeTo = relativeTo; } Duration Alarm::relativeStart() const { return d->relativeDuration; } Relative Alarm::relativeTo() const { return d->relativeTo; } void Alarm::setDuration(const Kolab::Duration &duration, int numrepeat) { d->numrepeat = numrepeat; d->duration = duration; } Duration Alarm::duration() const { return d->duration; } int Alarm::numrepeat() const { return d->numrepeat; } Alarm::Type Alarm::type() const { return d->type; } }//Namespace libkolabxml-1.1.2/src/containers/kolabcontainers.h000066400000000000000000000263601262531651400223120ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLAB_CONTAINERS_H #define KOLAB_CONTAINERS_H #include #include #include namespace Kolab { /** * - months: 1-12 * - days: 1-31 * - hour: 0-23 * - minute: 0-59 * - second: 0-59 */ class cDateTime { public: cDateTime(); cDateTime(int year, int month, int day, int hour, int minute, int second, bool isUtc=false); cDateTime(const std::string &timezone, int year, int month, int day, int hour, int minute, int second); cDateTime(int year, int month, int day); ~cDateTime(); cDateTime(const cDateTime &); void operator=(const cDateTime &); bool operator==(const cDateTime &) const; void setDate(int year, int month, int day); int year() const; int month() const; int day() const; bool isDateOnly() const; void setTime(int hour, int minute, int second); int hour() const; int minute() const; int second() const; void setUTC(bool); bool isUTC() const; void setTimezone(const std::string &); std::string timezone() const; bool isValid() const; private: struct Private; boost::scoped_ptr d; }; enum Classification { ClassPublic, ClassPrivate, ClassConfidential }; enum Status { StatusUndefined, StatusNeedsAction, StatusCompleted, StatusInProcess, StatusCancelled, StatusTentative, StatusConfirmed, StatusDraft, StatusFinal }; enum Weekday { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday }; struct DayPos { DayPos(): mIsValid(false){}; DayPos(int occurrence, Weekday weekday): mOccurrence(occurrence), mWeekday(weekday), mIsValid(true){}; bool operator==(const DayPos &other) const { return mOccurrence == other.mOccurrence && mWeekday == other.mWeekday; }; int occurence() const { return mOccurrence; }; Weekday weekday() const { return mWeekday; }; bool isValid() { return mIsValid; }; private: int mOccurrence; Weekday mWeekday; bool mIsValid; }; class Attachment { public: Attachment(); Attachment(const Kolab::Attachment &); ~Attachment(); void operator=(const Attachment &); bool operator==(const Attachment &) const; void setUri(const std::string &uri, const std::string &mimetype); std::string uri() const; ///Un-encoded binary content, Implies embedded, will be encoded void setData(const std::string &, const std::string &mimetype); ///Decoded binary content. std::string data() const; //TODO add possibility to set already encoded data and uri to be embedded as performance/convenience improvement? // ///Base64 encoded binary content, Implies embedded // void setEncodedData(const std::string &, const std::string &mimetype); std::string mimetype() const; ///User visible label void setLabel(const std::string &); std::string label() const; bool isValid() const; private: struct Private; boost::scoped_ptr d; }; enum Relative { Start, End }; struct Duration { Duration():mWeeks(0), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(false), valid(false){}; Duration(int weeks, bool negative = false): mWeeks(weeks), mDays(0), mHours(0), mMinutes(0), mSeconds(0), mNegative(negative), valid(true){}; Duration(int days, int hours, int minutes, int seconds, bool negative = false): mWeeks(0), mDays(days), mHours(hours), mMinutes(minutes), mSeconds(seconds), mNegative(negative), valid(true){}; bool operator==(const Duration &other) const{ return (/*mWeeks == other.mWeeks && mDays == other.mDays && mHours == other.mHours && mMinutes == other.mMinutes && mSeconds == other.mSeconds && mNegative == other.mNegative &&*/ ( ((((mWeeks * 7 + mDays) * 24 + mHours) * 60 + mMinutes) * 60 + mSeconds) == ((((other.mWeeks * 7 + other.mDays) * 24 + other.mHours) * 60 + other.mMinutes) * 60 + other.mSeconds) ) && valid == other.valid );}; int weeks() const { return mWeeks; }; int days() const { return mDays; }; int hours() const { return mHours; }; int minutes() const { return mMinutes; }; int seconds() const { return mSeconds; }; bool isNegative() const { return mNegative; }; bool isValid() const { return valid; }; private: int mWeeks; int mDays; int mHours; int mMinutes; int mSeconds; bool mNegative; bool valid; }; struct ContactReference { enum ReferenceType { Invalid, EmailReference, UidReference, EmailAndUidReference }; ContactReference(): mType(Invalid) {}; ///For xCal ContactReference(const std::string &email, const std::string &name = std::string(), const std::string &uid = std::string()): mType(EmailAndUidReference), mEmail(email), mUid(uid), mName(name) {}; ///For xCard ContactReference(ReferenceType type, const std::string &emailOrUID, const std::string &name = std::string()): mType(type), mName(name) { if (type == EmailReference) { mEmail = emailOrUID; } else { mUid = emailOrUID; } }; bool operator==(const ContactReference &other) const { return mEmail == other.mEmail && mName == other.mName && mUid == other.mUid; }; bool isValid() const { return mType != Invalid; }; void setName(const std::string &name) { mName = name; }; std::string email() const { return mEmail; }; std::string uid() const { return mUid; }; std::string name() const { return mName; }; ReferenceType type() const { return mType; }; private: ReferenceType mType; std::string mEmail; std::string mUid; std::string mName; }; class Alarm { public: enum Type { InvalidAlarm, EMailAlarm, DisplayAlarm, AudioAlarm }; Alarm(); Alarm(const Alarm &); ~Alarm(); void operator=(const Alarm &); bool operator==(const Alarm &other) const; ///EMail Alarm, @param attendees accepts only email + name and no uid Alarm(const std::string &summary, const std::string &description, const std::vector attendees); std::string summary() const; std::string description() const; std::vector attendees() const; ///Display Alarm Alarm(const std::string &text); std::string text() const; ///Audio Alarm Alarm(const Attachment &audio); Attachment audioFile() const; void setRelativeStart(const Duration &, Relative); Duration relativeStart() const; Relative relativeTo() const; void setStart(const cDateTime &); cDateTime start() const; void setDuration(const Duration &, int numrepeat); Duration duration() const; int numrepeat() const; Type type() const; private: struct Private; boost::scoped_ptr d; }; class RecurrenceRule { public: RecurrenceRule(); RecurrenceRule(const RecurrenceRule &); ~RecurrenceRule(); void operator=(const RecurrenceRule &); bool operator==(const RecurrenceRule &other) const; enum Frequency { FreqNone, Yearly, Monthly, Weekly, Daily, Hourly, Minutely, Secondly }; void setFrequency(Frequency); Frequency frequency() const; void setWeekStart(Weekday); Weekday weekStart() const; void setEnd(const cDateTime &); cDateTime end() const; void setCount(int count); int count() const; void setInterval(int); int interval() const; void setBysecond(const std::vector &); std::vector bysecond() const; void setByminute(const std::vector &); std::vector byminute() const; void setByhour(const std::vector &); std::vector byhour() const; void setByday(const std::vector &); std::vector byday() const; void setBymonthday(const std::vector &); std::vector bymonthday() const; void setByyearday(const std::vector &); std::vector byyearday() const; void setByweekno(const std::vector &); std::vector byweekno() const; void setBymonth(const std::vector &); std::vector bymonth() const; bool isValid() const; private: struct Private; boost::scoped_ptr d; }; enum PartStatus { PartNeedsAction, PartAccepted, PartDeclined, PartTentative, PartDelegated, PartInProcess, PartCompleted }; enum Role { Required, Chair, Optional, NonParticipant }; enum Cutype { CutypeUnknown, CutypeGroup, CutypeIndividual, CutypeResource, CutypeRoom }; class Attendee { public: Attendee(); Attendee(const ContactReference &contact); Attendee(const Attendee &); ~Attendee(); void operator=(const Attendee &); bool operator==(const Attendee &) const; bool isValid() const; void setContact(const ContactReference &); ContactReference contact() const; void setPartStat(PartStatus); PartStatus partStat() const; void setRole(Role); Role role() const; void setRSVP(bool); bool rsvp() const; void setDelegatedTo(const std::vector &); std::vector delegatedTo() const; void setDelegatedFrom(const std::vector &); std::vector delegatedFrom() const; void setCutype(Cutype); Cutype cutype() const; private: struct Private; boost::scoped_ptr d; }; struct CustomProperty { CustomProperty(){}; CustomProperty(const std::string &i, const std::string &v) : identifier(i), value(v) {}; bool operator==(const CustomProperty &other) const{ return (identifier == other.identifier && value == other.value);}; std::string identifier; std::string value; }; //WARNING this function copies the vector and does not modify it template std::vector operator<< ( std::vector v, const T &s) { v.push_back(s); return v; } } #endif libkolabxml-1.1.2/src/containers/kolabevent.cpp000066400000000000000000000134341262531651400216170ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabevent.h" #include "kolabevent_p.h" namespace Kolab { Event::Event() : d(new Event::Private()) { // std::cout << "ctor" << std::endl; } Event::Event(const Event &other) : d(new Event::Private()) { *d = *other.d; // std::cout << "cctor" << std::endl; } Event::~Event() { // std::cout << "dtor" << std::endl; } void Event::operator=(const Kolab::Event &other) { *d = *other.d; } bool Event::isValid() const { return !d->uid.empty(); } void Event::setUid(const std::string &uid) { d->uid = uid; } std::string Event::uid() const { return d->uid; } void Event::setCreated(const Kolab::cDateTime &created) { d->created = created; } cDateTime Event::created() const { return d->created; } void Event::setLastModified(const Kolab::cDateTime &lastMod) { d->lastModified = lastMod; } cDateTime Event::lastModified() const { return d->lastModified; } void Event::setSequence(int sequence) { d->sequence = sequence; } int Event::sequence() const { return d->sequence; } void Event::setClassification(Classification class_) { d->classification = class_; } Classification Event::classification() const { return d->classification; } void Event::setCategories(const std::vector< std::string > &categories) { d->categories = categories; } void Event::addCategory(const std::string &cat) { d->categories.push_back(cat); } std::vector< std::string > Event::categories() const { return d->categories; } void Event::setStart(const Kolab::cDateTime &start) { d->start = start; } cDateTime Event::start() const { return d->start; } void Event::setEnd(const Kolab::cDateTime &end) { d->end = end; } cDateTime Event::end() const { return d->end; } void Event::setDuration(const Duration &duration) { d->duration = duration; } Duration Event::duration() const { return d->duration; } void Event::setRecurrenceID(const Kolab::cDateTime &rID, bool thisandfuture) { d->recurrenceID = rID; d->thisAndFuture = thisandfuture; } cDateTime Event::recurrenceID() const { return d->recurrenceID; } bool Event::thisAndFuture() const { return d->thisAndFuture; } void Event::setSummary(const std::string &summary) { d->summary = summary; } std::string Event::summary() const { return d->summary; } void Event::setDescription(const std::string &description) { d->description = description; } std::string Event::description() const { return d->description; } void Event::setComment(const std::string &comment) { d->comment = comment; } std::string Event::comment() const { return d->comment; } void Event::setPriority(int priority) { d->priority = priority; } int Event::priority() const { return d->priority; } void Event::setStatus(Status status) { d->status = status; } Status Event::status() const { return d->status; } void Event::setLocation(const std::string &location) { d->location = location; } std::string Event::location() const { return d->location; } void Event::setRecurrenceRule(const Kolab::RecurrenceRule &rrule) { d->rrule = rrule; } RecurrenceRule Event::recurrenceRule() const { return d->rrule; } void Event::setRecurrenceDates(const std::vector< cDateTime > &dates) { d->recurrenceDates = dates; } void Event::addRecurrenceDate(const Kolab::cDateTime &dt) { d->recurrenceDates.push_back(dt); } std::vector< cDateTime > Event::recurrenceDates() const { return d->recurrenceDates; } void Event::setExceptionDates(const std::vector< cDateTime > &dates) { d->exceptionDates = dates; } void Event::addExceptionDate(const Kolab::cDateTime &dt) { d->exceptionDates.push_back(dt); } std::vector< cDateTime > Event::exceptionDates() const { return d->exceptionDates; } void Event::setTransparency(bool isTransparent) { d->isTransparent = isTransparent; } bool Event::transparency() const { return d->isTransparent; } void Event::setOrganizer(const ContactReference &organizer) { d->organizer = organizer; } ContactReference Event::organizer() const { return d->organizer; } void Event::setAttendees(const std::vector< Attendee > &attendees) { d->attendees = attendees; } std::vector< Attendee > Event::attendees() const { return d->attendees; } void Event::setAttachments(const std::vector< Attachment > &attach) { d->attachments = attach; } std::vector< Attachment > Event::attachments() const { return d->attachments; } void Event::setUrl(const std::string &url) { d->url = url; } std::string Event::url() const { return d->url; } void Event::setCustomProperties(const std::vector< CustomProperty > &prop) { d->customProperties = prop; } std::vector< CustomProperty > Event::customProperties() const { return d->customProperties; } void Event::setExceptions(const std::vector< Event > &exceptions) { d->exceptions = exceptions; } std::vector< Event > Event::exceptions() const { return d->exceptions; } void Event::setAlarms(const std::vector< Alarm > &alarms) { d->alarms = alarms; } std::vector< Alarm > Event::alarms() const { return d->alarms; } } libkolabxml-1.1.2/src/containers/kolabevent.h000066400000000000000000000071371262531651400212670ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLAB_EVENT_H #define KOLAB_EVENT_H #include #include #include #include "kolabcontainers.h" namespace Kolab { class Event { public: Event(); ~Event(); Event(const Event &); void operator=(const Event &); bool isValid() const; void setUid(const std::string &); std::string uid() const; void setCreated(const cDateTime &); cDateTime created() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setSequence(int); int sequence() const; void setClassification(Classification); Classification classification() const; void setCategories(const std::vector &); void addCategory(const std::string &); std::vector categories() const; void setStart(const cDateTime &); cDateTime start() const; void setEnd(const cDateTime &); cDateTime end() const; void setDuration(const Duration &); Duration duration() const; void setTransparency(bool isTransparent); bool transparency() const; void setRecurrenceRule(const RecurrenceRule &); RecurrenceRule recurrenceRule() const; void setRecurrenceDates(const std::vector &); void addRecurrenceDate(const cDateTime &); std::vector recurrenceDates() const; void setExceptionDates(const std::vector &); void addExceptionDate(const cDateTime &); std::vector exceptionDates() const; void setRecurrenceID(const cDateTime &, bool thisandfuture); cDateTime recurrenceID() const; bool thisAndFuture() const; void setSummary(const std::string &); std::string summary() const; void setDescription(const std::string &); std::string description() const; void setComment(const std::string &); std::string comment() const; void setPriority(int); int priority() const; void setStatus(Status); Status status() const; void setLocation(const std::string &); std::string location() const; void setOrganizer(const ContactReference &); ContactReference organizer() const; void setAttendees(const std::vector &); std::vector attendees() const; void setAttachments(const std::vector &); std::vector attachments() const; void setUrl(const std::string &); std::string url() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; void setExceptions(const std::vector &); std::vector exceptions() const; void setAlarms(const std::vector &); std::vector alarms() const; protected: struct Private; boost::scoped_ptr d; }; } #endif libkolabxml-1.1.2/src/containers/kolabevent_p.h000066400000000000000000000021261262531651400215770ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABEVENT_P #define KOLABEVENT_P #include "kolabcontainers.h" #include "incidence_p.h" namespace Kolab { class Event; struct Event::Private: public PrivateIncidence { Private() : PrivateIncidence(), isTransparent(false){} cDateTime end; bool isTransparent; Duration duration; std::vector< Event > exceptions; }; } #endif libkolabxml-1.1.2/src/containers/kolabfile.cpp000066400000000000000000000061251262531651400214140ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabfile.h" namespace Kolab { struct File::Private { Private() : classification(ClassPublic){} std::string uid; cDateTime created; cDateTime lastModified; std::vector< std::string > categories; Classification classification; std::string note; Attachment attachment; std::vector customProperties; }; File::File() : d(new File::Private()) { } File::File(const File &other) : d(new File::Private()) { *d = *other.d; } File::~File() { } void File::operator=(const Kolab::File &other) { *d = *other.d; } bool File::operator==(const Kolab::File& other) const { return ( d->uid == other.uid() && d->created == other.created() && d->lastModified == other.lastModified() && d->categories == other.categories() && d->classification == other.classification() && d->note == other.note() && d->attachment == other.file() && d->customProperties == other.customProperties()); } bool File::isValid() const { return !d->uid.empty(); } void File::setUid(const std::string &uid) { d->uid = uid; } std::string File::uid() const { return d->uid; } void File::setCreated(const Kolab::cDateTime &created) { d->created = created; } cDateTime File::created() const { return d->created; } void File::setLastModified(const Kolab::cDateTime &lastMod) { d->lastModified = lastMod; } cDateTime File::lastModified() const { return d->lastModified; } void File::setClassification(Classification class_) { d->classification = class_; } Classification File::classification() const { return d->classification; } void File::setCategories(const std::vector< std::string > &categories) { d->categories = categories; } void File::addCategory(const std::string &cat) { d->categories.push_back(cat); } std::vector< std::string > File::categories() const { return d->categories; } void File::setNote(const std::string ¬e) { d->note = note; } std::string File::note() const { return d->note; } void File::setFile(const Attachment &attach) { d->attachment = attach; } Attachment File::file() const { return d->attachment; } void File::setCustomProperties(const std::vector< CustomProperty > &prop) { d->customProperties = prop; } std::vector< CustomProperty > File::customProperties() const { return d->customProperties; } } //File libkolabxml-1.1.2/src/containers/kolabfile.h000066400000000000000000000040261262531651400210570ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABFILE_H #define KOLABFILE_H #include #include #include #include "kolabcontainers.h" namespace Kolab { class File { public: File(); ~File(); File(const File &); void operator=(const File &); bool operator==(const File &) const; bool isValid() const; void setUid(const std::string &); std::string uid() const; void setCreated(const cDateTime &); cDateTime created() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setClassification(Classification); Classification classification() const; void setCategories(const std::vector &); void addCategory(const std::string &); std::vector categories() const; void setNote(const std::string &); std::string note() const; void setFile(const Attachment &); Attachment file() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; private: struct Private; boost::scoped_ptr d; }; } #endif libkolabxml-1.1.2/src/containers/kolabfreebusy.cpp000066400000000000000000000070351262531651400223220ustar00rootroot00000000000000/* Copyright (C) 2012 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "kolabfreebusy.h" #include "kolabfreebusy_p.h" namespace Kolab { FreebusyPeriod::FreebusyPeriod() : d(new FreebusyPeriod::Private()) { } FreebusyPeriod::FreebusyPeriod(const FreebusyPeriod &other) : d(new FreebusyPeriod::Private()) { *d = *other.d; } void FreebusyPeriod::operator=(const FreebusyPeriod &other) { *d = *other.d; } FreebusyPeriod::~FreebusyPeriod() { } bool FreebusyPeriod::operator==(const FreebusyPeriod &other) const { return d->type == other.type() && d->eventUid == other.eventUid() && d->eventSummary == other.eventSummary() && d->eventLocation == other.eventLocation() && d->periods == other.periods(); } bool FreebusyPeriod::isValid() const { return d->type == Invalid; } void FreebusyPeriod::setType(FBType t) { d->type = t; } FreebusyPeriod::FBType FreebusyPeriod::type() const { return d->type; } void FreebusyPeriod::setPeriods(const std::vector< Period > &periods) { d->periods = periods; } std::vector< Period > FreebusyPeriod::periods() const { return d->periods; } void FreebusyPeriod::setEvent(const std::string& uid, const std::string& summary, const std::string& location) { d->eventUid = uid; d->eventSummary = summary; d->eventLocation = location; } std::string FreebusyPeriod::eventUid() const { return d->eventUid; } std::string FreebusyPeriod::eventSummary() const { return d->eventSummary; } std::string FreebusyPeriod::eventLocation() const { return d->eventLocation; } Freebusy::Freebusy() : d(new Freebusy::Private()) { } Freebusy::Freebusy(const Freebusy &other) : d(new Freebusy::Private()) { *d = *other.d; } Freebusy::~Freebusy() { } void Freebusy::operator=(const Freebusy &other) { *d = *other.d; } bool Freebusy::isValid() const { return !d->uid.empty(); } void Freebusy::setUid(const std::string &uid) { d->uid = uid; } std::string Freebusy::uid() const { return d->uid; } void Freebusy::setTimestamp(const cDateTime &t) { d->timestamp = t; } cDateTime Freebusy::timestamp() const { return d->timestamp; } void Freebusy::setStart(const cDateTime &s) { d->start = s; } cDateTime Freebusy::start() const { return d->start; } void Freebusy::setEnd(const cDateTime &e) { d->end = e; } cDateTime Freebusy::end() const { return d->end; } void Freebusy::setOrganizer(const ContactReference &c) { d->organizer = c; } ContactReference Freebusy::organizer() const { return d->organizer; } void Freebusy::setPeriods(const std::vector< FreebusyPeriod > &periods) { d->periods = periods; } std::vector< FreebusyPeriod > Freebusy::periods() const { return d->periods; } }libkolabxml-1.1.2/src/containers/kolabfreebusy.h000066400000000000000000000053111262531651400217620ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABFREEBUSY_H #define KOLABFREEBUSY_H #include #include #include #include "kolabcontainers.h" namespace Kolab { struct Period { Period(){}; Period(const cDateTime& s, const cDateTime &e): start(s), end(e){}; bool operator==(const Period &other) const { return start == other.start && end == other.end; }; bool isValid() const { return start.isValid() && end.isValid(); }; cDateTime start; cDateTime end; }; class FreebusyPeriod { public: FreebusyPeriod(); ~FreebusyPeriod(); FreebusyPeriod(const FreebusyPeriod &); void operator=(const FreebusyPeriod &); bool operator==(const FreebusyPeriod &) const; bool isValid() const; enum FBType { Invalid, Busy, Tentative, OutOfOffice }; void setType(FBType t); FBType type() const; void setEvent(const std::string &uid, const std::string &summary, const std::string &location); std::string eventUid() const; std::string eventSummary() const; std::string eventLocation() const; void setPeriods(const std::vector &); std::vector periods() const; private: struct Private; boost::scoped_ptr d; }; class Freebusy { public: Freebusy(); ~Freebusy(); Freebusy(const Freebusy &); void operator=(const Freebusy &); // bool operator==(const Freebusy &) const; bool isValid() const; void setUid(const std::string &); std::string uid() const; void setTimestamp(const cDateTime &); cDateTime timestamp() const; void setStart(const cDateTime &); cDateTime start() const; void setEnd(const cDateTime &); cDateTime end() const; void setOrganizer(const ContactReference &); ContactReference organizer() const; void setPeriods(const std::vector &); std::vector periods() const; private: struct Private; boost::scoped_ptr d; }; } #endif libkolabxml-1.1.2/src/containers/kolabfreebusy_p.h000066400000000000000000000024431262531651400223040ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef FREEBUSY_P #define FREEBUSY_P #include "kolabcontainers.h" #include "kolabfreebusy.h" namespace Kolab { struct FreebusyPeriod::Private { Private() : type(Invalid) {} FBType type; std::string eventUid; std::string eventSummary; std::string eventLocation; std::vector< Period > periods; }; class Freebusy; struct Freebusy::Private { Private() {} std::string uid; cDateTime timestamp; cDateTime start; cDateTime end; ContactReference organizer; std::vector< FreebusyPeriod > periods; }; } #endif libkolabxml-1.1.2/src/containers/kolabjournal.cpp000066400000000000000000000070241262531651400221460ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabjournal.h" #include "incidence_p.h" namespace Kolab { struct Journal::Private: public PrivateIncidence { Private() : PrivateIncidence() {} }; Journal::Journal() : d(new Journal::Private()) { } Journal::Journal(const Journal &other) : d(new Journal::Private()) { *d = *other.d; } Journal::~Journal() { } void Journal::operator=(const Kolab::Journal &other) { *d = *other.d; } bool Journal::isValid() const { return !d->uid.empty(); } void Journal::setUid(const std::string &uid) { d->uid = uid; } std::string Journal::uid() const { return d->uid; } void Journal::setCreated(const Kolab::cDateTime &created) { d->created = created; } cDateTime Journal::created() const { return d->created; } void Journal::setLastModified(const Kolab::cDateTime &lastMod) { d->lastModified = lastMod; } cDateTime Journal::lastModified() const { return d->lastModified; } void Journal::setSequence(int sequence) { d->sequence = sequence; } int Journal::sequence() const { return d->sequence; } void Journal::setClassification(Classification class_) { d->classification = class_; } Classification Journal::classification() const { return d->classification; } void Journal::setCategories(const std::vector< std::string > &categories) { d->categories = categories; } void Journal::addCategory(const std::string &cat) { d->categories.push_back(cat); } std::vector< std::string > Journal::categories() const { return d->categories; } void Journal::setStart(const Kolab::cDateTime &start) { d->start = start; } cDateTime Journal::start() const { return d->start; } void Journal::setSummary(const std::string &summary) { d->summary = summary; } std::string Journal::summary() const { return d->summary; } void Journal::setDescription(const std::string &description) { d->description = description; } std::string Journal::description() const { return d->description; } void Journal::setComment(const std::string &comment) { d->comment = comment; } std::string Journal::comment() const { return d->comment; } void Journal::setStatus(Status status) { d->status = status; } Status Journal::status() const { return d->status; } void Journal::setAttendees(const std::vector< Attendee > &attendees) { d->attendees = attendees; } std::vector< Attendee > Journal::attendees() const { return d->attendees; } void Journal::setAttachments(const std::vector< Attachment > &attach) { d->attachments = attach; } std::vector< Attachment > Journal::attachments() const { return d->attachments; } void Journal::setCustomProperties(const std::vector< CustomProperty > &prop) { d->customProperties = prop; } std::vector< CustomProperty > Journal::customProperties() const { return d->customProperties; } }//Namespace libkolabxml-1.1.2/src/containers/kolabjournal.h000066400000000000000000000045731262531651400216210ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABJOURNAL_H #define KOLABJOURNAL_H #include #include #include #include "kolabcontainers.h" namespace Kolab { class Journal { public: Journal(); ~Journal(); Journal(const Journal &); void operator=(const Journal &); bool isValid() const; void setUid(const std::string &); std::string uid() const; void setCreated(const cDateTime &); cDateTime created() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setSequence(int); int sequence() const; void setClassification(Classification); Classification classification() const; void setCategories(const std::vector &); void addCategory(const std::string &); std::vector categories() const; void setStart(const cDateTime &); cDateTime start() const; void setSummary(const std::string &); std::string summary() const; void setDescription(const std::string &); std::string description() const; void setComment(const std::string &); std::string comment() const; void setStatus(Status); Status status() const; //TODO Contacts void setAttendees(const std::vector &); std::vector attendees() const; void setAttachments(const std::vector &); std::vector attachments() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; private: struct Private; boost::scoped_ptr d; }; } #endif libkolabxml-1.1.2/src/containers/kolabnote.cpp000066400000000000000000000071401262531651400214400ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabnote.h" namespace Kolab { struct Note::Private { Private() : classification(ClassPublic){} std::string uid; cDateTime created; cDateTime lastModified; std::vector< std::string > categories; Classification classification; std::string summary; std::string description; std::string color; std::vector attachments; std::vector customProperties; }; Note::Note() : d(new Note::Private()) { } Note::Note(const Note &other) : d(new Note::Private()) { *d = *other.d; } Note::~Note() { } void Note::operator=(const Kolab::Note &other) { *d = *other.d; } bool Note::operator==(const Kolab::Note& other) const { return ( d->uid == other.uid() && d->created == other.created() && d->lastModified == other.lastModified() && d->categories == other.categories() && d->classification == other.classification() && d->summary == other.summary() && d->description == other.description() && d->color == other.color() && d->attachments == other.attachments() && d->customProperties == other.customProperties()); } bool Note::isValid() const { return !d->uid.empty(); } void Note::setUid(const std::string &uid) { d->uid = uid; } std::string Note::uid() const { return d->uid; } void Note::setCreated(const Kolab::cDateTime &created) { d->created = created; } cDateTime Note::created() const { return d->created; } void Note::setLastModified(const Kolab::cDateTime &lastMod) { d->lastModified = lastMod; } cDateTime Note::lastModified() const { return d->lastModified; } void Note::setClassification(Classification class_) { d->classification = class_; } Classification Note::classification() const { return d->classification; } void Note::setCategories(const std::vector< std::string > &categories) { d->categories = categories; } void Note::addCategory(const std::string &cat) { d->categories.push_back(cat); } std::vector< std::string > Note::categories() const { return d->categories; } void Note::setSummary(const std::string &summary) { d->summary = summary; } std::string Note::summary() const { return d->summary; } void Note::setDescription(const std::string &description) { d->description = description; } std::string Note::description() const { return d->description; } void Note::setColor(const std::string &color) { d->color = color; } std::string Note::color() const { return d->color; } void Note::setAttachments(const std::vector< Attachment > &attach) { d->attachments = attach; } std::vector< Attachment > Note::attachments() const { return d->attachments; } void Note::setCustomProperties(const std::vector< CustomProperty > &prop) { d->customProperties = prop; } std::vector< CustomProperty > Note::customProperties() const { return d->customProperties; } } //Note libkolabxml-1.1.2/src/containers/kolabnote.h000066400000000000000000000044001262531651400211010ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABNOTE_H #define KOLABNOTE_H #include #include #include #include "kolabcontainers.h" namespace Kolab { class Note { public: Note(); ~Note(); Note(const Note &); void operator=(const Note &); bool operator==(const Note &) const; bool isValid() const; void setUid(const std::string &); std::string uid() const; void setCreated(const cDateTime &); cDateTime created() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setClassification(Classification); Classification classification() const; void setCategories(const std::vector &); void addCategory(const std::string &); std::vector categories() const; void setSummary(const std::string &); std::string summary() const; void setDescription(const std::string &); std::string description() const; void setColor(const std::string &); std::string color() const; void setAttachments(const std::vector &); std::vector attachments() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; private: struct Private; boost::scoped_ptr d; }; } #endif libkolabxml-1.1.2/src/containers/kolabtodo.cpp000066400000000000000000000136651262531651400214510ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabtodo.h" #include "incidence_p.h" namespace Kolab { struct Todo::Private: public PrivateIncidence { Private() : PrivateIncidence(), percentComplete(0){} cDateTime due; int percentComplete; std::vector< Todo > exceptions; }; Todo::Todo() : d(new Todo::Private()) { } Todo::Todo(const Todo &other) : d(new Todo::Private()) { *d = *other.d; } Todo::~Todo() { } void Todo::operator=(const Kolab::Todo &other) { *d = *other.d; } bool Todo::isValid() const { return !d->uid.empty(); } void Todo::setUid(const std::string &uid) { d->uid = uid; } std::string Todo::uid() const { return d->uid; } void Todo::setCreated(const Kolab::cDateTime &created) { d->created = created; } cDateTime Todo::created() const { return d->created; } void Todo::setLastModified(const Kolab::cDateTime &lastMod) { d->lastModified = lastMod; } cDateTime Todo::lastModified() const { return d->lastModified; } void Todo::setSequence(int sequence) { d->sequence = sequence; } int Todo::sequence() const { return d->sequence; } void Todo::setClassification(Classification class_) { d->classification = class_; } Classification Todo::classification() const { return d->classification; } void Todo::setCategories(const std::vector< std::string > &categories) { d->categories = categories; } void Todo::addCategory(const std::string &cat) { d->categories.push_back(cat); } std::vector< std::string > Todo::categories() const { return d->categories; } void Todo::setRelatedTo(const std::vector< std::string > &related) { d->relatedTo = related; } void Todo::addRelatedTo(const std::string &related) { d->relatedTo.push_back(related); } std::vector< std::string > Todo::relatedTo() const { return d->relatedTo; } void Todo::setStart(const Kolab::cDateTime &start) { d->start = start; } cDateTime Todo::start() const { return d->start; } void Todo::setDue(const Kolab::cDateTime &due) { d->due = due; } cDateTime Todo::due() const { return d->due; } void Todo::setRecurrenceID(const Kolab::cDateTime &rID, bool thisandfuture) { d->recurrenceID = rID; d->thisAndFuture = thisandfuture; } cDateTime Todo::recurrenceID() const { return d->recurrenceID; } bool Todo::thisAndFuture() const { return d->thisAndFuture; } void Todo::setSummary(const std::string &summary) { d->summary = summary; } std::string Todo::summary() const { return d->summary; } void Todo::setDescription(const std::string &description) { d->description = description; } std::string Todo::description() const { return d->description; } void Todo::setComment(const std::string &comment) { d->comment = comment; } std::string Todo::comment() const { return d->comment; } void Todo::setPriority(int priority) { d->priority = priority; } int Todo::priority() const { return d->priority; } void Todo::setStatus(Status status) { d->status = status; } Status Todo::status() const { return d->status; } void Todo::setPercentComplete(int complete) { d->percentComplete = complete; } int Todo::percentComplete() const { return d->percentComplete; } void Todo::setLocation(const std::string &location) { d->location = location; } std::string Todo::location() const { return d->location; } void Todo::setRecurrenceRule(const Kolab::RecurrenceRule &rrule) { d->rrule = rrule; } RecurrenceRule Todo::recurrenceRule() const { return d->rrule; } void Todo::setRecurrenceDates(const std::vector< cDateTime > &dates) { d->recurrenceDates = dates; } void Todo::addRecurrenceDate(const Kolab::cDateTime &dt) { d->recurrenceDates.push_back(dt); } std::vector< cDateTime > Todo::recurrenceDates() const { return d->recurrenceDates; } void Todo::setExceptionDates(const std::vector< cDateTime > &dates) { d->exceptionDates = dates; } void Todo::addExceptionDate(const Kolab::cDateTime &dt) { d->exceptionDates.push_back(dt); } std::vector< cDateTime > Todo::exceptionDates() const { return d->exceptionDates; } void Todo::setOrganizer(const ContactReference &organizer) { d->organizer = organizer; } ContactReference Todo::organizer() const { return d->organizer; } void Todo::setAttendees(const std::vector< Attendee > &attendees) { d->attendees = attendees; } std::vector< Attendee > Todo::attendees() const { return d->attendees; } void Todo::setAttachments(const std::vector< Attachment > &attach) { d->attachments = attach; } std::vector< Attachment > Todo::attachments() const { return d->attachments; } void Todo::setUrl(const std::string &url) { d->url = url; } std::string Todo::url() const { return d->url; } void Todo::setCustomProperties(const std::vector< CustomProperty > &prop) { d->customProperties = prop; } std::vector< CustomProperty > Todo::customProperties() const { return d->customProperties; } void Todo::setExceptions(const std::vector< Todo > &exceptions) { d->exceptions = exceptions; } std::vector< Todo > Todo::exceptions() const { return d->exceptions; } void Todo::setAlarms(const std::vector< Alarm > &alarms) { d->alarms = alarms; } std::vector< Alarm > Todo::alarms() const { return d->alarms; } } libkolabxml-1.1.2/src/containers/kolabtodo.h000066400000000000000000000072271262531651400211130ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLAB_TODO_H #define KOLAB_TODO_H #include #include #include #include "kolabcontainers.h" namespace Kolab { class Todo { public: Todo(); ~Todo(); Todo(const Todo &); void operator=(const Todo &); bool isValid() const; void setUid(const std::string &); std::string uid() const; void setCreated(const cDateTime &); cDateTime created() const; void setLastModified(const cDateTime &); cDateTime lastModified() const; void setSequence(int); int sequence() const; void setClassification(Classification); Classification classification() const; void setCategories(const std::vector &); void addCategory(const std::string &); std::vector categories() const; void setRelatedTo(const std::vector &); void addRelatedTo(const std::string &); std::vector relatedTo() const; void setStart(const cDateTime &); cDateTime start() const; void setDue(const cDateTime &); cDateTime due() const; void setRecurrenceRule(const RecurrenceRule &); RecurrenceRule recurrenceRule() const; void setRecurrenceDates(const std::vector &); void addRecurrenceDate(const cDateTime &); std::vector recurrenceDates() const; void setExceptionDates(const std::vector &); void addExceptionDate(const cDateTime &); std::vector exceptionDates() const; void setRecurrenceID(const cDateTime &, bool thisandfuture); cDateTime recurrenceID() const; bool thisAndFuture() const; void setSummary(const std::string &); std::string summary() const; void setDescription(const std::string &); std::string description() const; void setComment(const std::string &); std::string comment() const; void setPriority(int); int priority() const; void setStatus(Status); Status status() const; void setPercentComplete(int); int percentComplete() const; void setLocation(const std::string &); std::string location() const; void setOrganizer(const ContactReference &); ContactReference organizer() const; void setAttendees(const std::vector &); std::vector attendees() const; void setAttachments(const std::vector &); std::vector attachments() const; void setUrl(const std::string &); std::string url() const; void setCustomProperties(const std::vector &); std::vector customProperties() const; void setExceptions(const std::vector &); std::vector exceptions() const; void setAlarms(const std::vector &); std::vector alarms() const; private: struct Private; boost::scoped_ptr d; }; } #endif libkolabxml-1.1.2/src/csharp/000077500000000000000000000000001262531651400160675ustar00rootroot00000000000000libkolabxml-1.1.2/src/csharp/CMakeLists.txt000066400000000000000000000133621262531651400206340ustar00rootroot00000000000000# Generate C# wrapper include_directories(../) # Compile CSHARP Bindings find_program(GMCS NAMES gmcs HINTS /usr/bin/) if (NOT GMCS) message("gmcs not found, not building csharp bindings") return() endif() set(KOLAB_SWIG_CSHARP_SOURCE_FILE ${CMAKE_CURRENT_BINARY_DIR}/csharp_kolabformat_wrapper.cpp) #it seems we never use this file? it works at least as a dependecy. set(KOLAB_SWIG_CSHARP_FILES ${CMAKE_CURRENT_BINARY_DIR}/Address.cs ${CMAKE_CURRENT_BINARY_DIR}/Affiliation.cs ${CMAKE_CURRENT_BINARY_DIR}/Alarm.cs ${CMAKE_CURRENT_BINARY_DIR}/Attachment.cs ${CMAKE_CURRENT_BINARY_DIR}/Attendee.cs ${CMAKE_CURRENT_BINARY_DIR}/CategoryColor.cs ${CMAKE_CURRENT_BINARY_DIR}/cDateTime.cs ${CMAKE_CURRENT_BINARY_DIR}/Classification.cs ${CMAKE_CURRENT_BINARY_DIR}/Configuration.cs ${CMAKE_CURRENT_BINARY_DIR}/Contact.cs ${CMAKE_CURRENT_BINARY_DIR}/ContactReference.cs ${CMAKE_CURRENT_BINARY_DIR}/Crypto.cs ${CMAKE_CURRENT_BINARY_DIR}/CustomProperty.cs ${CMAKE_CURRENT_BINARY_DIR}/Cutype.cs ${CMAKE_CURRENT_BINARY_DIR}/DayPos.cs ${CMAKE_CURRENT_BINARY_DIR}/Dictionary.cs ${CMAKE_CURRENT_BINARY_DIR}/DistList.cs ${CMAKE_CURRENT_BINARY_DIR}/Duration.cs ${CMAKE_CURRENT_BINARY_DIR}/ErrorSeverity.cs ${CMAKE_CURRENT_BINARY_DIR}/Email.cs ${CMAKE_CURRENT_BINARY_DIR}/Event.cs ${CMAKE_CURRENT_BINARY_DIR}/File.cs ${CMAKE_CURRENT_BINARY_DIR}/FileDriver.cs ${CMAKE_CURRENT_BINARY_DIR}/Freebusy.cs ${CMAKE_CURRENT_BINARY_DIR}/FreebusyPeriod.cs ${CMAKE_CURRENT_BINARY_DIR}/Geo.cs ${CMAKE_CURRENT_BINARY_DIR}/Journal.cs ${CMAKE_CURRENT_BINARY_DIR}/Key.cs ${CMAKE_CURRENT_BINARY_DIR}/kolabformatPINVOKE.cs ${CMAKE_CURRENT_BINARY_DIR}/NameComponents.cs ${CMAKE_CURRENT_BINARY_DIR}/Note.cs ${CMAKE_CURRENT_BINARY_DIR}/PartStatus.cs ${CMAKE_CURRENT_BINARY_DIR}/Period.cs ${CMAKE_CURRENT_BINARY_DIR}/RecurrenceRule.cs ${CMAKE_CURRENT_BINARY_DIR}/Related.cs ${CMAKE_CURRENT_BINARY_DIR}/Relation.cs ${CMAKE_CURRENT_BINARY_DIR}/Relative.cs ${CMAKE_CURRENT_BINARY_DIR}/Role.cs ${CMAKE_CURRENT_BINARY_DIR}/Snippet.cs ${CMAKE_CURRENT_BINARY_DIR}/SnippetsCollection.cs ${CMAKE_CURRENT_BINARY_DIR}/Status.cs ${CMAKE_CURRENT_BINARY_DIR}/Telephone.cs ${CMAKE_CURRENT_BINARY_DIR}/Todo.cs ${CMAKE_CURRENT_BINARY_DIR}/Url.cs ${CMAKE_CURRENT_BINARY_DIR}/vectoraddress.cs ${CMAKE_CURRENT_BINARY_DIR}/vectoraffiliation.cs ${CMAKE_CURRENT_BINARY_DIR}/vectoralarm.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorattachment.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorattendee.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorcategorycolor.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorcontactref.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorcs.cs ${CMAKE_CURRENT_BINARY_DIR}/vectordatetime.cs ${CMAKE_CURRENT_BINARY_DIR}/vectordaypos.cs ${CMAKE_CURRENT_BINARY_DIR}/vectoremail.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorevent.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorfreebusyperiod.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorgeo.cs ${CMAKE_CURRENT_BINARY_DIR}/vectori.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorkey.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorperiod.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorrelated.cs ${CMAKE_CURRENT_BINARY_DIR}/vectors.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorsnippet.cs ${CMAKE_CURRENT_BINARY_DIR}/vectortelephone.cs ${CMAKE_CURRENT_BINARY_DIR}/vectortodo.cs ${CMAKE_CURRENT_BINARY_DIR}/vectorurl.cs ${CMAKE_CURRENT_BINARY_DIR}/Weekday.cs ) set(KOLAB_SWIG_CSHARP_DLL_FILE ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.dll) set(KOLAB_SWIG_CSHARP_TEST_FILE ${CMAKE_CURRENT_BINARY_DIR}/test.exe) add_custom_command(OUTPUT ${KOLAB_SWIG_CSHARP_SOURCE_FILE} ${KOLAB_SWIG_CSHARP_FILES} COMMAND ${SWIG} -v -c++ -csharp -o ${KOLAB_SWIG_CSHARP_SOURCE_FILE} ../kolabformat.i COMMENT "Generating C# bindings" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ../kolabformat.i kolabxml VERBATIM ) SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_CSHARP_SOURCE_FILE} PROPERTIES GENERATED 1) SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_CSHARP_FILES} PROPERTIES GENERATED 1) configure_file(test.cs ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) add_custom_command(OUTPUT ${KOLAB_SWIG_CSHARP_DLL_FILE} COMMAND ${GMCS} -target:library "${CMAKE_CURRENT_BINARY_DIR}/kolabformat.cs" ${KOLAB_SWIG_CSHARP_FILES} COMMENT "Compiling C# library" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS kolabxml ${KOLAB_SWIG_CSHARP_SOURCE_FILE} ${KOLAB_SWIG_CSHARP_FILES} VERBATIM ) add_custom_command(OUTPUT ${KOLAB_SWIG_CSHARP_TEST_FILE} COMMAND ${GMCS} -reference:${KOLAB_SWIG_CSHARP_DLL_FILE} ${CMAKE_CURRENT_BINARY_DIR}/test.cs COMMENT "Compiling C# test.exe" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} DEPENDS kolabxml ${KOLAB_SWIG_CSHARP_SOURCE_FILE} ${KOLAB_SWIG_CSHARP_DLL_FILE} VERBATIM ) SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_CSHARP_DLL_FILE} PROPERTIES GENERATED 1) SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_CSHARP_TEST_FILE} PROPERTIES GENERATED 1) ADD_CUSTOM_TARGET(generate_csharp_bindings ALL DEPENDS ${KOLAB_SWIG_CSHARP_DLL_FILE} ${KOLAB_SWIG_CSHARP_TEST_FILE}) set(CSHARP_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/csharpbindings" CACHE STRING "Install directory for csharp bindings.") #not sure about the LIBRARY here, but might work install(FILES ${KOLAB_SWIG_CSHARP_DLL_FILE} DESTINATION ${CSHARP_INSTALL_DIR}) install(FILES ${KOLAB_SWIG_CSHARP_TEST_FILE} DESTINATION ${CSHARP_INSTALL_DIR}) libkolabxml-1.1.2/src/csharp/test.cs000066400000000000000000000004471262531651400174020ustar00rootroot00000000000000using System; class MyEvent { static void Main() { Event myEvent = new Event(); ContactReference myContactReference = new ContactReference("john.doe@example.org"); myContactReference.setName("John Doe"); myEvent.setOrganizer(myContactReference); } } libkolabxml-1.1.2/src/global_definitions.h000066400000000000000000000023371262531651400206200ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLAB_GLOBAL_DEFINITIONS_H #define KOLAB_GLOBAL_DEFINITIONS_H namespace Kolab { enum ErrorSeverity { NoError, Warning, //Warning, error could be corrected, object can be used without dataloss Error, //Potentially corrupt object, writing the object back could result in dataloss. (Object could still be used to display the data readonly). Critical //Ciritcal error, produced object cannot be used and should be thrown away (writing back will result in dataloss). }; } #endif libkolabxml-1.1.2/src/java/000077500000000000000000000000001262531651400155305ustar00rootroot00000000000000libkolabxml-1.1.2/src/java/CMakeLists.txt000066400000000000000000000106261262531651400202750ustar00rootroot00000000000000# Generate Java wrapper include_directories(../) set(KOLAB_SWIG_JAVA_SOURCE_FILE java_kolabformat_wrapper.cpp) set(KOLAB_SWIG_JAVA_FILES ${CMAKE_CURRENT_BINARY_DIR}/Address.java ${CMAKE_CURRENT_BINARY_DIR}/Affiliation.java ${CMAKE_CURRENT_BINARY_DIR}/Alarm.java ${CMAKE_CURRENT_BINARY_DIR}/Attachment.java ${CMAKE_CURRENT_BINARY_DIR}/Attendee.java ${CMAKE_CURRENT_BINARY_DIR}/CategoryColor.java ${CMAKE_CURRENT_BINARY_DIR}/cDateTime.java ${CMAKE_CURRENT_BINARY_DIR}/Classification.java ${CMAKE_CURRENT_BINARY_DIR}/Configuration.java ${CMAKE_CURRENT_BINARY_DIR}/Contact.java ${CMAKE_CURRENT_BINARY_DIR}/ContactReference.java ${CMAKE_CURRENT_BINARY_DIR}/Crypto.java ${CMAKE_CURRENT_BINARY_DIR}/CustomProperty.java ${CMAKE_CURRENT_BINARY_DIR}/Cutype.java ${CMAKE_CURRENT_BINARY_DIR}/DayPos.java ${CMAKE_CURRENT_BINARY_DIR}/Dictionary.java ${CMAKE_CURRENT_BINARY_DIR}/DistList.java ${CMAKE_CURRENT_BINARY_DIR}/Duration.java ${CMAKE_CURRENT_BINARY_DIR}/ErrorSeverity.java ${CMAKE_CURRENT_BINARY_DIR}/Event.java ${CMAKE_CURRENT_BINARY_DIR}/File.java ${CMAKE_CURRENT_BINARY_DIR}/FileDriver.java ${CMAKE_CURRENT_BINARY_DIR}/Freebusy.java ${CMAKE_CURRENT_BINARY_DIR}/FreebusyPeriod.java ${CMAKE_CURRENT_BINARY_DIR}/Geo.java ${CMAKE_CURRENT_BINARY_DIR}/Journal.java ${CMAKE_CURRENT_BINARY_DIR}/Key.java ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.java ${CMAKE_CURRENT_BINARY_DIR}/kolabformatJNI.java ${CMAKE_CURRENT_BINARY_DIR}/Makefile ${CMAKE_CURRENT_BINARY_DIR}/NameComponents.java ${CMAKE_CURRENT_BINARY_DIR}/Note.java ${CMAKE_CURRENT_BINARY_DIR}/PartStatus.java ${CMAKE_CURRENT_BINARY_DIR}/Period.java ${CMAKE_CURRENT_BINARY_DIR}/RecurrenceRule.java ${CMAKE_CURRENT_BINARY_DIR}/Relation.java ${CMAKE_CURRENT_BINARY_DIR}/Related.java ${CMAKE_CURRENT_BINARY_DIR}/Relative.java ${CMAKE_CURRENT_BINARY_DIR}/Role.java ${CMAKE_CURRENT_BINARY_DIR}/Status.java ${CMAKE_CURRENT_BINARY_DIR}/Snippet.java ${CMAKE_CURRENT_BINARY_DIR}/SnippetsCollection.java ${CMAKE_CURRENT_BINARY_DIR}/Telephone.java ${CMAKE_CURRENT_BINARY_DIR}/Todo.java ${CMAKE_CURRENT_BINARY_DIR}/Url.java ${CMAKE_CURRENT_BINARY_DIR}/vectoraddress.java ${CMAKE_CURRENT_BINARY_DIR}/vectoraffiliation.java ${CMAKE_CURRENT_BINARY_DIR}/vectoralarm.java ${CMAKE_CURRENT_BINARY_DIR}/vectorattachment.java ${CMAKE_CURRENT_BINARY_DIR}/vectorattendee.java ${CMAKE_CURRENT_BINARY_DIR}/vectorcategorycolor.java ${CMAKE_CURRENT_BINARY_DIR}/vectorcontactref.java ${CMAKE_CURRENT_BINARY_DIR}/vectorcs.java ${CMAKE_CURRENT_BINARY_DIR}/vectordatetime.java ${CMAKE_CURRENT_BINARY_DIR}/vectordaypos.java ${CMAKE_CURRENT_BINARY_DIR}/vectoremail.java ${CMAKE_CURRENT_BINARY_DIR}/vectorevent.java ${CMAKE_CURRENT_BINARY_DIR}/vectorfreebusyperiod.java ${CMAKE_CURRENT_BINARY_DIR}/vectorgeo.java ${CMAKE_CURRENT_BINARY_DIR}/vectori.java ${CMAKE_CURRENT_BINARY_DIR}/vectorkey.java ${CMAKE_CURRENT_BINARY_DIR}/vectorperiod.java ${CMAKE_CURRENT_BINARY_DIR}/vectorrelated.java ${CMAKE_CURRENT_BINARY_DIR}/vectors.java ${CMAKE_CURRENT_BINARY_DIR}/vectorsnippet.java ${CMAKE_CURRENT_BINARY_DIR}/vectortelephone.java ${CMAKE_CURRENT_BINARY_DIR}/vectortodo.java ${CMAKE_CURRENT_BINARY_DIR}/vectorurl.java ${CMAKE_CURRENT_BINARY_DIR}/Weekday.java ) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_JAVA_SOURCE_FILE} ${KOLAB_SWIG_JAVA_FILES} COMMAND ${SWIG} -v -c++ -java -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_JAVA_SOURCE_FILE} ../kolabformat.i COMMENT "Generating Java bindings" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ../kolabformat.i kolabxml VERBATIM ) SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_JAVA_SOURCE_FILE} PROPERTIES GENERATED 1) ADD_CUSTOM_TARGET(generate_JAVA_bindings ALL DEPENDS ${KOLAB_SWIG_JAVA_SOURCE_FILE}) # Compile JAVA Bindings set(JAVA_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/javabindings" CACHE STRING "Install directory for java bindings.") install( FILES ${KOLAB_SWIG_JAVA_FILES} DESTINATION ${JAVA_INSTALL_DIR} ) libkolabxml-1.1.2/src/kolabconversions.h000066400000000000000000000655411262531651400203540ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABOBJECTCONVERSION_H #define KOLABOBJECTCONVERSION_H #include #include #include #include #include #include #include "kolabcontainers.h" #include "global_definitions.h" #include "utils.h" #include "kolabnote.h" #include "shared_conversions.h" #include "kolabconfiguration.h" #include "kolabfile.h" #include "base64.h" namespace Kolab { namespace KolabObjects { const char* const KOLAB_NAMESPACE = "http://kolab.org"; const char* const BASE64 = "BASE64"; using namespace Kolab::Utils; using namespace Kolab::Shared; template std::vector toStringList(const xsd::cxx::tree::sequence &s) { std::vector d; std::copy(s.begin(), s.end(), std::back_inserter(d)); return d; } Kolab::Attachment toAttachment(KolabXSD::attachmentPropType aProp) { Kolab::Attachment a; const KolabXSD::attachmentPropType ::parameters_type ¶meters = aProp.parameters(); std::string mimetype = parameters.fmttype(); if (parameters.encoding() && (*parameters.encoding() != BASE64)) { ERROR("wrong encoding"); return Kolab::Attachment(); } if (parameters.x_label()) { a.setLabel(*parameters.x_label()); } if (mimetype.empty()) { ERROR("no mimetype"); } if (aProp.uri()) { a.setUri(*aProp.uri(), mimetype); } else if (aProp.binary()) { a.setData(base64_decode(*aProp.binary()), mimetype); } else { ERROR("not uri and no data available"); } return a; } KolabXSD::attachmentPropType fromAttachment(const Kolab::Attachment &a) { KolabXSD::attachmentPropType::parameters_type p(a.mimetype()); if (!a.label().empty()) { p.x_label(a.label()); } if (!a.data().empty()) { p.encoding(BASE64); } KolabXSD::attachmentPropType attachment(p); if (!a.uri().empty()) { attachment.uri(a.uri()); } else if (!a.data().empty()) { attachment.binary(base64_encode(reinterpret_cast(a.data().c_str()), static_cast(a.data().length()))); } else { ERROR("no uri and no data"); } return attachment; } void writeColors(KolabXSD::Configuration::categorycolor_sequence &colors, const std::vector &input) { BOOST_FOREACH (const CategoryColor &entry, input) { KolabXSD::Configuration::categorycolor_type c(entry.category()); c.color(entry.color()); writeColors(c.categorycolor(), entry.subcategories()); colors.push_back(c); } } std::vector readColors(const KolabXSD::Configuration::categorycolor_sequence &list) { std::vector colors ; BOOST_FOREACH (const KolabXSD::Configuration::categorycolor_type &entry, list) { if (!entry.color()) { ERROR("Color is missing"); continue; } CategoryColor color(entry.category()); color.setColor(*entry.color()); color.setSubcategories(readColors(entry.categorycolor())); colors.push_back(color); } return colors; } KolabXSD::Configuration::type_type getConfigurationType(Kolab::Configuration::ConfigurationType t) { switch (t) { case Kolab::Configuration::TypeDictionary: return KolabXSD::Configuration::type_type::dictionary; case Kolab::Configuration::TypeCategoryColor: return KolabXSD::Configuration::type_type::categorycolor; case Kolab::Configuration::TypeSnippet: return KolabXSD::Configuration::type_type::snippets; case Kolab::Configuration::TypeRelation: return KolabXSD::Configuration::type_type::relation; case Kolab::Configuration::TypeFileDriver: return KolabXSD::Configuration::type_type::file_driver; default: CRITICAL("Invalid configuration type"); } return KolabXSD::Configuration::type_type::dictionary; } template std::string serializeObject(const T &, const std::string prod = std::string()); template <> std::string serializeObject (const Kolab::Configuration &configuration, const std::string prod) { try { const std::string &uid = getUID(configuration.uid()); setCreatedUid(uid); KolabXSD::Configuration::creation_date_type created(0,0,0,0,0,0); if (configuration.created().isValid()) { created = fromDateTime(configuration.created()); } else { created = fromDateTime(timestamp()); } KolabXSD::Configuration::last_modification_date_type lastModificationDate(0,0,0,0,0,0); if (configuration.lastModified().isValid()) { lastModificationDate = fromDateTime(configuration.lastModified()); } else { // WARNING("missing last_modification_date, fallback to current timestamp"); lastModificationDate = fromDateTime(timestamp()); } KolabXSD::Configuration n(uid, getProductId(prod), created, lastModificationDate, getConfigurationType(configuration.type())); switch (configuration.type()) { case Kolab::Configuration::TypeDictionary: { const Kolab::Dictionary &dict = configuration.dictionary(); n.language(dict.language()); BOOST_FOREACH(const std::string &e, dict.entries()) { n.e().push_back(e); } } break; case Kolab::Configuration::TypeCategoryColor: writeColors(n.categorycolor(), configuration.categoryColor()); break; case Kolab::Configuration::TypeSnippet: { const Kolab::SnippetsCollection &snippets = configuration.snippets(); n.name(snippets.name()); BOOST_FOREACH(const Kolab::Snippet &s, snippets.snippets()) { KolabXSD::Snippet::textformat_type type = KolabXSD::Snippet::textformat_type::PLAIN; if (s.textType() == Snippet::HTML) { type = KolabXSD::Snippet::textformat_type::HTML; } KolabXSD::Configuration::snippet_type snippet(s.name(), s.text(), type); if (!s.shortCut().empty()) { snippet.shortcut(s.shortCut()); } n.snippet().push_back(snippet); } } break; case Kolab::Configuration::TypeRelation: { const Kolab::Relation &relation = configuration.relation(); n.name(relation.name()); if (!relation.type().empty()) { n.relationType(relation.type()); } if (!relation.color().empty()) { n.color(relation.color()); } if (!relation.iconName().empty()) { n.iconName(relation.iconName()); } if (!relation.parent().empty()) { n.parent(relation.parent()); } if (!relation.priority() != 0) { n.priority(fromInt(relation.priority())); } BOOST_FOREACH(const std::string &s, relation.members()) { n.member().push_back(s); } } break; case Kolab::Configuration::TypeFileDriver: { const Kolab::FileDriver &fileDriver = configuration.fileDriver(); n.driver(fileDriver.driver()); n.title(fileDriver.title()); n.enabled(fileDriver.enabled()); KolabXSD::FileDriverSettings settings; settings.host(fileDriver.host()); settings.port(fileDriver.port()); settings.username(fileDriver.username()); settings.password(fileDriver.password()); n.settings(settings); } break; default: CRITICAL("Invalid configuration type"); return std::string(); } xml_schema::namespace_infomap map; map[""].name = KOLAB_NAMESPACE; std::ostringstream ostringstream; KolabXSD::configuration(ostringstream, n, map); return ostringstream.str(); } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to write configuration!"); return std::string(); } template <> std::string serializeObject (const Kolab::Note ¬e, const std::string prod) { try { const std::string &uid = getUID(note.uid()); setCreatedUid(uid); KolabXSD::Note::creation_date_type created(0,0,0,0,0,0); if (note.created().isValid()) { created = fromDateTime(note.created()); } else { created = fromDateTime(timestamp()); } KolabXSD::Note::last_modification_date_type lastModificationDate(0,0,0,0,0,0); if (note.lastModified().isValid()) { lastModificationDate = fromDateTime(note.lastModified()); } else { // WARNING("missing last_modification_date, fallback to current timestamp"); lastModificationDate = fromDateTime(timestamp()); } KolabXSD::Note n(uid, getProductId(prod), created, lastModificationDate); if (!note.categories().empty()) { KolabXSD::Note::categories_sequence categories; const std::vector &l = note.categories(); BOOST_FOREACH(const std::string &c, l) { categories.push_back(c); } n.categories(categories); } switch (note.classification()) { case Kolab::ClassPublic: n.classification(KolabXSD::Note::classification_type::PUBLIC); break; case Kolab::ClassPrivate: n.classification(KolabXSD::Note::classification_type::PRIVATE); break; case Kolab::ClassConfidential: n.classification(KolabXSD::Note::classification_type::CONFIDENTIAL); break; default: ERROR("unknown classification"); } if (!note.attachments().empty()) { const std::vector &l = note.attachments(); BOOST_FOREACH(const Kolab::Attachment &a, l) { n.attachment().push_back(fromAttachment(a)); } } n.summary(note.summary()); n.description(note.description()); n.color(note.color()); if (!note.customProperties().empty()) { const std::vector &l = note.customProperties(); BOOST_FOREACH(const Kolab::CustomProperty &a, l) { n.x_custom().push_back(KolabXSD::CustomType(a.identifier, a.value)); } } xml_schema::namespace_infomap map; map[""].name = KOLAB_NAMESPACE; std::ostringstream ostringstream; KolabXSD::note(ostringstream, n, map); return ostringstream.str(); } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to write note!"); return std::string(); } template <> std::string serializeObject (const Kolab::File &file, const std::string prod) { try { const std::string &uid = getUID(file.uid()); setCreatedUid(uid); KolabXSD::File::creation_date_type created(0,0,0,0,0,0); if (file.created().isValid()) { created = fromDateTime(file.created()); } else { created = fromDateTime(timestamp()); } KolabXSD::File::last_modification_date_type lastModificationDate(0,0,0,0,0,0); if (file.lastModified().isValid()) { lastModificationDate = fromDateTime(file.lastModified()); } else { // WARNING("missing last_modification_date, fallback to current timestamp"); lastModificationDate = fromDateTime(timestamp()); } if (file.file().label().empty()) { ERROR("missing filename"); } KolabXSD::File n(uid, getProductId(prod), created, lastModificationDate, fromAttachment(file.file())); if (!file.categories().empty()) { KolabXSD::File::categories_sequence categories; const std::vector &l = file.categories(); BOOST_FOREACH(const std::string &c, l) { categories.push_back(c); } n.categories(categories); } switch (file.classification()) { case Kolab::ClassPublic: n.classification(KolabXSD::File::classification_type::PUBLIC); break; case Kolab::ClassPrivate: n.classification(KolabXSD::File::classification_type::PRIVATE); break; case Kolab::ClassConfidential: n.classification(KolabXSD::File::classification_type::CONFIDENTIAL); break; default: ERROR("unknown classification"); } n.note(file.note()); if (!file.customProperties().empty()) { const std::vector &l = file.customProperties(); BOOST_FOREACH(const Kolab::CustomProperty &a, l) { n.x_custom().push_back(KolabXSD::CustomType(a.identifier, a.value)); } } xml_schema::namespace_infomap map; map[""].name = KOLAB_NAMESPACE; std::ostringstream ostringstream; KolabXSD::file(ostringstream, n, map); return ostringstream.str(); } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to write file!"); return std::string(); } template boost::shared_ptr deserializeObject(const std::string& s, bool isUrl); template <> boost::shared_ptr deserializeObject (const std::string& s, bool isUrl) { try { std::auto_ptr note; if (isUrl) { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseFile(s); if (doc.get()) { note = KolabXSD::note(doc); } } else { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseString(s); if (doc.get()) { note = KolabXSD::note(doc); } } if (!note.get()) { CRITICAL("failed to parse note!"); return boost::shared_ptr(); } boost::shared_ptr n = boost::shared_ptr(new Kolab::Note); n->setUid(note->uid()); n->setCreated(*toDate(note->creation_date())); n->setLastModified(*toDate(note->last_modification_date())); std::vector categories; std::copy(note->categories().begin(), note->categories().end(), std::back_inserter(categories)); n->setCategories(categories); if (note->classification()) { switch (*note->classification()) { case KolabXSD::Note::classification_type::PUBLIC: n->setClassification(Kolab::ClassPublic); break; case KolabXSD::Note::classification_type::PRIVATE: n->setClassification(Kolab::ClassPrivate); break; case KolabXSD::Note::classification_type::CONFIDENTIAL: n->setClassification(Kolab::ClassConfidential); break; default: ERROR("unknown classification"); } } if (!note->attachment().empty()) { std::vector attachments; BOOST_FOREACH(KolabXSD::Note::attachment_type &aProp, note->attachment()) { const Kolab::Attachment &a = toAttachment(aProp); if (!a.isValid()) { ERROR("invalid attachment"); continue; } attachments.push_back(a); } n->setAttachments(attachments); } if (note->summary()) { n->setSummary(*note->summary()); } if (note->description()) { n->setDescription(*note->description()); } if (note->color()) { n->setColor(*note->color()); } setProductId( note->prodid() ); // setFormatVersion( vcards->vcard().version().text() ); // global_xCardVersion = vcalendar.properties().version().text(); setKolabVersion( note->version() ); if (!note->x_custom().empty()) { std::vector customProperties; BOOST_FOREACH(const KolabXSD::CustomType &p, note->x_custom()) { customProperties.push_back(CustomProperty(p.identifier(), p.value())); } n->setCustomProperties(customProperties); } return n; } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to read note!"); return boost::shared_ptr(); } template <> boost::shared_ptr deserializeObject (const std::string& s, bool isUrl) { try { std::auto_ptr configuration; if (isUrl) { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseFile(s); if (doc.get()) { configuration = KolabXSD::configuration(doc); } } else { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseString(s); if (doc.get()) { configuration = KolabXSD::configuration(doc); } } if (!configuration.get()) { CRITICAL("failed to parse configuration!"); return boost::shared_ptr(); } boost::shared_ptr n; if (configuration->type() == KolabXSD::ConfigurationType::dictionary) { std::string lang("XX"); if (configuration->language()) { lang = *configuration->language(); } else { WARNING("missing dictionary language, default to special value XX"); } Dictionary dict(lang); std::vector entries; BOOST_FOREACH (const KolabXSD::Configuration::e_type &entry, configuration->e()) { entries.push_back(entry); } dict.setEntries(entries); n = boost::shared_ptr(new Kolab::Configuration(dict)); } else if (configuration->type() == KolabXSD::ConfigurationType::categorycolor) { n = boost::shared_ptr(new Kolab::Configuration(readColors(configuration->categorycolor()))); } else if (configuration->type() == KolabXSD::ConfigurationType::snippets) { std::string name; if (configuration->name()) { name = *configuration->name(); } SnippetsCollection collection(name); std::vector snippets; BOOST_FOREACH (const KolabXSD::Configuration::snippet_type &entry, configuration->snippet()) { Snippet snippet(entry.name(), entry.text()); if (entry.textformat() == KolabXSD::textformatType::HTML) { snippet.setTextType(Snippet::HTML); } if (entry.shortcut()) { snippet.setShortCut(*entry.shortcut()); } snippets.push_back(snippet); } collection.setSnippets(snippets); n = boost::shared_ptr(new Kolab::Configuration(collection)); } else if (configuration->type() == KolabXSD::ConfigurationType::relation) { std::string name; if (configuration->name()) { name = *configuration->name(); } std::string type; if (configuration->relationType()) { type = *configuration->relationType(); } Relation relation(name, type); if (configuration->color()) { relation.setColor(*configuration->color()); } if (configuration->iconName()) { relation.setIconName(*configuration->iconName()); } if (configuration->parent()) { relation.setParent(*configuration->parent()); } if (configuration->priority()) { relation.setPriority(convertToInt(*configuration->priority())); } relation.setMembers(toStringList(configuration->member())); n = boost::shared_ptr(new Kolab::Configuration(relation)); } else if (configuration->type() == KolabXSD::ConfigurationType::file_driver) { std::string driver; if (configuration->driver()) { driver = *configuration->driver(); } std::string title; if (configuration->title()) { title = *configuration->title(); } Kolab::FileDriver fileDriver(driver, title); fileDriver.setEnabled(*configuration->enabled()); if (configuration->settings()) { fileDriver.setHost(*configuration->settings()->host()); fileDriver.setPort(convertToInt(*configuration->settings()->port())); fileDriver.setUsername(*configuration->settings()->username()); fileDriver.setPassword(*configuration->settings()->password()); } else { CRITICAL("Settings are missing"); } n = boost::shared_ptr(new Kolab::Configuration(fileDriver)); } else { CRITICAL("No valid configuration type"); } n->setUid(configuration->uid()); n->setCreated(*toDate(configuration->creation_date())); n->setLastModified(*toDate(configuration->last_modification_date())); setProductId( configuration->prodid() ); // setFormatVersion( vcards->vcard().version().text() ); // global_xCardVersion = vcalendar.properties().version().text(); setKolabVersion( configuration->version() ); return n; } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to read configuration!"); return boost::shared_ptr(); } template <> boost::shared_ptr deserializeObject (const std::string& s, bool isUrl) { try { std::auto_ptr file; if (isUrl) { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseFile(s); if (doc.get()) { file = KolabXSD::file(doc); } } else { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseString(s); if (doc.get()) { file = KolabXSD::file(doc); } } if (!file.get()) { CRITICAL("failed to parse file!"); return boost::shared_ptr(); } boost::shared_ptr n = boost::shared_ptr(new Kolab::File); n->setUid(file->uid()); n->setCreated(*toDate(file->creation_date())); n->setLastModified(*toDate(file->last_modification_date())); std::vector categories; std::copy(file->categories().begin(), file->categories().end(), std::back_inserter(categories)); n->setCategories(categories); if (file->classification()) { switch (*file->classification()) { case KolabXSD::File::classification_type::PUBLIC: n->setClassification(Kolab::ClassPublic); break; case KolabXSD::File::classification_type::PRIVATE: n->setClassification(Kolab::ClassPrivate); break; case KolabXSD::File::classification_type::CONFIDENTIAL: n->setClassification(Kolab::ClassConfidential); break; default: ERROR("unknown classification"); } } const Kolab::Attachment &attachment = toAttachment(file->file()); if (attachment.label().empty()) { ERROR("Missing filename"); } if (!attachment.isValid()) { ERROR("invalid attachment"); } n->setFile(attachment); if (file->note()) { n->setNote(*file->note()); } setProductId( file->prodid() ); // setFormatVersion( vcards->vcard().version().text() ); // global_xCardVersion = vcalendar.properties().version().text(); setKolabVersion( file->version() ); if (!file->x_custom().empty()) { std::vector customProperties; BOOST_FOREACH(const KolabXSD::CustomType &p, file->x_custom()) { customProperties.push_back(CustomProperty(p.identifier(), p.value())); } n->setCustomProperties(customProperties); } return n; } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to read file!"); return boost::shared_ptr(); } }//Namespace } //Namespace #endif libkolabxml-1.1.2/src/kolabformat.cpp000066400000000000000000000175461262531651400176310ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "kolabformat.h" #include #include "xcalconversions.h" #include "xcardconversions.h" #include "utils.h" #include "kolabconversions.h" #include "objectvalidation.h" namespace Kolab { ErrorSeverity error() { return Utils::getError(); } bool errorOccurred() { return Utils::getError() > Warning; } std::string errorMessage() { return Utils::getErrorMessage(); } std::string productId() { return Utils::productId(); } std::string xCalVersion() { return Utils::xCalVersion(); } std::string xKolabVersion() { return Utils::kolabVersion(); } std::string getSerializedUID() { return Utils::createdUid(); } std::string generateUID() { return Utils::getUID(); } void overrideTimestamp(const cDateTime& dt) { Utils::setOverrideTimestamp(dt); } Kolab::Event readEvent(const std::string& s, bool isUrl) { Utils::clearErrors(); Kolab::XCAL::IncidenceTrait ::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait >(s, isUrl); if (!ptr.get()) { return Kolab::Event(); } validate(*ptr); return *ptr; } std::string writeEvent(const Kolab::Event &event, const std::string& productId) { Utils::clearErrors(); validate(event); const std::string result = XCAL::serializeIncidence< XCAL::IncidenceTrait >(event, productId); //Validate XCAL::deserializeIncidence< XCAL::IncidenceTrait >(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } Kolab::Todo readTodo(const std::string& s, bool isUrl) { Utils::clearErrors(); XCAL::IncidenceTrait::IncidencePtr ptr = XCAL::deserializeIncidence< XCAL::IncidenceTrait >(s, isUrl); if (!ptr.get()) { return Kolab::Todo(); } validate(*ptr); return *ptr; } std::string writeTodo(const Kolab::Todo &event, const std::string& productId) { Utils::clearErrors(); validate(event); const std::string result = XCAL::serializeIncidence< XCAL::IncidenceTrait >(event, productId); //Validate XCAL::deserializeIncidence< XCAL::IncidenceTrait >(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } Journal readJournal(const std::string& s, bool isUrl) { Utils::clearErrors(); XCAL::IncidenceTrait::IncidencePtr ptr = XCAL::deserializeIncidence >(s, isUrl); if (!ptr.get()) { return Kolab::Journal(); } validate(*ptr); return *ptr; } std::string writeJournal(const Kolab::Journal &j, const std::string& productId) { Utils::clearErrors(); validate(j); const std::string result = XCAL::serializeIncidence< XCAL::IncidenceTrait >(j, productId); //Validate XCAL::deserializeIncidence< XCAL::IncidenceTrait >(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } Kolab::Freebusy readFreebusy(const std::string& s, bool isUrl) { Utils::clearErrors(); XCAL::IncidenceTrait::IncidencePtr ptr = XCAL::deserializeIncidence >(s, isUrl); if (!ptr.get()) { return Kolab::Freebusy(); } validate(*ptr); return *ptr; } std::string writeFreebusy(const Freebusy &f, const std::string& productId) { Utils::clearErrors(); validate(f); const std::string result = XCAL::serializeFreebusy >(f, productId); XCAL::deserializeIncidence >(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } Kolab::Contact readContact(const std::string& s, bool isUrl) { Utils::clearErrors(); boost::shared_ptr ptr = XCARD::deserializeCard(s, isUrl); if (!ptr.get()) { return Kolab::Contact(); } validate(*ptr); return *ptr; } std::string writeContact(const Contact &contact, const std::string& productId) { Utils::clearErrors(); validate(contact); const std::string result = XCARD::serializeCard(contact, productId); //Validate XCARD::deserializeCard(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } DistList readDistlist(const std::string& s, bool isUrl) { Utils::clearErrors(); boost::shared_ptr ptr = XCARD::deserializeCard(s, isUrl); if (!ptr.get()) { return Kolab::DistList(); } validate(*ptr); return *ptr; } std::string writeDistlist(const DistList &list, const std::string& productId) { Utils::clearErrors(); validate(list); const std::string result = XCARD::serializeCard(list, productId); //Validate XCARD::deserializeCard(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } Note readNote(const std::string& s, bool isUrl) { Utils::clearErrors(); boost::shared_ptr ptr = Kolab::KolabObjects::deserializeObject(s, isUrl); if (!ptr.get()) { return Kolab::Note(); } validate(*ptr); return *ptr; } std::string writeNote(const Note ¬e, const std::string& productId) { Utils::clearErrors(); validate(note); const std::string result = Kolab::KolabObjects::serializeObject(note, productId); //Validate Kolab::KolabObjects::deserializeObject(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } File readFile(const std::string& s, bool isUrl) { Utils::clearErrors(); boost::shared_ptr ptr = Kolab::KolabObjects::deserializeObject(s, isUrl); if (!ptr.get()) { return Kolab::File(); } validate(*ptr); return *ptr; } std::string writeFile(const File &file, const std::string& productId) { Utils::clearErrors(); validate(file); const std::string result = Kolab::KolabObjects::serializeObject(file, productId); //Validate Kolab::KolabObjects::deserializeObject(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } Configuration readConfiguration(const std::string& s, bool isUrl) { Utils::clearErrors(); boost::shared_ptr ptr = Kolab::KolabObjects::deserializeObject(s, isUrl); if (!ptr.get()) { return Kolab::Configuration(); } validate(*ptr); return *ptr; } std::string writeConfiguration(const Configuration &config, const std::string& productId) { Utils::clearErrors(); validate(config); const std::string result = Kolab::KolabObjects::serializeObject(config, productId); //Validate Kolab::KolabObjects::deserializeObject(result, false); if (errorOccurred()) { LOG("Error occurred while writing.") } return result; } } libkolabxml-1.1.2/src/kolabformat.h000066400000000000000000000125051262531651400172640ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABFORMAT_H #define KOLABFORMAT_H #include #include "kolabcontainers.h" #include "kolabtodo.h" #include "kolabevent.h" #include "kolabjournal.h" #include "kolabcontact.h" #include "kolabnote.h" #include "kolabconfiguration.h" #include "kolabfreebusy.h" #include "kolabfile.h" #include "global_definitions.h" /** * Kolab Format v3 Implementation * * Note that this code is threadsafe, as it uses thread-local storage. * * Example: * * Kolab::Event event; * event.setStart(Kolab::cDateTime("Europe/Zurich",2011,10,10,12,1,1)); * event.setEnd(Kolab::cDateTime("Europe/Zurich",2012,5,5,3,4,4)); * event.setLastModified(Kolab::cDateTime(2011,10,11,12,1,2,true)); * event.setCreated(Kolab::cDateTime(2011,10,11,12,1,3,true)); * std::string serialization = Kolab::writeEvent(ev, "Product ID"); * std::string serializedUID = Kolab::getSerializedUID(); //returns the UID of the just serialized event * if (Kolab::error() != Kolab::NoError) { * std::cout << "Error on write " << Kolab::errorMessage(); * } * Kolab::Event e = Kolab::readEvent(serialization, false); * if (Kolab::error() != Kolab::NoError) { * std::cout << "Error on read " << Kolab::errorMessage(); * } * */ namespace Kolab { /** * Check to see if serialization/deserialization was successful. * * Returns true if at least an Error occurred. Warning is not considered an error. */ bool errorOccurred(); /** * Returns the highest severity of the errors which occured. * * Note that a Warning is not considered an error, use errorOccurred to check for errors. */ Kolab::ErrorSeverity error(); /** * Returns the corresponding error message to the reported error. */ std::string errorMessage(); /** * Returns productId string of the last deserialized object. * Updated during deserialization of object. */ std::string productId(); /** * Returns KolabFormat version of the last deserialized object. * Updated during deserialization of object. */ std::string xKolabVersion(); /** * Returns xCal version of the last deserialized xCal object. * Updated during deserialization of object. */ std::string xCalVersion(); /** * Returns the UID of the last serialized object. * Updated during serialization of the object. */ std::string getSerializedUID(); /** * Returns a generated uid. */ std::string generateUID(); /** * Use this function to override the timestamp which is normally generated upon serialization from the system time. * To override the timestamp call this function once. You will need to clear the timestamp manually by setting a default constructed cDateTime(). * * The timestamp is used as lastModifiedDate on every write, and as creation-date on the first write (when there is no creation-date yet). * * The supplied timestamp must be in UTC format. * * This function exists primarily for testing purpose. */ void overrideTimestamp(const Kolab::cDateTime &dt); /** * Serializing functions for kolab objects. * * Check error() to see if the operation was successful. * * @param isUrl if true, the file with the url @param s is opened and read. * @param productId Sets the productid on serialization. Note that the versionstring of libkolabxml will be appended to the productId. */ Kolab::Event readEvent(const std::string& s, bool isUrl); std::string writeEvent(const Kolab::Event &, const std::string& productId = std::string()); Kolab::Todo readTodo(const std::string& s, bool isUrl); std::string writeTodo(const Kolab::Todo &, const std::string& productId = std::string()); Kolab::Journal readJournal(const std::string& s, bool isUrl); std::string writeJournal(const Kolab::Journal &, const std::string& productId = std::string()); Kolab::Freebusy readFreebusy(const std::string& s, bool isUrl); std::string writeFreebusy(const Kolab::Freebusy &, const std::string& productId = std::string()); Kolab::Contact readContact(const std::string& s, bool isUrl); std::string writeContact(const Kolab::Contact &, const std::string& productId = std::string()); Kolab::DistList readDistlist(const std::string& s, bool isUrl); std::string writeDistlist(const Kolab::DistList &, const std::string& productId = std::string()); Kolab::Note readNote(const std::string& s, bool isUrl); std::string writeNote(const Kolab::Note &, const std::string& productId = std::string()); Kolab::Configuration readConfiguration(const std::string& s, bool isUrl); std::string writeConfiguration(const Kolab::Configuration &, const std::string& productId = std::string()); Kolab::File readFile(const std::string& s, bool isUrl); std::string writeFile(const Kolab::File &, const std::string& productId = std::string()); } #endif // KOLABFORMAT_H libkolabxml-1.1.2/src/kolabformat.i000066400000000000000000000046661262531651400172760ustar00rootroot00000000000000/* kolabformat.i */ %module kolabformat %{ /* This macro ensures that return vectors remain a vector also in python and are not converted to tuples */ #define SWIG_PYTHON_EXTRA_NATIVE_CONTAINERS #include "global_definitions.h" #include "kolabformat.h" #include "containers/kolabcontainers.h" #include "containers/kolabevent.h" #include "containers/kolabtodo.h" #include "containers/kolabjournal.h" #include "containers/kolabcontact.h" #include "containers/kolabnote.h" #include "containers/kolabconfiguration.h" #include "containers/kolabfile.h" #include "containers/kolabfreebusy.h" %} %include "std_string.i" %include "std_vector.i" /* Avoid warnings about not generated operators */ %ignore *::operator=; %ignore *::operator==; namespace std { %template(vectori) vector; %template(vectors) vector; %template(vectordaypos) vector; %template(vectorcs) vector; %template(vectoraddress) vector; %template(vectoraffiliation) vector; %template(vectoralarm) vector; %template(vectorattachment) vector; %template(vectorattendee) vector; %template(vectorcontactref) vector; %template(vectorgeo) vector; %template(vectorevent) vector; %template(vectorrelated) vector; %template(vectortelephone) vector; %template(vectortodo) vector; %template(vectoremail) vector; %template(vectordatetime) vector; %template(vectorurl) vector; %template(vectorkey) vector; %template(vectorcategorycolor) vector; %template(vectorsnippet) vector; %template(vectorfreebusyperiod) vector; %template(vectorperiod) vector; }; %rename(readKolabFile) Kolab::readFile; %rename(writeKolabFile) Kolab::writeFile; %include "global_definitions.h" %include "kolabformat.h" %include "containers/kolabcontainers.h" %include "containers/kolabevent.h" %include "containers/kolabtodo.h" %include "containers/kolabjournal.h" %include "containers/kolabcontact.h" %include "containers/kolabnote.h" %include "containers/kolabconfiguration.h" %include "containers/kolabfile.h" %include "containers/kolabfreebusy.h" libkolabxml-1.1.2/src/objectvalidation.cpp000066400000000000000000000066321262531651400206430ustar00rootroot00000000000000/* * Copyright (C) 2013 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "objectvalidation.h" #include "kolabevent.h" #include "kolabtodo.h" #include "kolabjournal.h" #include "kolabcontact.h" #include "kolabconfiguration.h" #include "kolabfile.h" #include "utils.h" #include "tztable.h" #include namespace Kolab { static boost::unordered_set initializeTzSet() { boost::unordered_set set; for (unsigned int i = 0; i < numOlsonTimezones; i++) { set.insert(olsonTimezones[i]); } return set; } const boost::unordered_set tzSet = initializeTzSet(); bool isValid(const cDateTime &datetime) { if (!datetime.isValid()) { return true; } const std::string tz = datetime.timezone(); if (!tz.empty()) { if (datetime.isUTC() && !tz.empty()) { Utils::logMessage("A UTC datetime may not have a timezone", "", 0, Error); return false; } if (tzSet.find(tz) == tzSet.end()) { Utils::logMessage("Not a valid olson timezone: " + tz, "", 0, Error); return false; } } return true; } #define ASSERT(arg) \ do {\ if ( !(arg) ) { \ Utils::logMessage(#arg " is false", __FILE__, __LINE__, Error); \ } \ } while(0) #define ASSERTEQUAL(arg1, arg2) \ do {\ if ( (arg1) != (arg2) ) { \ Utils::logMessage(#arg1 " != " #arg2, __FILE__, __LINE__, Error); \ } \ } while(0) #define ASSERTEXISTING(arg) \ do {\ if ( !(arg).isValid() ) { \ Utils::logMessage(#arg " is not set", __FILE__, __LINE__, Error); \ } \ } while(0) #define ASSERTVALID(arg) \ do {\ if ( (arg).isValid() && !isValid((arg)) ) { \ Utils::logMessage(#arg " is not valid", __FILE__, __LINE__, Error); \ } \ } while(0) void validate(const Event &event) { ASSERTEXISTING(event.start()); ASSERTVALID(event.start()); ASSERTVALID(event.end()); if (event.start().isValid() && event.end().isValid()) { ASSERTEQUAL(event.start().isDateOnly(), event.end().isDateOnly()); } } void validate(const Todo& todo) { ASSERTVALID(todo.start()); ASSERTVALID(todo.due()); if (todo.start().isValid() && todo.due().isValid()) { ASSERTEQUAL(todo.start().isDateOnly(), todo.due().isDateOnly()); } } void validate(const Journal& journal) { ASSERTVALID(journal.start()); } void validate(const Contact& /* contact */) { } void validate(const DistList& /* distlist */) { } void validate(const Freebusy& /* freebusy */) { } void validate(const Note& /* note */) { } void validate(const Configuration& /* configuration */) { } void validate(const File& /* file */) { } } libkolabxml-1.1.2/src/objectvalidation.h000066400000000000000000000031021262531651400202750ustar00rootroot00000000000000/* * Copyright (C) 2013 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef OBJECTVALIDATION_H #define OBJECTVALIDATION_H namespace Kolab { class Event; class Todo; class Journal; class Freebusy; class Contact; class DistList; class Note; class Configuration; class File; /** * The validations in here are supposed to validate kolab objects beyond what the xml schema covers. * * A typical usecase is to check if event start/end date have the same timezone, or if all used timezones are valid. */ void validate(const Kolab::Event &event); void validate(const Kolab::Todo &todo); void validate(const Kolab::Journal &journal); void validate(const Kolab::Freebusy &freebusy); void validate(const Kolab::Contact &contact); void validate(const Kolab::DistList &distlist); void validate(const Kolab::Note ¬e); void validate(const Kolab::Configuration &configuration); void validate(const Kolab::File &file); } #endif libkolabxml-1.1.2/src/php/000077500000000000000000000000001262531651400153765ustar00rootroot00000000000000libkolabxml-1.1.2/src/php/CMakeLists.txt000066400000000000000000000056401262531651400201430ustar00rootroot00000000000000#Generate PHP wrapper include_directories(../) set(KOLAB_SWIG_PHP_SOURCE_FILE php_kolabformat_wrapper.cpp) add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE} ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.php COMMAND ${SWIG} -v -c++ -php -o ${CMAKE_CURRENT_BINARY_DIR}/${KOLAB_SWIG_PHP_SOURCE_FILE} ../kolabformat.i COMMENT "Generating php bindings" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ../kolabformat.i kolabxml VERBATIM ) set_source_files_properties(${KOLAB_SWIG_PHP_SOURCE_FILE} PROPERTIES GENERATED 1) add_custom_target(generate_php_bindings ALL DEPENDS ${KOLAB_SWIG_PHP_SOURCE_FILE}) #Compile PHP Bindings # Since there is no php library we can't compile with -Wl,--no-undefined if (APPLE) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -flat_namespace -undefined suppress" ) endif() set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-variable -Wno-unused-label -Wno-maybe-uninitialized -Wno-unused-function" ) # Try to find PHP5 find_path(PHP_INCLUDE_DIR NAMES main/php.h PATH_SUFFIXES php php5) find_program(PHP_EXECUTABLE NAMES php) # Libkolabxml needs PHP >= 5.3 set(PHP_MIN_VERSION 50300) # Find where to install the extension files if it's not defined if(NOT DEFINED PHP_INSTALL_DIR) find_program(PHP_CONFIG_EXECUTABLE NAMES php-config) if(PHP_CONFIG_EXECUTABLE) execute_process(COMMAND ${PHP_CONFIG_EXECUTABLE} --extension-dir OUTPUT_VARIABLE _php_extensions_dir ) string(REGEX REPLACE "\n" "" _php_extensions_dir "${_php_extensions_dir}") set(PHP_INSTALL_DIR ${_php_extensions_dir} CACHE STRING "Install directory for PHP bindings.") else() set(PHP_INSTALL_DIR ${LIB_INSTALL_DIR}/extensions) endif() endif() if(PHP_INCLUDE_DIR AND PHP_EXECUTABLE) file(READ ${PHP_INCLUDE_DIR}/main/php_version.h PHP_VERSION_CONTENT) string(REGEX MATCH "#define PHP_VERSION_ID[ ]*[0-9]*\n" _PHP_VERSION_ID_MATCH ${PHP_VERSION_CONTENT}) if(_PHP_VERSION_ID_MATCH) string(REGEX REPLACE "#define PHP_VERSION_ID[ ]*([0-9]*)\n" "\\1" PHP_VERSION_ID ${_PHP_VERSION_ID_MATCH}) endif() # Include the needed PHP5 subdirs set(PHP_INCLUDE_DIRS ${PHP_INCLUDE_DIR} ${PHP_INCLUDE_DIR}/main ${PHP_INCLUDE_DIR}/TSRM ${PHP_INCLUDE_DIR}/Zend ) endif() if(NOT PHP_VERSION_ID VERSION_LESS ${PHP_MIN_VERSION}) include_directories(${PHP_INCLUDE_DIRS}) add_library(phpbindings SHARED ${KOLAB_SWIG_PHP_SOURCE_FILE}) target_link_libraries(phpbindings kolabxml) set_target_properties(phpbindings PROPERTIES OUTPUT_NAME "kolabformat") set_target_properties(phpbindings PROPERTIES PREFIX "") configure_file(test.php ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) install(TARGETS phpbindings LIBRARY DESTINATION ${PHP_INSTALL_DIR}) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.php DESTINATION ${PHP_INSTALL_DIR} ) else() message(WARNING "not building php bindings because php was not found") endif() libkolabxml-1.1.2/src/php/test.php000077500000000000000000000243661262531651400171040ustar00rootroot00000000000000push($val); return $vec; } /////// Test Event $e = new Event(); $e->setCreated(new cDateTime(2012,3,14, 9,5,30, true)); $e->setStart(new cDateTime(2012,7,31)); $d = new cDateTime(2009,10,12); assertequal($e->exceptionDates()->size(), 0, "Event::exceptionDates()"); $e->addExceptionDate($d); assertequal($e->exceptionDates()->size(), 1, "Event::addExceptionDate()"); $r = new RecurrenceRule(); $r->setFrequency(RecurrenceRule::Minutely); $bysec = new vectori(); $bysec->push(1); $bysec->push(3); $r->setBySecond($bysec); $e->setRecurrenceRule($r); $va = new vectoralarm; $a1 = new Alarm("Display alarm"); $a1->setRelativeStart(new Duration(0, 6, 30, 0, true), kolabformat::Start); $va->push($a1); $acr = new vectorcontactref; $acr->push(new ContactReference("alarms@kolab.org")); $a2 = new Alarm("Email alarm", "Alarm description", $acr); $a2->setStart(new cDateTime(2012,7,30, 20,30,0, true)); $va->push($a2); $e->setAlarms($va); $xml = kolabformat::writeEvent($e); #print $xml; assertcontains($xml, '2012-07-31', "Event::setStart() with date only"); assertcontains($xml, '2012-03-14T09:05:30Z', "Event::setCreated() with date-time"); assertcontains($xml, 'MINUTELY', "RecurrenceRule::setFrequency()"); assertcontains($xml, 'MINUTELY13', "RecurrenceRule::setBySecond()"); assertcontains($xml, '2009-10-12', "Event Recurrence Exceptions"); assertcontains($xml, '-PT6H30M', "Alarm::setRelativeStart(Duration)"); assertcontains($xml, '2012-07-30T20:30:00Z', "Alarm::setStart()"); assertcontains($xml, 'START', "Alarm relative to Start"); assertcontains($xml, 'EMAIL', "Email alarm"); assertcontains($xml, 'mailto:%3Calarms%40kolab.org%3E', "Email alarm attendee"); $e1 = kolabformat::readEvent($xml, false); assertequal($xml, kolabformat::writeEvent($e1), "kolabformat::readEvent() => kolabformat::writeEvent()"); $s = $e1->start(); assertequal(sprintf('%d-%d-%d', $s->year(), $s->month(), $s->day()), '2012-7-31', "Event::start()"); $r = $e1->recurrenceRule(); assertequal($r->frequency(), RecurrenceRule::Minutely, "RecurrenceRule::frequency()"); assertequal($r->bysecond()->size(), 2, "RecurrenceRule::bysecond()"); assertequal($e1->exceptionDates()->size(), 1, "Read Event::exceptionDates()"); $va = $e1->alarms(); assertequal($va->size(), 2, "Event::alarms()"); $rr = new RecurrenceRule(); $rr->setFrequency(RecurrenceRule::Monthly); $byday = new vectordaypos; $byday->push(new DayPos(2, kolabformat::Monday)); $byday->push(new DayPos(-1, kolabformat::Friday)); $rr->setByday($byday); $e1->setRecurrenceRule($rr); $xml = kolabformat::writeEvent($e1); #print $xml; assertcontains($xml, '2MO-1FR', "Recurrence by weekday"); $att1 = new Attendee(new ContactReference("john@kolab.org")); $att1->setPartStat(kolabformat::PartDelegated); $att2 = new Attendee(new ContactReference("jane@kolab.org")); $att1->setPartStat(kolabformat::PartNeedsAction); $vdelegatees = new vectorcontactref; $vdelegatees->push($att2->contact()); $att1->setDelegatedTo($vdelegatees); $vdelegators = new vectorcontactref; $vdelegators->push($att1->contact()); $att2->setDelegatedFrom($vdelegators); $attendees = new vectorattendee; $attendees->push($att1); $attendees->push($att2); $e1->setAttendees($attendees); $xml = kolabformat::writeEvent($e1); assertcontains($xml, 'mailto:%3Cjane%40kolab.org%3E', "Delegated-To"); assertcontains($xml, 'mailto:%3Cjohn%40kolab.org%3E', "Delegated-From"); $e2 = kolabformat::readEvent($xml, false); $attendees_ = $e2->attendees(); assertequal($attendees_->size(), 2, "Event::attendees()"); $att1_ = $attendees_->get(0); $att2_ = $attendees_->get(1); assertequal($att1_->contact()->email(), "john@kolab.org", "Attendee email"); $vdelegatees_ = $att1_->delegatedTo(); assertequal($vdelegatees_->size(), 1, "Attendee::delegatedTo()"); assertequal($vdelegatees_->get(0)->email(), "jane@kolab.org", "Delegated-To email"); /////// Test Todo $t = new Todo(); $t->setCreated(new cDateTime(2014,3,14, 9,5,30, true)); $due = new cDateTime(2014,5,20, 17,30,0); $t->setDue($due); $t->setStart(new cDateTime(2014,4,30, 8,0,0)); $t->setSummary('Test Task'); $xml = kolabformat::writeTodo($t); #print $xml; assertcontains($xml, '2014-05-20T17:30:00', "Todo::setDue() with date/time"); assertcontains($xml, '2014-04-30T08:00:00', "Todo::setStart() with date/time"); /////// Test Contact $c = new Contact; $c->setName("Contact-FN"); $nc = new NameComponents; $nc->setSurnames(array2vector("Surname")); $nc->setGiven(array2vector("Given")); $nc->setAdditional(array2vector(array("Middle1", "Middle2"))); $nc->setPrefixes(array2vector("Prefix")); #$nc->setSuffixes(new vectors); assertcontains($nc->surnames()->size(), 1, "NameComponents::setSurnames()"); assertcontains($nc->given()->size(), 1, "NameComponents::setGiven()"); assertcontains($nc->additional()->size(), 2, "NameComponents::setAdditional()"); assertcontains($nc->prefixes()->size(), 1, "NameComponents::setPrefixes()"); assertcontains($nc->suffixes()->size(), 0, "NameComponents::suffixes()"); $c->setNameComponents($nc); $c->setTitles(array2vector("MyProfession")); $pic = "R0lGODlhEgASAIAAAMDAwAAAACH5BAEAAAAALAAAAAASABIAQAIPhI+py+0Po5y02ouz3pwXADs="; $c->setPhoto(base64_decode($pic), 'image/gif'); $geo = new vectorgeo; $geo->push(new Geo(46.952585, 7.43766)); $c->setGPSpos($geo); $bd = new cDateTime(1980,8,1); $c->setBDay($bd); $vcs = new vectorcs; $vcs->push(new CustomProperty("initials", "KF")); $c->setCustomProperties($vcs); $xml = kolabformat::writeContact($c); #print $xml; assertcontains($xml, "urn:uuid:", "Generate Contact UID as urn::uuid"); assertcontains($xml, "SurnameGivenMiddle1Middle2Prefix", "Contact::setNameComponents()"); assertcontains($xml, "<text>MyProfession</text>", "Contact::setTitles()"); assertcontains($xml, "data:image/gif;base64,$pic", "Contact::setPhoto()"); assertcontains($xml, "19800801", "Contact::setBDay()"); assertcontains($xml, "geo:46.952585,7.43766", "Contact::setGPSpos()"); $c1 = kolabformat::readContact($xml, false); assertequal($xml, kolabformat::writeContact($c1), "kolabformat::readContact() => kolabformat::writeContact()"); assertequal($c1->photoMimetype(), "image/gif", "Contact::photoMimetype()"); assertequal($c1->uid(), kolabformat::getSerializedUID(), "kolabformat::getSerializedUID()"); $lm = $c1->lastModified(); assertequal(sprintf('%d-%02d-%02d', $lm->year(), $lm->month(), $lm->day()), gmdate('Y-m-d'), "Contact::lastModified()"); $c1->setBDay(new cDateTime); $xml = kolabformat::writeContact($c); assertfalse(strpos($xml, ''), "Unset BDay with empty cDateTime"); /////// Test DistList $dl = new DistList; $dl->setName("DalistÄÖŸ"); $m = new vectorcontactref; $a = new ContactReference(ContactReference::EmailReference, "a@localhost", "Member-A"); $m->push($a); $b = new ContactReference(ContactReference::UidReference, "x-member-b-fff"); $b->setName("Member-B"); $m->push($b); #$c = new ContactReference(ContactReference::EmailAndUidReference, "c@localhost", "dddaab06-0000-0000-eeb5-cc64ff7f0000"); #$c->setName("Member-C"); #$m->push($c); assertequal($m->size(), 2, "vectorcontactref::size()"); $dl->setMembers($m); $xml = kolabformat::writeDistlist($dl); #print $xml; assertcontains($xml, 'DalistÄÖŸ', "kolabformat::writeDistlist(): FN (UTF-8)"); assertcontains($xml, 'mailto:Member-A%3Ca%40localhost%3E', "kolabformat::writeDistlist(): mailto uri"); assertcontains($xml, 'urn:uuid:x-member-b-fff', "kolabformat::writeDistlist(): member urn::uuid"); /////// Test Configuration.Dictionary $d = new Dictionary('de'); $d->setEntries(array2vector(array('Kolab','Roundcube','libkolabxml'))); $c = new Configuration($d); $xml = kolabformat::writeConfiguration($c); #print $xml; $c2 = kolabformat::readConfiguration($xml, false); $d2 = $c2->dictionary(); assertequal($d2->language(), 'de', "Configuration.Dictionary::language"); assertequal($d2->entries()->size(), 3, "Dictionary::entries()"); $d = new Dictionary('en'); $d->setEntries(array2vector(array('Kolab','Roundcube','libkolabxml'))); $c = new Configuration($d); $xml = kolabformat::writeConfiguration($c); #print $xml; $c3 = kolabformat::readConfiguration($xml, false); asserttrue($c2->uid() != $c3->uid(), "Generate different UIDs for configuration objects"); // terminate with error status exit($errors); libkolabxml-1.1.2/src/python/000077500000000000000000000000001262531651400161305ustar00rootroot00000000000000libkolabxml-1.1.2/src/python/CMakeLists.txt000066400000000000000000000033261262531651400206740ustar00rootroot00000000000000# Generate Python wrapper include_directories(../) # Compile Python Bindings find_package(PythonLibs REQUIRED) if (NOT PYTHONLIBS_FOUND) message("python libs not found, not building python bindings") return() endif() message("found python include dirs: ${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH}") set(KOLAB_SWIG_PYTHON_SOURCE_FILE ${CMAKE_CURRENT_BINARY_DIR}/python_kolabformat_wrapper.cpp) set(KOLAB_SWIG_PYTHON_HEADER_FILE ${CMAKE_CURRENT_BINARY_DIR}/kolabformat.py) add_custom_command(OUTPUT ${KOLAB_SWIG_PYTHON_SOURCE_FILE} ${KOLAB_SWIG_PYTHON_HEADER_FILE} COMMAND ${SWIG} -v -c++ -python -o ${KOLAB_SWIG_PYTHON_SOURCE_FILE} ../kolabformat.i COMMENT "Generating python bindings" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ../kolabformat.i kolabxml VERBATIM ) SET_SOURCE_FILES_PROPERTIES(${KOLAB_SWIG_PYTHON_SOURCE_FILE} PROPERTIES GENERATED 1) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-maybe-uninitialized" ) #${PYTHON_INCLUDE_PATH} is for backwards compatibility (el6) include_directories(${PYTHON_INCLUDE_DIRS} ${PYTHON_INCLUDE_PATH}) set(PYTHON_MODULE_PREFIX "_") python_add_module(kolabformat ${KOLAB_SWIG_PYTHON_SOURCE_FILE}) #cmake 2.6.4 fails to respect the module prefix SET_TARGET_PROPERTIES(kolabformat PROPERTIES PREFIX "${PYTHON_MODULE_PREFIX}") target_link_libraries(kolabformat kolabxml ${PYTHON_LIBRARIES}) configure_file(test.py ${CMAKE_CURRENT_BINARY_DIR} COPYONLY) set(PYTHON_INSTALL_DIR "${CMAKE_CURRENT_BINARY_DIR}/pythonbindings" CACHE STRING "Install directory for python bindings.") install(TARGETS kolabformat LIBRARY DESTINATION ${PYTHON_INSTALL_DIR}) install( FILES ${KOLAB_SWIG_PYTHON_HEADER_FILE} DESTINATION ${PYTHON_INSTALL_DIR} ) libkolabxml-1.1.2/src/python/test.py000066400000000000000000000050231262531651400174610ustar00rootroot00000000000000import kolabformat import unittest class TestKolabformat(unittest.TestCase): def test_event_basic(self): e = kolabformat.Event() e.setSummary("test") start = kolabformat.cDateTime(2014,7,1, 12,30,0) start.setTimezone("Europe/London") e.setStart(start) ex = e.exceptionDates() ex.size() ex.push_back(kolabformat.cDateTime(2014,7,5)) ex.size() e.exceptionDates().size() e.setExceptionDates(ex) e.exceptionDates().size() xml = kolabformat.writeEvent(e) e1 = kolabformat.readEvent(xml, False) xml1 = kolabformat.writeEvent(e1) self.assertEqual(xml, xml1) def test_event_delegated(self): e = kolabformat.Event() e.setSummary("test") e.setStart(kolabformat.cDateTime(2014,7,1, 12,30,0)) att1 = kolabformat.Attendee(kolabformat.ContactReference("john@doe.org")) att1.setRole(kolabformat.NonParticipant) att1.setPartStat(kolabformat.PartDelegated) att1.setDelegatedTo([kolabformat.ContactReference("jane@doe.org")]) att2 = kolabformat.Attendee(kolabformat.ContactReference("jane@doe.org")) att2.setRole(kolabformat.Required) att2.setPartStat(kolabformat.PartNeedsAction) att2.setDelegatedFrom([kolabformat.ContactReference("john@doe.org")]) e.setAttendees([att1, att2]) self.assertEqual(len(att1.delegatedTo()), 1) self.assertEqual(len(att2.delegatedFrom()), 1) xml = kolabformat.writeEvent(e) e1 = kolabformat.readEvent(xml, False) # print xml attendees_ = e1.attendees() self.assertEqual(len(attendees_), 2) self.assertEqual(len(attendees_[0].delegatedTo()), 1) self.assertEqual(len(attendees_[1].delegatedFrom()), 1) delegatees = attendees_[0].delegatedTo() self.assertEqual(delegatees[0].email(), "jane@doe.org") def test_todo_partstat(self): t = kolabformat.Todo() t.setSummary("test") t.setPercentComplete(40) att = kolabformat.Attendee(kolabformat.ContactReference("john@doe.org")) att.setRole(kolabformat.Required) att.setPartStat(kolabformat.PartInProcess) t.setAttendees([att]) xml = kolabformat.writeTodo(t) self.assertTrue("IN-PROCESS" in xml) t1 = kolabformat.readTodo(xml, False) attendees = t1.attendees() self.assertEqual(attendees[0].partStat(), kolabformat.PartInProcess) if __name__ == '__main__': unittest.main()libkolabxml-1.1.2/src/shared_conversions.h000066400000000000000000000063061262531651400206630ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef SHAREDCONVERSIONS_H #define SHAREDCONVERSIONS_H #include #include "kolabcontainers.h" #include #include "utils.h" #include namespace Kolab { namespace Shared { typedef boost::shared_ptr cDateTimePtr; typedef ::xsd::cxx::tree::type type; #if (XSD_INT_VERSION >= 4000000L) typedef ::xsd::cxx::tree::simple_type< char, type > simple_type; #else typedef ::xsd::cxx::tree::simple_type< type > simple_type; #endif typedef ::xsd::cxx::tree::date< char, simple_type > date; typedef ::xsd::cxx::tree::date_time< char, simple_type > date_time; using namespace Utils; cDateTimePtr toDate(const date &dt) { cDateTimePtr date(new cDateTime()); date->setDate(dt.year(), dt.month(), dt.day()); return date; } cDateTimePtr toDate(const date_time &dt) { cDateTimePtr date(new cDateTime()); date->setDate(dt.year(), dt.month(), dt.day()); date->setTime(dt.hours(), dt.minutes(), convertToInt(dt.seconds())); if (dt.zone_present()) { date->setUTC(true); } return date; } date_time fromDateTime(const cDateTime &d) { date_time date(d.year(), fromInt(d.month()), fromInt(d.day()), fromInt(d.hour()), fromInt(d.minute()), fromInt(d.second())); if (d.isUTC()) { //Setting both zone hours/and zone minutes to zero results in a Z being appended to indicate UTC date.zone_hours(0); date.zone_minutes(0); } return date; } date fromDate(const cDateTime &d) { date de(fromInt(d.year()), fromInt(d.month()), fromInt(d.day())); return de; } std::string toURN(const std::string &uid) { if (uid.substr(0, 9) == std::string("urn:uuid:")) { return uid; } return std::string("urn:uuid:")+uid; } std::string fromURN(const std::string &uri) { if (uri.substr(0, 9) != std::string("urn:uuid:")) { LOG("not a urn"); return uri; } return uri.substr(9); } Kolab::ContactReference toContactReference(const std::string &uri) { std::string name; if (uri.substr(0, 9) == std::string("urn:uuid:")) { return Kolab::ContactReference(Kolab::ContactReference::UidReference, fromURN(uri)); } const std::string &email = fromMailto(uri, name); return Kolab::ContactReference(Kolab::ContactReference::EmailReference, email, name); } } //Namespace } //Namespace #endif libkolabxml-1.1.2/src/uriencode.cpp000066400000000000000000000027421262531651400172750ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include std::string uriEncode(const std::string &s) { CURL *easyhandle = curl_easy_init(); char *result = curl_easy_escape(easyhandle, s.c_str(), static_cast(s.length())); curl_easy_cleanup(easyhandle); if (!result) { return std::string(); } const std::string r(result); curl_free(result); return r; } std::string uriDecode(const std::string &s) { CURL *easyhandle = curl_easy_init(); int length = 0; char *result = curl_easy_unescape(easyhandle, s.c_str(), static_cast(s.length()), &length); curl_easy_cleanup(easyhandle); if (!length) { return std::string(); } const std::string r(result, length); curl_free(result); return r; } libkolabxml-1.1.2/src/uriencode.h000066400000000000000000000017201262531651400167350ustar00rootroot00000000000000/* * Copyright (C) 2012 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef URIENCODE_H #define URIENCODE_H #include /** * Url encoding according to RFC 3986 (used for mailto encoding) */ std::string uriEncode(const std::string &s); std::string uriDecode(const std::string &s); #endiflibkolabxml-1.1.2/src/utils.cpp000066400000000000000000000173141262531651400164610ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include "utils.h" #include #include #include #if BOOST_VERSION >= 104300 #include #include #include #else #include #endif #include #include #include #include "base64.h" #include "uriencode.h" #include "libkolabxml-version.h" namespace Kolab { namespace Utils { /** * We have to store our global variables thread-local to ensure thread-safety. */ struct Global { std::string createdUID; std::string productId; std::string xKolabVersion; std::string xCalVersion; ErrorSeverity errorBit; std::string errorMessage; cDateTime overrideTimestamp; }; boost::thread_specific_ptr ptr; class ThreadLocal { public: static Global &inst() { Global *t = ptr.get(); // std::cout << "inst " << boost::this_thread::get_id() << std::endl; if (!t) { // std::cout << "initialize Global" << std::endl; t = new Global(); ptr.reset(t); } return *t; } }; void setKolabVersion(const std::string &s) { ThreadLocal::inst().xKolabVersion = s; } std::string kolabVersion() { return ThreadLocal::inst().xKolabVersion; } void setXCalVersion(const std::string &s) { ThreadLocal::inst().xCalVersion = s; } std::string xCalVersion() { return ThreadLocal::inst().xCalVersion; } void setProductId(const std::string &s) { ThreadLocal::inst().productId = s; } std::string productId() { return ThreadLocal::inst().productId; } void setCreatedUid(const std::string &s) { ThreadLocal::inst().createdUID = s; } std::string createdUid() { return ThreadLocal::inst().createdUID; } std::string getUID(const std::string &s) { if (!s.empty()) { return s; } #if BOOST_VERSION >= 104300 //Required because boost::uuids::uuid is implemented as POD type class uuid_class : public boost::uuids::uuid { public: uuid_class() : boost::uuids::uuid(boost::uuids::random_generator()()) {} }; uuid_class u; // initialize uuid return boost::uuids::to_string(u); #else uuid_t *uuid; //to avoid the "dereferencing type-punned pointer will break strict-aliasing rules" warning char * __attribute__((__may_alias__)) str = 0; uuid_create(&uuid); uuid_make(uuid, UUID_MAKE_V1); uuid_export(uuid, UUID_FMT_STR, (void**)&str, 0); uuid_destroy(uuid); return std::string(str, 36); //We don't need the terminating \0 #endif } cDateTime getCurrentTime() { time_t rawtime; struct tm * ptm; time(&rawtime); ptm = gmtime(&rawtime); return cDateTime(ptm->tm_year+1900, ptm->tm_mon+1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, true); } void setOverrideTimestamp(const cDateTime &dt) { ThreadLocal::inst().overrideTimestamp = dt; } cDateTime timestamp() { const cDateTime &dt = ThreadLocal::inst().overrideTimestamp; if (dt.isValid()) { LOG("Timestamp overridden"); return dt; } return getCurrentTime(); } void logMessage(const std::string &m, ErrorSeverity s) { switch (s) { case NoError: std::cout << "Debug: " << m << std::endl; break; case Warning: std::cerr << "Warning: " << m << std::endl; if (ThreadLocal::inst().errorBit < Warning) { ThreadLocal::inst().errorBit = Warning; ThreadLocal::inst().errorMessage = m; } break; case Error: std::cerr << "Error: " << m << std::endl; if (ThreadLocal::inst().errorBit < Error) { ThreadLocal::inst().errorBit = Error; ThreadLocal::inst().errorMessage = m; } break; case Critical: default: std::cerr << "Critical: " << m << std::endl; if (ThreadLocal::inst().errorBit < Critical) { ThreadLocal::inst().errorBit = Critical; ThreadLocal::inst().errorMessage = m; } } } void logMessage(const std::string &message, const std::string &file, int line, ErrorSeverity s) { logMessage(file+" "+boost::lexical_cast(line)+": " + " " + message, s); } void clearErrors() { ThreadLocal::inst().errorBit = NoError; ThreadLocal::inst().errorMessage.clear(); } ErrorSeverity getError() { return ThreadLocal::inst().errorBit; } std::string getErrorMessage() { return ThreadLocal::inst().errorMessage; } std::string uriInlineEncoding(const std::string &s, const std::string &mimetype) { return std::string("data:")+mimetype+std::string(";base64,")+base64_encode(reinterpret_cast(s.c_str()), static_cast(s.length())); } std::string uriInlineDecoding(const std::string &s, std::string &mimetype) { if (s.substr(0, 5) != std::string("data:")) { ERROR("wrong picture encoding"); std::cout << s << " " << s.substr(0, 5) << std::endl; return std::string(); } std::size_t pos = s.find(";",5); if (pos == std::string::npos) { ERROR("wrong picture encoding"); std::cout << s << " " << s.substr(0, 5) << std::endl; return std::string(); } mimetype = s.substr(5, pos-5); if (s.substr(pos+1, 6) != std::string("base64")) { ERROR("wrong picture encoding"); std::cout << s << " " << s.substr(pos+1, 6) << std::endl; return std::string(); } return base64_decode(s.substr(pos+8, s.size()-(pos+8))); } std::string toMailto(const std::string &email, const std::string &name) { std::string mailto; if (!name.empty()) { mailto.append(name); } mailto.append("<"); mailto.append(email); mailto.append(">"); return std::string("mailto:")+uriEncode(mailto); } std::string fromMailto(const std::string &mailtoUri, std::string &name) { const std::string &decoded = uriDecode(mailtoUri); if (decoded.substr(0, 7).compare("mailto:")) { WARNING("no mailto address"); std::cout << decoded << std::endl; return mailtoUri; } std::size_t begin = decoded.find('<',7); if (begin == std::string::npos) { WARNING("no mailto address"); std::cout << decoded << std::endl; return mailtoUri; } std::size_t end = decoded.find('>', begin); if (end == std::string::npos) { WARNING("no mailto address"); std::cout << decoded << std::endl; return mailtoUri; } name = decoded.substr(7, begin-7); const std::string &email = decoded.substr(begin+1, end-begin-1); return email; } std::string fromMailto(const std::string &mailtoUri) { std::string n; return fromMailto(mailtoUri, n); } std::string getProductId(const std::string& clientProdid) { if (clientProdid.empty()) { return KOLAB_LIB_VERSION_STRING; } return clientProdid + " " + KOLAB_LIB_VERSION_STRING; } } //Namespace } //Namespace libkolabxml-1.1.2/src/utils.h000066400000000000000000000074011262531651400161220ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef UTILS_H #define UTILS_H #include #include "kolabcontainers.h" #include "global_definitions.h" #include namespace Kolab { namespace Utils { /** * Returns a new globally unique UID if the parameter is empty */ std::string getUID(const std::string & = std::string()); void logMessage(const std::string &,const std::string &, int, ErrorSeverity s); #define LOG(message) Utils::logMessage(message,__FILE__, __LINE__, NoError); #define WARNING(message) Utils::logMessage(message,__FILE__, __LINE__, Warning); #define ERROR(message) Utils::logMessage(message,__FILE__, __LINE__, Error); #define CRITICAL(message) Utils::logMessage(message,__FILE__, __LINE__, Critical); void logMessage(const std::string &, ErrorSeverity s = Warning); /** * The following values must be updated by the serialization/deserialization functions */ /** * The error state after serialization/deserialization */ void clearErrors(); ErrorSeverity getError(); std::string getErrorMessage(); /** * The uid of the last serialized object */ void setCreatedUid(const std::string &); std::string createdUid(); /** * The productId of the last deserialized object */ void setProductId(const std::string &); std::string productId(); /** * The Kolab Format Version of the last deserialized object */ void setKolabVersion(const std::string &); std::string kolabVersion(); /** * The xCal Version of the last deserialized object */ void setXCalVersion(const std::string &); std::string xCalVersion(); /** * A timestamp which overrides the one normally used. */ void setOverrideTimestamp(const cDateTime &); /** * From system time or overrideTimestamp if set. */ cDateTime timestamp(); /** * Helper functions for save conversion of integer types (so we can catch overflows) */ template int convertToInt(T integer) { try { return boost::numeric_cast(integer); } catch(boost::numeric::negative_overflow& e) { ERROR(e.what()); } catch(boost::numeric::positive_overflow& e) { ERROR(e.what()); } catch(boost::numeric::bad_numeric_cast& e) { ERROR(e.what()); } return 0; } template T fromInt(int integer) { try { return boost::numeric_cast(integer); } catch(boost::numeric::negative_overflow& e) { ERROR(e.what()); } catch(boost::numeric::positive_overflow& e) { ERROR(e.what()); } catch(boost::numeric::bad_numeric_cast& e) { ERROR(e.what()); } return 0; } std::string uriInlineEncoding(const std::string &, const std::string &mime); std::string uriInlineDecoding(const std::string &s, std::string &mimetype); std::string toMailto(const std::string &email, const std::string &name = std::string()); std::string fromMailto(const std::string &mailtoUri, std::string &name); std::string fromMailto(const std::string &mailtoUri); /** * Appends the libkolabxml productid and returns the string */ std::string getProductId(const std::string &clientProdid); } //Namespace } //Namespace #endif libkolabxml-1.1.2/src/xcalconversions.h000066400000000000000000002166231262531651400202120ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef XCALCONVERSIONS_H #define XCALCONVERSIONS_H #include "global_definitions.h" #include "libkolabxml-version.h" #include #include #include #include #include #include #include #include #include #include #include "kolabcontainers.h" #include "kolabtodo.h" #include "kolabevent.h" #include "kolabjournal.h" #include #include "utils.h" #include "base64.h" #include "shared_conversions.h" namespace Kolab { namespace XCAL { const char* const XCAL_VERSION = "2.0"; const char* const XCAL_NAMESPACE = "urn:ietf:params:xml:ns:icalendar-2.0"; const char* const TZ_PREFIX = "/kolab.org/"; const char* const THISANDFUTURE = "THISANDFUTURE"; const char* const BASE64 = "BASE64"; const char* const NEEDSACTION = "NEEDS-ACTION"; const char* const COMPLETED = "COMPLETED"; const char* const COMPLETED_COMPAT = "OPAQUE"; const char* const INPROCESS = "IN-PROCESS"; const char* const CANCELLED = "CANCELLED"; const char* const TENTATIVE = "TENTATIVE"; const char* const CONFIRMED = "CONFIRMED"; const char* const DRAFT = "DRAFT"; const char* const FINAL = "FINAL"; const char* const CONFIDENTIAL = "CONFIDENTIAL"; const char* const PRIVATE = "PRIVATE"; const char* const PUBLIC = "PUBLIC"; const char* const PARTACCEPTED = "ACCEPTED"; const char* const PARTDECLINED = "DECLINED"; const char* const PARTDELEGATED = "DELEGATED"; const char* const PARTNEEDSACTION = "NEEDS-ACTION"; const char* const PARTTENTATIVE = "TENTATIVE"; const char* const PARTINPROCESS = "IN-PROCESS"; const char* const PARTCOMPLETED = "COMPLETED"; const char* const CHAIR = "CHAIR"; const char* const NONPARTICIPANT = "NON-PARTICIPANT"; const char* const OPTIONAL = "OPT-PARTICIPANT"; const char* const REQUIRED = "REQ-PARTICIPANT"; const char* const DISPLAYALARM = "DISPLAY"; const char* const EMAILALARM = "EMAIL"; const char* const AUDIOALARM = "AUDIO"; const char* const TRANSPARENT = "TRANSPARENT"; const char* const OPAQUE = "OPAQUE"; const char* const MO = "MO"; const char* const TU = "TU"; const char* const WE = "WE"; const char* const TH = "TH"; const char* const FR = "FR"; const char* const SA = "SA"; const char* const SU = "SU"; const char* const GROUP = "GROUP"; const char* const INDIVIDUAL = "INDIVIDUAL"; const char* const RESOURCE = "RESOURCE"; const char* const UNKNOWN = "UNKNOWN"; const char* const ROOM = "ROOM"; //Alarms const char* const START = "START"; const char* const END = "END"; //Freebusy const char* const BUSY = "BUSY"; const char* const BUSY_TENTATIVE = "BUSY-TENTATIVE"; const char* const BUSY_OUTOFOFFICE = "X-OUT-OF-OFFICE"; using namespace Kolab::Utils; using namespace Kolab::Shared; //=== Generic Conversions === int toInt(const icalendar_2_0::IntegerPropertyType &prop) { return convertToInt(prop.integer()); } std::vector toStringList(const icalendar_2_0::TextListPropertyType &s) { std::vector d; std::copy(s.text().begin(), s.text().end(), std::back_inserter(d)); return d; } template std::auto_ptr fromStringList(const std::vector &list) { std::auto_ptr ptr(new T()); std::copy(list.begin(), list.end(), std::back_inserter(ptr->text())); return ptr; } //TODO doesn't seem very useful after all, remove std::string toString(const icalendar_2_0::TextPropertyType &s) { return s.text(); } std::string fromDayPos(const Kolab::DayPos &d) { std::string s; if (d.occurence() != 0) { s.append(boost::lexical_cast(d.occurence())); } switch (d.weekday()) { case Kolab::Monday: s.append(MO); break; case Kolab::Tuesday: s.append(TU); break; case Kolab::Wednesday: s.append(WE); break; case Kolab::Thursday: s.append(TH); break; case Kolab::Friday: s.append(FR); break; case Kolab::Saturday: s.append(SA); break; case Kolab::Sunday: s.append(SU); break; } return s; } Kolab::DayPos toDayPos(const std::string &s) { std::string number; bool gotOccurrence = false; int occurrence = 0; for (std::string::const_iterator it = s.begin(); it != s.end(); it++) { switch(*it) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '+': case '-': number.push_back(*it); break; default: if (!gotOccurrence && !number.empty()) { try { occurrence = boost::lexical_cast(number); } catch(boost::bad_lexical_cast &) { ERROR("failed to convert: " + number); return DayPos(); } number.clear(); } gotOccurrence = true; number.push_back(*it); break; } } if (number == MO) { return DayPos(occurrence, Kolab::Monday); } else if (number == TU) { return DayPos(occurrence, Kolab::Tuesday); } else if (number == WE) { return DayPos(occurrence, Kolab::Wednesday); } else if (number == TH) { return DayPos(occurrence, Kolab::Thursday); } else if (number == FR) { return DayPos(occurrence, Kolab::Friday); } else if (number == SA) { return DayPos(occurrence, Kolab::Saturday); } else if (number == SU) { return DayPos(occurrence, Kolab::Sunday); } return DayPos(); } std::string fromDuration(const Kolab::Duration &d) { std::string s; if (!d.isValid()) { return s; } if (d.isNegative()) { s.push_back('-'); } s.push_back('P'); try { if (d.weeks() > 0) { s.append(boost::lexical_cast(d.weeks())); s.push_back('W'); } if (d.days() > 0) { s.append(boost::lexical_cast(d.days())); s.push_back('D'); } if (d.hours() > 0 || d.minutes() > 0 || d.seconds() > 0) { s.push_back('T'); if (d.hours() > 0) { s.append(boost::lexical_cast(d.hours())); s.push_back('H'); } if (d.minutes() > 0) { s.append(boost::lexical_cast(d.minutes())); s.push_back('M'); } if (d.seconds() > 0) { s.append(boost::lexical_cast(d.seconds())); s.push_back('S'); } } } catch(boost::bad_lexical_cast &) { ERROR("failed to convert duration"); return std::string(); } return s; } Kolab::Duration toDuration(const icalendar_2_0::DurationValueType &d) { int weeks = 0; int days = 0; int hours = 0; int minutes = 0; int seconds = 0; bool negative = false; std::string number; for (std::string::const_iterator it = d.begin(); it != d.end(); it++) { switch(*it) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': number.push_back(*it); break; case 'H': try { hours = boost::lexical_cast(number); } catch(boost::bad_lexical_cast &) { ERROR("failed to convert: " + number); return Duration(); } number.clear(); break; case 'M': try { minutes = boost::lexical_cast(number); } catch(boost::bad_lexical_cast &) { ERROR("failed to convert: " + number); return Duration(); } number.clear(); break; case 'S': try { seconds = boost::lexical_cast(number); } catch(boost::bad_lexical_cast &) { ERROR("failed to convert: " + number); return Duration(); } number.clear(); break; case 'T': break; case 'W': try { weeks = boost::lexical_cast(number); } catch(boost::bad_lexical_cast &) { ERROR("failed to convert: " + number); return Duration(); } return Duration(weeks, negative); case 'D': try { days = boost::lexical_cast(number); } catch(boost::bad_lexical_cast &) { ERROR("failed to convert: " + number); return Duration(); } number.clear(); break; case '+': break; case '-': negative = true; break; case 'P': break; default: ERROR("failed to convert duration: " + *it); return Duration(); } } return Duration(days, hours, minutes, seconds, negative); } template T fromContactReference(const Kolab::ContactReference &c) { T organizer(toMailto(c.email())); typename T::parameters_type p; if (!c.name().empty()) { icalendar_2_0::CnParamType name(c.name()); p.baseParameter().push_back(name); } if (!c.uid().empty()) { icalendar_2_0::DirParamType dir(toURN(c.uid())); p.baseParameter().push_back(dir); } organizer.parameters(p); return organizer; } Kolab::ContactReference toContactReference(const icalendar_2_0::CalAddressPropertyType &cal) { const std::string &email = fromMailto(cal.cal_address());; std::string name; std::string uid; if (cal.parameters()) { for (icalendar_2_0::ArrayOfParameters::baseParameter_const_iterator it((*cal.parameters()).baseParameter().begin()); it != (*cal.parameters()).baseParameter().end(); it++) { if (const icalendar_2_0::CnParamType * tz = dynamic_cast (&*it)) { name = tz->text(); continue; } if (const icalendar_2_0::DirParamType * tz = dynamic_cast (&*it)) { uid = fromURN(tz->uri()); continue; } } } return Kolab::ContactReference(email, name, uid); } template Kolab::Attachment toAttachment(T aProp) { Kolab::Attachment a; std::string mimetype; if (aProp.parameters()) { const icalendar_2_0::AttachPropType ::parameters_type ¶meters = *aProp.parameters(); for (icalendar_2_0::AttachPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) { if (const icalendar_2_0::FmttypeParamType *p = dynamic_cast (&*it)) { mimetype = p->text(); } if (const icalendar_2_0::EncodingParamType *p = dynamic_cast (&*it)) { if (p->text() != BASE64) { ERROR("wrong encoding"); return Kolab::Attachment(); } } if (const icalendar_2_0::XlabelParamType *p = dynamic_cast (&*it)) { a.setLabel(p->text()); } } } if (aProp.uri()) { a.setUri(*aProp.uri(), mimetype); } else if (aProp.binary()) { a.setData(base64_decode(*aProp.binary()), mimetype); } else { ERROR("no uri and no data available"); } return a; } icalendar_2_0::AttachPropType fromAttachment(const Kolab::Attachment &a) { icalendar_2_0::AttachPropType attachment; icalendar_2_0::AttachPropType::parameters_type p; p.baseParameter().push_back(icalendar_2_0::FmttypeParamType(a.mimetype())); if (!a.label().empty()) { p.baseParameter().push_back(icalendar_2_0::XlabelParamType(a.label())); } if (!a.uri().empty()) { attachment.uri(a.uri()); } else if (!a.data().empty()) { attachment.binary(base64_encode(reinterpret_cast(a.data().c_str()), static_cast(a.data().length()))); p.baseParameter().push_back(icalendar_2_0::EncodingParamType(BASE64)); } else { ERROR("no uri and no data"); } attachment.parameters(p); return attachment; } //==== cDateTime ==== std::string getTimezone(const icalendar_2_0::ArrayOfParameters ¶meters) { for (icalendar_2_0::DateDatetimePropertyType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) { if (const icalendar_2_0::TzidParamType* tz = dynamic_cast (&*it)) { std::string tzid = tz->text(); if (tzid.find(TZ_PREFIX) != std::string::npos) { tzid.erase(0, strlen(TZ_PREFIX)); } else { WARNING("/kolab.org/ timezone prefix is missing"); } return tzid; } } return std::string(); } cDateTimePtr toDate(const icalendar_2_0::DateDatetimePropertyType &dtProperty) { cDateTimePtr date; if (dtProperty.date_time()) { date = Shared::toDate(*dtProperty.date_time()); } else if (dtProperty.date()) { date = Shared::toDate(*dtProperty.date()); } if (dtProperty.parameters()) { const std::string &tzid = getTimezone(*dtProperty.parameters()); if (tzid.size()) { date->setTimezone(tzid); } } return date; } cDateTimePtr toDate(const icalendar_2_0::UtcDatetimePropertyType &dtProperty) { cDateTimePtr date; if (dtProperty.date_time()) { date = Shared::toDate(*dtProperty.date_time()); } else { //The utc-date-time element shouldn't even exist date = cDateTimePtr(new cDateTime()); ERROR("This element shouldn't even be existing"); //TODO Implement anyways? return date; } date->setUTC(true); return date; } template std::auto_ptr fromDate(const cDateTime &dt) { std::auto_ptr ptr(new I); if (dt.isDateOnly()) { ptr->date(Shared::fromDate(dt)); } else { ptr->date_time(Shared::fromDateTime(dt)); const std::string &timezone = dt.timezone(); if (timezone.size() != 0) { std::string tz(TZ_PREFIX); tz.append(timezone); icalendar_2_0::TzidParamType tzidParam(tz); icalendar_2_0::ArrayOfParameters parameters; parameters.baseParameter().push_back(tzidParam); ptr->parameters(parameters); } } return ptr; } template std::vector toDateTimeList(I datelistProperty) { std::vector list; std::string tzid; if (datelistProperty.parameters()) { tzid = getTimezone(*datelistProperty.parameters()); } if (!datelistProperty.date().empty()) { BOOST_FOREACH(const xml_schema::date &d, datelistProperty.date()) { list.push_back(*Shared::toDate(d)); } } else if (!datelistProperty.date_time().empty()) { BOOST_FOREACH(const xml_schema::date_time &d, datelistProperty.date_time()) { cDateTimePtr date = Shared::toDate(d); if (tzid.size()) { date->setTimezone(tzid); } list.push_back(*date); } } return list; } template std::auto_ptr fromDateTimeList(const std::vector &dtlist) { std::auto_ptr ptr(new I); BOOST_FOREACH(const cDateTime &dt, dtlist) { if (dt.isDateOnly()) { ptr->date().push_back(Shared::fromDate(dt)); } else { ptr->date_time().push_back(Shared::fromDateTime(dt)); } //TODO handle utc } if (!dtlist.empty() && !dtlist.at(0).timezone().empty()) { const std::string &timezone = dtlist.at(0).timezone(); if (timezone.size() != 0) { std::string tz(TZ_PREFIX); tz.append(timezone); icalendar_2_0::TzidParamType tzidParam(tz); icalendar_2_0::ArrayOfParameters parameters; parameters.baseParameter().push_back(tzidParam); ptr->parameters(parameters); } } return ptr; } //---- cDateTime ---- //=== Attendee === std::string mapPartStat(PartStatus status) { switch (status) { case PartAccepted: return PARTACCEPTED; case PartDeclined: return PARTDECLINED; case PartDelegated: return PARTDELEGATED; case PartNeedsAction: return PARTNEEDSACTION; case PartTentative: return PARTTENTATIVE; case PartInProcess: return PARTINPROCESS; case PartCompleted: return PARTCOMPLETED; } ERROR("PartStat not handled: " + status); return std::string(); } PartStatus mapPartStat(const std::string &status) { if (status == PARTACCEPTED) { return PartAccepted; } else if (status == PARTDECLINED) { return PartDeclined; } else if (status == PARTDELEGATED) { return PartDelegated; } else if (status == PARTNEEDSACTION) { return PartNeedsAction; } else if (status == PARTTENTATIVE) { return PartTentative; } else if (status == PARTINPROCESS) { return PartInProcess; } else if (status == PARTCOMPLETED) { return PartCompleted; } ERROR("PartStat not handled: " + status); return PartNeedsAction; } std::string mapRole(Role status) { switch (status) { case Chair: return std::string(CHAIR); case NonParticipant: return NONPARTICIPANT; case Optional: return OPTIONAL; case Required: return REQUIRED; } ERROR("PartStat not handled: " + status); return std::string(); } Role mapRole(const std::string &status) { if (status == CHAIR) { return Chair; } else if (status == NONPARTICIPANT) { return NonParticipant; } else if (status == OPTIONAL) { return Optional; } else if (status == REQUIRED) { return Required; } ERROR("Unhandled Role " + status); return Required; } //---------------- //=== Recurrence Rule === typedef std::auto_ptr RecurrencePtr; RecurrenceRule::Frequency mapRecurrenceFrequency(const icalendar_2_0::RecurType::freq_type &freq) { using namespace icalendar_2_0; switch (freq) { case FreqRecurType::YEARLY: return RecurrenceRule::Yearly; case FreqRecurType::MONTHLY: return RecurrenceRule::Monthly; case FreqRecurType::WEEKLY: return RecurrenceRule::Weekly; case FreqRecurType::DAILY: return RecurrenceRule::Daily; case FreqRecurType::HOURLY: return RecurrenceRule::Hourly; case FreqRecurType::MINUTELY: return RecurrenceRule::Minutely; case FreqRecurType::SECONDLY: return RecurrenceRule::Secondly; default: ERROR("invalid unhandled recurrenc type" + freq); } return RecurrenceRule::FreqNone; } icalendar_2_0::RecurType::freq_type mapRecurrenceFrequency(RecurrenceRule::Frequency freq) { using namespace icalendar_2_0; switch (freq) { case RecurrenceRule::Yearly: return FreqRecurType::YEARLY; case RecurrenceRule::Monthly: return FreqRecurType::MONTHLY; case RecurrenceRule::Weekly: return FreqRecurType::WEEKLY; case RecurrenceRule::Daily: return FreqRecurType::DAILY; case RecurrenceRule::Hourly: return FreqRecurType::HOURLY; case RecurrenceRule::Minutely: return FreqRecurType::MINUTELY; case RecurrenceRule::Secondly: return FreqRecurType::SECONDLY; default: ERROR("invalid unhandled recurrenc type"); } return 0; } static void setWeekStart(RecurrencePtr &r, const icalendar_2_0::RecurType::wkst_type &wkst) { using namespace icalendar_2_0; switch (wkst) { case WeekdayRecurType::MO: r->setWeekStart(Kolab::Monday); break; case WeekdayRecurType::TU: r->setWeekStart(Kolab::Tuesday); break; case WeekdayRecurType::WE: r->setWeekStart(Kolab::Wednesday); break; case WeekdayRecurType::TH: r->setWeekStart(Kolab::Thursday); break; case WeekdayRecurType::FR: r->setWeekStart(Kolab::Friday); break; case WeekdayRecurType::SA: r->setWeekStart(Kolab::Saturday); break; case WeekdayRecurType::SU: r->setWeekStart(Kolab::Sunday); break; default: ERROR("invalid unhandled weekday" + wkst); } } static void setByday(RecurrencePtr &r, const icalendar_2_0::RecurType::byday_sequence &list) { std::vector by; for (icalendar_2_0::RecurType::byday_const_iterator it(list.begin()); it != list.end(); it++) { by.push_back(toDayPos(*it)); } r->setByday(by); } template std::vector bylist(const xsd::cxx::tree::sequence &list) { std::vector by; BOOST_FOREACH(const T i, list) { by.push_back(convertToInt(i)); } return by; } RecurrencePtr toRRule(const icalendar_2_0::RecurType &rrule) { using namespace icalendar_2_0; RecurrencePtr r(new RecurrenceRule()); r->setFrequency(mapRecurrenceFrequency(rrule.freq())); if (rrule.until()) { cDateTimePtr date; if ((*rrule.until()).date_time()) { date = Shared::toDate(*(*rrule.until()).date_time()); } else if ((*rrule.until()).date()) { date = Shared::toDate(*(*rrule.until()).date()); } r->setEnd(*date); } else if (rrule.count()) { r->setCount(toInt(*rrule.count())); } if (rrule.interval()) { r->setInterval(toInt(*rrule.interval())); } else { r->setInterval(1); } r->setBysecond(bylist(rrule.bysecond())); r->setByminute(bylist(rrule.byminute())); r->setByhour(bylist(rrule.byhour())); setByday(r, rrule.byday()); r->setBymonthday(bylist(rrule.bymonthday())); r->setByyearday(bylist(rrule.byyearday())); r->setByweekno(bylist(rrule.byweekno())); r->setBymonth(bylist(rrule.bymonth())); if (rrule.wkst()) { setWeekStart(r, *rrule.wkst()); } return r; } //--- Recurrence Rule --- template void setIncidenceProperties(I &inc, const T &prop) { inc.setUid(toString(prop.uid())); inc.setCreated(*toDate(prop.created())); inc.setLastModified(*toDate(prop.dtstamp())); if (prop.sequence()) { inc.setSequence(toInt(*prop.sequence())); } if (prop.class_()) { std::string string(toString(*prop.class_())); Kolab::Classification sec = ClassPublic; if (string == PRIVATE) { sec = ClassPrivate; } else if (string == CONFIDENTIAL) { sec = ClassConfidential; } inc.setClassification(sec); } if (prop.categories()) { inc.setCategories(toStringList(*prop.categories())); } if (prop.dtstart()) { const cDateTimePtr date = toDate(*prop.dtstart()); inc.setStart(*date); } if (prop.summary()) { inc.setSummary(toString(*prop.summary())); } if (prop.description()) { inc.setDescription(toString(*prop.description())); } if (prop.comment()) { inc.setComment(toString(*prop.comment())); } if (prop.status()) { const std::string &status = toString(*prop.status()); if (status == NEEDSACTION) { inc.setStatus(StatusNeedsAction); } else if (status == COMPLETED || status == COMPLETED_COMPAT) { inc.setStatus(StatusCompleted); } else if (status == INPROCESS) { inc.setStatus(StatusInProcess); } else if (status == CANCELLED) { inc.setStatus(StatusCancelled); } else if (status == TENTATIVE) { inc.setStatus(StatusTentative); } else if (status == CONFIRMED) { inc.setStatus(StatusConfirmed); } else if (status == DRAFT) { inc.setStatus(StatusDraft); } else if (status == FINAL) { inc.setStatus(StatusFinal); } else { ERROR("Unhandled status"); } } if (prop.attendee().size()) { std::vector attendees; BOOST_FOREACH(typename T::attendee_type aProp, prop.attendee()) { Kolab::Attendee a; std::string name; if (aProp.parameters()) { const icalendar_2_0::AttendeePropType::parameters_type ¶meters = *aProp.parameters(); for (icalendar_2_0::AttendeePropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) { if (const icalendar_2_0::CnParamType * p = dynamic_cast (&*it)) { name = p->text(); } if (const icalendar_2_0::PartstatParamType * p = dynamic_cast (&*it)) { PartStatus s = mapPartStat(p->text()); if (s != PartNeedsAction) { a.setPartStat(s); } } if (const icalendar_2_0::RoleParamType * p = dynamic_cast (&*it)) { Role s = mapRole(p->text()); if (s != Required) { a.setRole(s); } } if (const icalendar_2_0::RsvpParamType * p = dynamic_cast (&*it)) { a.setRSVP(p->boolean()); } if (const icalendar_2_0::DelegatedToParamType * p = dynamic_cast (&*it)) { std::vector list; BOOST_FOREACH(const icalendar_2_0::CalAddressListParamType::cal_address_type &adr, p->cal_address()) { list.push_back(Shared::toContactReference(adr)); } a.setDelegatedTo(list); } if (const icalendar_2_0::DelegatedFromParamType * p = dynamic_cast (&*it)) { std::vector list; BOOST_FOREACH(const icalendar_2_0::CalAddressListParamType::cal_address_type &adr, p->cal_address()) { list.push_back(Shared::toContactReference(adr)); } a.setDelegatedFrom(list); } if (const icalendar_2_0::CutypeParamType * p = dynamic_cast (&*it)) { if (p->text() == RESOURCE) { a.setCutype(CutypeResource); } else if (p->text() == INDIVIDUAL) { a.setCutype(CutypeIndividual); } else if (p->text() == GROUP) { a.setCutype(CutypeGroup); } else if (p->text() == ROOM) { a.setCutype(CutypeGroup); } else if (p->text() == UNKNOWN) { a.setCutype(CutypeGroup); } else { WARNING("Invalid attendee cutype"); } } } } Kolab::ContactReference ref = toContactReference(aProp); a.setContact(ref); attendees.push_back(a); } inc.setAttendees(attendees); } if (prop.attach().size()) { std::vector attachments; BOOST_FOREACH(typename T::attach_type aProp, prop.attach()) { const Kolab::Attachment &a = toAttachment(aProp); if (!a.isValid()) { ERROR("invalid attachment"); continue; } attachments.push_back(a); } inc.setAttachments(attachments); } if (prop.x_custom().size()) { std::vector customProperties; BOOST_FOREACH(typename T::x_custom_type p, prop.x_custom()) { customProperties.push_back(CustomProperty(p.identifier(), p.value())); } inc.setCustomProperties(customProperties); } } template void setTodoEventProperties(I &inc, const T &prop) { if (prop.rrule()) { RecurrencePtr rrule = toRRule(prop.rrule()->recur()); inc.setRecurrenceRule(*rrule); } if (prop.rdate()) { inc.setRecurrenceDates(toDateTimeList(*prop.rdate())); if (!prop.rdate()->period().empty()) { ERROR("the period element must not be used, ignored."); } } if (prop.exdate()) { inc.setExceptionDates(toDateTimeList(*prop.exdate())); } if (prop.recurrence_id()) { bool thisandfuture = false; if (prop.recurrence_id()->parameters()) { const icalendar_2_0::RecurrenceIdPropType::parameters_type ¶meters = *prop.recurrence_id()->parameters(); for (icalendar_2_0::RecurrenceIdPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) { if (dynamic_cast (&*it)) { thisandfuture = true; } } } inc.setRecurrenceID(*toDate(*prop.recurrence_id()), thisandfuture); } if (prop.priority()) { inc.setPriority(toInt(*prop.priority())); } if (prop.location()) { inc.setLocation(toString(*prop.location())); } if (prop.organizer()) { inc.setOrganizer(toContactReference(*prop.organizer())); } if (prop.url()) { inc.setUrl((*prop.url()).uri()); } } template T fromList(const std::vector &input) { T list; BOOST_FOREACH(int i, input) { list.push_back(convertToInt(i)); } return list; } std::auto_ptr< icalendar_2_0::RrulePropType > recurrenceProperty(const RecurrenceRule &r) { using namespace icalendar_2_0; std::auto_ptr< RrulePropType > rruleProp(new RrulePropType(mapRecurrenceFrequency(r.frequency()))); RecurPropertyType::recur_type &recur = rruleProp->recur(); const cDateTime &endDate = r.end(); if (endDate.isValid()) { RecurPropertyType::recur_type::until_type until; if (endDate.isDateOnly()) { until.date(Shared::fromDate(endDate)); } else { until.date_time(Shared::fromDateTime(endDate)); } recur.until(until); } else if (r.count() > 0) { recur.count(fromInt(r.count())); } if (r.interval() > 1) { recur.interval(fromInt(r.interval())); } if (!r.bysecond().empty()) { recur.bysecond(fromList(r.bysecond())); } if (!r.byminute().empty()) { recur.byminute(fromList(r.byminute())); } if (!r.byhour().empty()) { recur.byhour(fromList(r.byhour())); } if (!r.byday().empty()) { RecurType::byday_sequence byday; const std::vector &l = r.byday(); BOOST_FOREACH(Kolab::DayPos daypos, l) { byday.push_back(fromDayPos(daypos)); } recur.byday(byday); } if (!r.bymonthday().empty()) { recur.bymonthday(fromList(r.bymonthday())); } if (!r.byyearday().empty()) { recur.byyearday(fromList(r.byyearday())); } if (!r.byweekno().empty()) { recur.byweekno(fromList(r.byweekno())); } if (!r.bymonth().empty()) { recur.bymonth(fromList(r.bymonth())); } return rruleProp; } template void getIncidenceProperties(T &prop, const I &inc) { using namespace icalendar_2_0; typedef T properties; prop.sequence(fromInt(inc.sequence())); switch (inc.classification()) { case Kolab::ClassConfidential: prop.class_(typename properties::class_type(CONFIDENTIAL)); break; case Kolab::ClassPrivate: prop.class_(typename properties::class_type(PRIVATE)); break; default: prop.class_(typename properties::class_type(PUBLIC)); break; } if (!inc.categories().empty()) { prop.categories(*fromStringList(inc.categories())); } if (inc.start().isValid()) { prop.dtstart(fromDate(inc.start())); } if (!inc.summary().empty()) { prop.summary(typename properties::summary_type(inc.summary())); } if (!inc.description().empty()) { prop.description(typename properties::description_type(inc.description())); } if (!inc.comment().empty()) { prop.comment(typename properties::comment_type(inc.comment())); } if (inc.status() != StatusUndefined) { switch (inc.status()) { case StatusNeedsAction: prop.status(typename properties::status_type(NEEDSACTION)); break; case StatusCompleted: prop.status(typename properties::status_type(COMPLETED)); break; case StatusInProcess: prop.status(typename properties::status_type(INPROCESS)); break; case StatusCancelled: prop.status(typename properties::status_type(CANCELLED)); break; case StatusTentative: prop.status(typename properties::status_type(TENTATIVE)); break; case StatusConfirmed: prop.status(typename properties::status_type(CONFIRMED)); break; case StatusDraft: prop.status(typename properties::status_type(DRAFT)); break; case StatusFinal: prop.status(typename properties::status_type(FINAL)); break; default: ERROR("unhandled status " + inc.status()); } } if (!inc.attendees().empty()) { const std::vector &l = inc.attendees(); BOOST_FOREACH(const Kolab::Attendee &a, l) { const Kolab::ContactReference &c = a.contact(); typename properties::attendee_type attendee = fromContactReference(c); typename properties::attendee_type::parameters_type &p = *attendee.parameters(); std::string stat = mapPartStat(a.partStat()); if (!stat.empty()) { p.baseParameter().push_back(icalendar_2_0::PartstatParamType(stat)); } std::string r = mapRole(a.role()); if (!r.empty()) { p.baseParameter().push_back(icalendar_2_0::RoleParamType(r)); } if (a.rsvp()) { p.baseParameter().push_back(icalendar_2_0::RsvpParamType(true)); } if (!a.delegatedTo().empty()) { icalendar_2_0::DelegatedToParamType delegatedTo; BOOST_FOREACH(const Kolab::ContactReference &ref, a.delegatedTo()) { delegatedTo.cal_address().push_back(CalAddressListParamType::cal_address_type(toMailto(ref.email(), ref.name()))); } p.baseParameter().push_back(delegatedTo); } if (!a.delegatedFrom().empty()) { icalendar_2_0::DelegatedFromParamType delegatedFrom; BOOST_FOREACH(const Kolab::ContactReference &ref, a.delegatedFrom()) { delegatedFrom.cal_address().push_back(CalAddressListParamType::cal_address_type(toMailto(ref.email(), ref.name()))); } p.baseParameter().push_back(delegatedFrom); } if (a.cutype() != CutypeIndividual) { std::string type; switch (a.cutype()) { case CutypeGroup: type = GROUP; break; case CutypeResource: type = RESOURCE; break; case CutypeRoom: type = ROOM; break; case CutypeUnknown: type = UNKNOWN; break; default: WARNING("unknown cutype"); type = INDIVIDUAL; break; } p.baseParameter().push_back(icalendar_2_0::CutypeParamType(type)); } prop.attendee().push_back(attendee); } } if (!inc.attachments().empty()) { const std::vector &l = inc.attachments(); BOOST_FOREACH(const Kolab::Attachment &a, l) { prop.attach().push_back(fromAttachment(a)); } } if (!inc.customProperties().empty()) { const std::vector &l = inc.customProperties(); BOOST_FOREACH(const Kolab::CustomProperty &a, l) { prop.x_custom().push_back(typename properties::x_custom_type(a.identifier, a.value)); } } } template void getTodoEventProperties(T &prop, const I &inc) { using namespace icalendar_2_0; typedef T properties; if (inc.recurrenceRule().isValid()) { const RecurrenceRule &r = inc.recurrenceRule(); prop.rrule(recurrenceProperty(r)); //TODO check if startdate is allDay if recurrence is allDay //TODO check if startdate matches the one of the event (it MUST) } if (!inc.recurrenceDates().empty()) { prop.rdate(fromDateTimeList(inc.recurrenceDates())); } if (!inc.exceptionDates().empty()) { prop.exdate(fromDateTimeList(inc.exceptionDates())); } if (inc.recurrenceID().isValid()) { std::auto_ptr recurrenceId = fromDate(inc.recurrenceID()); if (inc.thisAndFuture()) { if (!recurrenceId->parameters()) { recurrenceId->parameters(typename properties::recurrence_id_type::parameters_type()); } typename properties::recurrence_id_type::parameters_type ¶meters = *recurrenceId->parameters(); //There is maybe already a timezone set icalendar_2_0::RangeParamType range(THISANDFUTURE); parameters.baseParameter().push_back(range); } prop.recurrence_id(recurrenceId); } if (inc.priority() != 0) { prop.priority(typename properties::priority_type(fromInt(inc.priority()))); } if (!inc.location().empty()) { prop.location(typename properties::location_type(inc.location())); } if (inc.organizer().isValid()) { prop.organizer(fromContactReference(inc.organizer())); } if (!inc.url().empty()) { prop.url(typename properties::url_type(inc.url())); } } //=== Alarms === template void setAlarms(typename KolabType::components_type& components, const IncidenceType &incidence) { const std::vector &alarms = incidence.alarms(); BOOST_FOREACH(const Kolab::Alarm &alarm, alarms) { typedef icalendar_2_0::ValarmType::properties_type PropType; PropType::trigger_type trigger; if (alarm.start().isValid()) { if (!alarm.start().isUTC()) { ERROR("alarm start date is not UTC but MUST be UTC"); continue; } trigger.date_time(fromDateTime(alarm.start())); } else { if (!alarm.relativeStart().isValid()) { ERROR("no start and no relativeStart"); continue; } trigger.duration(PropType::trigger_type::duration_type(fromDuration(alarm.relativeStart()))); icalendar_2_0::ArrayOfParameters parameters; if (alarm.relativeTo() == Kolab::End) { parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(END)); } else { parameters.baseParameter().push_back(icalendar_2_0::RelatedParamType(START)); } trigger.parameters(parameters); } std::auto_ptr p; switch(alarm.type()) { case Kolab::Alarm::DisplayAlarm: p = std::auto_ptr(new PropType(PropType::action_type(DISPLAYALARM), trigger)); p->description(PropType::description_type(alarm.description())); break; case Kolab::Alarm::EMailAlarm: { p = std::auto_ptr(new PropType(PropType::action_type(EMAILALARM), trigger)); p->summary(PropType::summary_type(alarm.summary())); p->description(PropType::description_type(alarm.description())); const std::vector &l = alarm.attendees(); BOOST_FOREACH(const Kolab::ContactReference &attendee, l) { p->attendee().push_back(icalendar_2_0::ContactType(toMailto(attendee.email(), attendee.name()))); } break; } case Kolab::Alarm::AudioAlarm: p = std::auto_ptr(new PropType(PropType::action_type(AUDIOALARM), trigger)); p->description(PropType::description_type(alarm.description())); p->attach(fromAttachment(alarm.audioFile())); break; default: ERROR("invalid alarm"); continue; } if (alarm.duration().isValid()) { p->duration(PropType::duration_type(fromDuration(alarm.duration()))); p->repeat(PropType::repeat_type(fromInt(alarm.numrepeat()))); } components.valarm().push_back(icalendar_2_0::ValarmType(p)); } } template void getAlarms(IncidenceType &incidence, const typename KolabType::components_type &components) { typedef icalendar_2_0::ValarmType::properties_type PropType; std::vector alarms; BOOST_FOREACH(const typename KolabType::components_type::valarm_type &valarm, components.valarm()) { const icalendar_2_0::ValarmType::properties_type &prop = valarm.properties(); Kolab::Alarm alarm; if (prop.action().text() == DISPLAYALARM) { if (!prop.description()) { ERROR("description is missing"); continue; } alarm = Kolab::Alarm((*prop.description()).text()); } else if (prop.action().text() == EMAILALARM) { std::vector attendees; if (prop.attendee().empty()) { WARNING("No receipents for email alarm"); } for (typename PropType::attendee_const_iterator at(prop.attendee().begin()); at != prop.attendee().end(); at++) { std::string name; const std::string &email = fromMailto((*at).cal_address(), name); attendees.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, email, name)); } if (!prop.description() || !prop.summary()) { ERROR("description or summary is missing"); continue; } alarm = Kolab::Alarm((*prop.summary()).text(), (*prop.description()).text(), attendees); } else if (prop.action().text() == AUDIOALARM) { if (!prop.attach()) { ERROR("audio file is missing"); continue; } const Kolab::Attachment &attach = toAttachment(*prop.attach()); if (!attach.isValid()) { ERROR("audio file is invalid"); continue; } alarm = Kolab::Alarm(attach); } else { ERROR("unknown alarm type " + prop.action().text()); continue; } if (prop.trigger().date_time()) { alarm.setStart(*Shared::toDate(*prop.trigger().date_time())); if (!alarm.start().isUTC()) { ERROR("The start date time must be in UTC "); continue; } } else if (prop.trigger().duration()) { Kolab::Relative relativeTo = Kolab::Start; if (prop.trigger().parameters()) { BOOST_FOREACH(const icalendar_2_0::ArrayOfParameters::baseParameter_type ¶m, (*prop.trigger().parameters()).baseParameter()) { if (const icalendar_2_0::RelatedParamType *rel = dynamic_cast (¶m)) { if (rel->text() == START) { relativeTo = Kolab::Start; } else if (rel->text() == END) { relativeTo = Kolab::End; } else { LOG("relativeTo not specified, default to start "); } } } } alarm.setRelativeStart(toDuration(*prop.trigger().duration()), relativeTo); } else { ERROR("no duration and not starttime "); continue; } if (prop.duration()) { int repeat = 0; if (prop.repeat()) { repeat = toInt(*prop.repeat()); } alarm.setDuration(toDuration((*prop.duration()).duration()), repeat); //TODO check duration? } alarms.push_back(alarm); } incidence.setAlarms(alarms); } //--- Alarms --- ///Trait for incidence properties specialized for Event/Todo/Journal template struct IncidenceTrait; template < > struct IncidenceTrait { typedef icalendar_2_0::KolabEvent KolabType; typedef Kolab::Event IncidenceType; typedef boost::shared_ptr IncidencePtr; static void writeIncidence(icalendar_2_0::KolabEvent& vevent, const Kolab::Event &event) { KolabType::components_type eventComponents; setAlarms(eventComponents, event); if (!eventComponents.valarm().empty()) { vevent.components(eventComponents); } icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties(); getIncidenceProperties(prop, event); getTodoEventProperties(prop, event); if (event.end().isValid()) { prop.dtend(fromDate(event.end())); } else if (event.duration().isValid()) { prop.duration(icalendar_2_0::KolabEvent::properties_type::duration_type(fromDuration(event.duration()))); } if (event.transparency()) { prop.transp( icalendar_2_0::KolabEvent::properties_type::transp_type(TRANSPARENT)); } } static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabEvent inc) //TODO to base trait { components.vevent().push_back(inc); } static void readIncidence(Kolab::Event &event, const icalendar_2_0::KolabEvent& vevent) { const icalendar_2_0::KolabEvent::properties_type &prop = vevent.properties(); if (!prop.dtstart()) { ERROR("Start date is missing, but is mandatory for events"); } setIncidenceProperties(event, prop); setTodoEventProperties(event, prop); if (prop.dtend()) { event.setEnd(*toDate(*prop.dtend())); } else if (prop.duration()) { event.setDuration(toDuration((*prop.duration()).duration())); } if (prop.transp()) { if (toString(*prop.transp()) == TRANSPARENT) { event.setTransparency(true); } else { event.setTransparency(false); if (toString(*prop.transp()) != OPAQUE) { ERROR("wrong transparency value " + toString(*prop.transp())); } } } if (vevent.components()) { getAlarms(event, *vevent.components()); } } static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) { return components.vevent().begin(); } static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) { return components.vevent().end(); } static IncidencePtr resolveExceptions(const std::vector &list) { IncidencePtr incidence = *list.begin(); std::vector exceptions; for (std::vector < IncidencePtr >::const_iterator it = list.begin()+1; it != list.end(); it++) { exceptions.push_back(**it); } incidence->setExceptions(exceptions); return incidence; } static void addExceptions(icalendar_2_0::VcalendarType::components_type &components, const Kolab::Event &event, KolabType::properties_type props) { BOOST_FOREACH(const Kolab::Event &exception, event.exceptions()) { KolabType ex(props); writeIncidence(ex, exception); addIncidence(components, ex); } } }; template < > struct IncidenceTrait { typedef icalendar_2_0::KolabTodo KolabType; typedef Kolab::Todo IncidenceType; typedef boost::shared_ptr IncidencePtr; static void writeIncidence(icalendar_2_0::KolabTodo& vevent, const Kolab::Todo &todo) { KolabType::components_type eventComponents; setAlarms(eventComponents, todo); if (!eventComponents.valarm().empty()) { vevent.components(eventComponents); } icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties(); getIncidenceProperties(prop, todo); getTodoEventProperties(prop, todo); if (!todo.relatedTo().empty()) { icalendar_2_0::KolabTodo::properties_type::related_to_sequence list; const std::vector &l = todo.relatedTo(); BOOST_FOREACH(const std::string &relatedTo, l) { list.push_back(icalendar_2_0::KolabTodo::properties_type::related_to_type(relatedTo)); } prop.related_to(list); } if (todo.due().isValid()) { prop.due(fromDate(todo.due())); } if (todo.percentComplete() > 0) { prop.percent_complete(icalendar_2_0::KolabTodo::properties_type::percent_complete_type(fromInt(todo.percentComplete()))); } } static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabTodo inc) //TODO to base trait { components.vtodo().push_back(inc); } static void readIncidence(Kolab::Todo &todo, const icalendar_2_0::KolabTodo& vevent) { const icalendar_2_0::KolabTodo::properties_type &prop = vevent.properties(); setIncidenceProperties(todo, prop); setTodoEventProperties(todo, prop); if (!prop.related_to().empty()) { BOOST_FOREACH(icalendar_2_0::KolabTodo::properties_type::related_to_type p, prop.related_to()) { todo.addRelatedTo(p.text()); } } if (prop.due()) { todo.setDue(*toDate(*prop.due())); } if (prop.percent_complete()) { todo.setPercentComplete(toInt(*prop.percent_complete())); } if (vevent.components()) { getAlarms(todo, *vevent.components()); } } static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) { return components.vtodo().begin(); } static icalendar_2_0::VcalendarType::components_type::vevent_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) { return components.vtodo().end(); } static IncidencePtr resolveExceptions(const std::vector &list) { IncidencePtr incidence = *list.begin(); std::vector exceptions; for (std::vector < IncidencePtr >::const_iterator it = list.begin()+1; it != list.end(); it++) { exceptions.push_back(**it); } incidence->setExceptions(exceptions); return incidence; } static void addExceptions(icalendar_2_0::VcalendarType::components_type &components, const Kolab::Todo &event, KolabType::properties_type props) { BOOST_FOREACH(const Kolab::Todo &exception, event.exceptions()) { KolabType ex(props); writeIncidence(ex, exception); addIncidence(components, ex); } } }; template < > struct IncidenceTrait { typedef icalendar_2_0::KolabJournal KolabType; typedef Kolab::Journal IncidenceType; typedef boost::shared_ptr IncidencePtr; static void writeIncidence(icalendar_2_0::KolabJournal& vjournal, const Kolab::Journal &journal) { icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties(); getIncidenceProperties(prop, journal); } static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabJournal inc) { components.vjournal().push_back(inc); } static void readIncidence(Kolab::Journal &journal, const icalendar_2_0::KolabJournal& vjournal) { const icalendar_2_0::KolabJournal::properties_type &prop = vjournal.properties(); setIncidenceProperties(journal, prop); } static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) { return components.vjournal().begin(); } static icalendar_2_0::VcalendarType::components_type::vjournal_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) { return components.vjournal().end(); } static IncidencePtr resolveExceptions(const std::vector &list) { return *list.begin(); } static void addExceptions(icalendar_2_0::VcalendarType::components_type &, const Kolab::Journal &, KolabType::properties_type) { } }; template < > struct IncidenceTrait { typedef icalendar_2_0::KolabFreebusy KolabType; typedef Kolab::Freebusy IncidenceType; typedef boost::shared_ptr IncidencePtr; static void writeIncidence(icalendar_2_0::KolabFreebusy& vfreebusy, const Kolab::Freebusy &fb) { icalendar_2_0::KolabFreebusy::properties_type &prop = vfreebusy.properties(); if (fb.start().isValid() && fb.end().isValid()) { if ((fb.start().isUTC() || fb.start().isDateOnly()) && (fb.end().isUTC() || fb.end().isDateOnly())) { prop.dtstart(fromDate(fb.start())); prop.dtend(fromDate(fb.end())); } else { WARNING("Start/end is not in UTC, but it MUST be, skipping"); } } if (fb.organizer().isValid()) { prop.organizer(fromContactReference(fb.organizer())); } if (!fb.periods().empty()) { BOOST_FOREACH (const Kolab::FreebusyPeriod &fbPeriod, fb.periods()) { icalendar_2_0::KolabFreebusy::properties_type::freebusy_type fb; icalendar_2_0::BasePropertyType::parameters_type params; std::string fbtype; switch (fbPeriod.type()) { case FreebusyPeriod::Busy: fbtype = BUSY; break; case FreebusyPeriod::Tentative: fbtype = BUSY_TENTATIVE; break; case FreebusyPeriod::OutOfOffice: fbtype = BUSY_OUTOFOFFICE; break; case FreebusyPeriod::Invalid: default: WARNING("Invalid fb type"); continue; } params.baseParameter().push_back(icalendar_2_0::FbtypeParamType(fbtype)); if (!fbPeriod.eventUid().empty() || fbPeriod.eventSummary().empty() || fbPeriod.eventLocation().empty()) { params.baseParameter().push_back(icalendar_2_0::XFBevent(fbPeriod.eventUid(), fbPeriod.eventSummary(), fbPeriod.eventLocation())); } fb.parameters(params); BOOST_FOREACH (const Kolab::Period &period, fbPeriod.periods()) { if (period.start.isDateOnly() || period.end.isDateOnly()) { WARNING("Period is date-only but must be date-time"); continue; } if (!period.start.isUTC() || !period.end.isUTC()) { WARNING("Period is not in UTC, but it MUST be, skipping"); continue; } icalendar_2_0::PeriodType p(Shared::fromDateTime(period.start)); p.end(Shared::fromDateTime(period.end)); fb.period().push_back(p); } prop.freebusy().push_back(fb); } } } static void addIncidence(icalendar_2_0::VcalendarType::components_type &components, icalendar_2_0::KolabFreebusy inc) { components.vfreebusy().push_back(inc); } static void readIncidence(Kolab::Freebusy &freebusy, const icalendar_2_0::KolabFreebusy& vfreebusy) { const icalendar_2_0::KolabFreebusy::properties_type &prop = vfreebusy.properties(); freebusy.setUid(toString(prop.uid())); freebusy.setTimestamp(*toDate(prop.dtstamp())); if (prop.dtstart()) { freebusy.setStart(*toDate(*prop.dtstart())); } if (prop.dtend()) { freebusy.setEnd(*toDate(*prop.dtend())); } if (prop.organizer()) { freebusy.setOrganizer(toContactReference(*prop.organizer())); } if (!prop.freebusy().empty()) { std::vector fbperiods; BOOST_FOREACH(icalendar_2_0::FreebusyPropType aProp, prop.freebusy()) { Kolab::FreebusyPeriod fbPeriod; fbPeriod.setType(Kolab::FreebusyPeriod::Busy); if (aProp.parameters()) { const icalendar_2_0::FreebusyPropType::parameters_type ¶meters = *aProp.parameters(); for (icalendar_2_0::FreebusyPropType::parameters_type::baseParameter_const_iterator it(parameters.baseParameter().begin()); it != parameters.baseParameter().end(); it++) { if (const icalendar_2_0::FbtypeParamType * p = dynamic_cast (&*it)) { if (p->text() == BUSY) { fbPeriod.setType(Kolab::FreebusyPeriod::Busy); } else if (p->text() == BUSY_OUTOFOFFICE) { fbPeriod.setType(Kolab::FreebusyPeriod::OutOfOffice); } else if (p->text() == BUSY_TENTATIVE) { fbPeriod.setType(Kolab::FreebusyPeriod::Tentative); } else { WARNING("Invalid fb type, default to busy"); } } if (const icalendar_2_0::XFBevent * p = dynamic_cast (&*it)) { fbPeriod.setEvent(p->uid(), p->summary(), p->location()); } } } std::vector periods; BOOST_FOREACH(icalendar_2_0::FreebusyPropType::period_type period, aProp.period()) { if (!period.end()) { WARNING("Period end date is required and duration is not supported, skipping period"); continue; } periods.push_back(Kolab::Period(*Shared::toDate(period.start()), *Shared::toDate(*period.end()))); } fbPeriod.setPeriods(periods); fbperiods.push_back(fbPeriod); } freebusy.setPeriods(fbperiods); } } static icalendar_2_0::VcalendarType::components_type::vfreebusy_const_iterator begin(const icalendar_2_0::VcalendarType::components_type &components) { return components.vfreebusy().begin(); } static icalendar_2_0::VcalendarType::components_type::vfreebusy_const_iterator end(const icalendar_2_0::VcalendarType::components_type &components) { return components.vfreebusy().end(); } static IncidencePtr resolveExceptions(const std::vector &list) { return *list.begin(); } static void addExceptions(icalendar_2_0::VcalendarType::components_type &, const Kolab::Freebusy &, KolabType::properties_type) { } }; //////////////////////////////////========================================= template std::string serializeIncidence(const typename T::IncidenceType &incidence, const std::string productid = std::string()) { using namespace icalendar_2_0; typedef typename T::KolabType KolabType; try { typename KolabType::properties_type::uid_type uid( getUID(incidence.uid())); setCreatedUid(uid.text()); typename KolabType::properties_type::dtstamp_type dtstamp; if (incidence.lastModified().isValid()) { dtstamp.date_time(fromDateTime(incidence.lastModified())); } else { dtstamp.date_time(fromDateTime(timestamp())); } typename KolabType::properties_type::created_type created; if (incidence.created().isValid()) { created.date_time(fromDateTime(incidence.created())); } else { created.date_time(fromDateTime(timestamp())); } typename KolabType::properties_type eventProps(uid, created, dtstamp); KolabType inc(eventProps); T::writeIncidence(inc, incidence); VcalendarType::components_type components; T::addIncidence(components, inc); T::addExceptions(components, incidence, eventProps); VcalendarType::properties_type::prodid_type prodid(getProductId(productid)); VcalendarType::properties_type::version_type version(XCAL_VERSION); VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION); VcalendarType::properties_type properties(prodid, version, x_kolab_version); VcalendarType vcalendar(properties, components); IcalendarType icalendar(vcalendar); xml_schema::namespace_infomap map; map[""].name = XCAL_NAMESPACE; std::ostringstream ostringstream; icalendar_2_0::icalendar(ostringstream, icalendar, map); return ostringstream.str(); } catch (const xml_schema::exception& e) { CRITICAL("failed to write Incidence"); } catch (...) { CRITICAL("Unhandled exception"); } return std::string(); } template typename T::IncidencePtr deserializeIncidence(const std::string& s, bool isUrl) { using namespace icalendar_2_0; typedef typename T::IncidencePtr IncidencePtr; typedef typename T::IncidenceType IncidenceType; typedef typename T::KolabType KolabType; try { std::auto_ptr icalendar; if (isUrl) { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseFile(s); if (doc.get()) { icalendar = icalendar_2_0::icalendar(doc); } } else { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseString(s); if (doc.get()) { icalendar = icalendar_2_0::icalendar(doc); } } if (!icalendar.get()) { CRITICAL("Failed to parse calendar!"); return IncidencePtr(); } const icalendar_2_0::VcalendarType &vcalendar = icalendar->vcalendar(); std::vector < IncidencePtr > incidences; for (typename xsd::cxx::tree::sequence< KolabType >::const_iterator it(T::begin(vcalendar.components())); it != T::end(vcalendar.components()); it++) { IncidencePtr e = IncidencePtr(new IncidenceType); const KolabType &event = *it; T::readIncidence(*e, event); incidences.push_back(e); } setProductId( vcalendar.properties().prodid().text() ); setXCalVersion(vcalendar.properties().version().text()); setKolabVersion( vcalendar.properties().x_kolab_version().text() ); if (incidences.empty()) { CRITICAL("no incidence in object"); return IncidencePtr(); } return T::resolveExceptions(incidences); } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to read incidence!"); return IncidencePtr(); } template std::string serializeFreebusy(const Kolab::Freebusy &incidence, const std::string productid = std::string()) { using namespace icalendar_2_0; typedef typename T::KolabType KolabType; try { typename KolabType::properties_type::uid_type uid( getUID(incidence.uid())); setCreatedUid(uid.text()); typename KolabType::properties_type::dtstamp_type dtstamp; dtstamp.date_time(fromDateTime(timestamp())); typename KolabType::properties_type eventProps(uid, dtstamp); KolabType inc(eventProps); T::writeIncidence(inc, incidence); VcalendarType::components_type components; T::addIncidence(components, inc); VcalendarType::properties_type::prodid_type prodid(getProductId(productid)); VcalendarType::properties_type::version_type version(XCAL_VERSION); VcalendarType::properties_type::x_kolab_version_type x_kolab_version(KOLAB_FORMAT_VERSION); VcalendarType::properties_type properties(prodid, version, x_kolab_version); VcalendarType vcalendar(properties, components); IcalendarType icalendar(vcalendar); xml_schema::namespace_infomap map; map[""].name = XCAL_NAMESPACE; std::ostringstream ostringstream; icalendar_2_0::icalendar(ostringstream, icalendar, map); return ostringstream.str(); } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("failed to write Incidence"); return std::string(); } } }//Namespace #endif libkolabxml-1.1.2/src/xcardconversions.h000066400000000000000000001252011262531651400203530ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #ifndef KOLABXCARDCONVERSION_H #define KOLABXCARDCONVERSION_H #include #include #include #include #include #include #include "kolabcontainers.h" #include "global_definitions.h" #include "libkolabxml-version.h" #include "utils.h" #include "kolabcontact.h" #include "shared_conversions.h" namespace Kolab { namespace XCARD { const char* const XCARD_NAMESPACE = "urn:ietf:params:xml:ns:vcard-4.0"; const char* const INDIVIDUAL = "individual"; const char* const GROUP = "group"; const char* const MIME_PGP_KEYS = "application/pgp-keys"; const char* const MIME_PKCS7_MIME = "application/pkcs7-mime"; using namespace Kolab::Utils; template std::string getType(); template <> std::string getType() { return INDIVIDUAL; } template <> std::string getType() { return GROUP; } template xsd::cxx::tree::sequence fromList(const std::vector &input) { xsd::cxx::tree::sequence list; BOOST_FOREACH(const std::string &s, input) { list.push_back(T(s)); } return list; } template xsd::cxx::tree::sequence fromList(const std::vector &input, int preferredIndex) { xsd::cxx::tree::sequence list; int index = 0; BOOST_FOREACH(const std::string &s, input) { T im(s); if(preferredIndex == index) { typename T::parameters_type parameters; parameters.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value())); im.parameters(parameters); } index++; list.push_back(im); } return list; } template std::vector toUriList(const xsd::cxx::tree::sequence &input) { std::vector list; BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, input) { list.push_back(s.uri()); } return list; } template std::vector toTextList(const xsd::cxx::tree::sequence &input) { std::vector list; BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, input) { list.push_back(s.text()); } return list; } std::vector toStringList(const ::xsd::cxx::tree::sequence< ::xml_schema::string > &s) { std::vector d; std::copy(s.begin(), s.end(), std::back_inserter(d)); return d; } ::xsd::cxx::tree::sequence< ::xml_schema::string > fromStringList(const std::vector &s) { ::xsd::cxx::tree::sequence< ::xml_schema::string > d; std::copy(s.begin(), s.end(), std::back_inserter(d)); return d; } std::string fromDate(const cDateTime &dt) { if (!dt.isDateOnly()) { WARNING("fromDate called on date time value"); } std::stringstream s; s.fill('0'); s.width(4); s << dt.year(); s.width(2); s << dt.month(); s.width(2); s << dt.day(); return s.str(); } std::string fromDateTime(const cDateTime &dt) { std::stringstream s; s.fill('0'); s << std::right; s.width(4); s << dt.year(); s.width(2); s << dt.month(); s.width(2); s << dt.day(); s.width(1); if (dt.isDateOnly()) { return s.str(); } s << "T"; s.width(2); s << dt.hour(); s.width(2); s << dt.minute(); s.width(2); s << dt.second(); if (dt.isUTC()) { s << "Z"; } return s.str(); } cDateTime toDateTime(const std::string &input) { int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0; bool isUtc = false; try { year = boost::lexical_cast(input.substr(0, 4)); month = boost::lexical_cast(input.substr(4, 2)); day = boost::lexical_cast(input.substr(6, 2)); if (input.size() >= 15) { //Minimum for time if (input.at(8) != 'T') { ERROR("Wrong demiliter"); return cDateTime(); } hour = boost::lexical_cast(input.substr(9, 2)); minute = boost::lexical_cast(input.substr(11, 2)); second = boost::lexical_cast(input.substr(13, 2)); } else { if (input.size() >= 9) { ERROR("Invalid dt " + input); return cDateTime(); } return cDateTime(year, month, day); } if (input.size() >= 16) { if (input.at(15) == 'Z') { isUtc = true; } else { ERROR("wrong utc char? " + input.at(15)); return cDateTime(); } } } catch (boost::bad_lexical_cast &c) { ERROR("failed to convert: "+std::string(c.what())); return cDateTime(); } catch (...) { ERROR("failed to convert: unknown exception"); return cDateTime(); } return cDateTime(year, month, day, hour, minute, second, isUtc); } cDateTime toDateTime(const vcard_4_0::DateDatetimePropertyType &prop) { if (prop.date_time()) { return toDateTime(*prop.date_time()); } else if (prop.date()) { return toDateTime(*prop.date()); } ERROR("no date and no datetime"); return cDateTime(); } template T fromDateTime(const Kolab::cDateTime &dt) { T prop; if (dt.isDateOnly()) { prop.date(fromDate(dt)); } else { prop.date_time(fromDateTime(dt)); } return prop; } vcard_4_0::PrefTypeValueType fromCryptoPref(Kolab::Crypto::CryptoPref pref) { switch (pref) { case Kolab::Crypto::Always: return vcard_4_0::CryptoType::encryptpref_type::text_type::Always; case Kolab::Crypto::Ask: return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask; case Kolab::Crypto::IfPossible: return vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible; case Kolab::Crypto::Never: return vcard_4_0::CryptoType::encryptpref_type::text_type::Never; default: WARNING("unknown encrypt pref"); } return vcard_4_0::CryptoType::encryptpref_type::text_type::Ask; } Kolab::Crypto::CryptoPref toCryptoPref(vcard_4_0::PrefTypeValueType pref) { switch (pref) { case vcard_4_0::CryptoType::encryptpref_type::text_type::Always: return Kolab::Crypto::Always; case vcard_4_0::CryptoType::encryptpref_type::text_type::Ask: return Kolab::Crypto::Ask; case vcard_4_0::CryptoType::encryptpref_type::text_type::IfPossible: return Kolab::Crypto::IfPossible; case vcard_4_0::CryptoType::encryptpref_type::text_type::Never: return Kolab::Crypto::Never; default: WARNING("unknown encrypt pref"); } return Kolab::Crypto::Ask; } vcard_4_0::relatedPropType fromRelated(const Kolab::Related &r) { using namespace vcard_4_0; vcard_4_0::relatedPropType related; if (r.type() == Kolab::Related::Uid) { related.uri(r.uri()); } else { related.text(r.text()); } if (r.relationTypes() != Kolab::Related::NoRelation) { vcard::adr_type::parameters_type::baseParameter_sequence base; vcard::adr_type::parameters_type b; vcard_4_0::typeParamType::text_sequence seq; if (r.relationTypes() & Kolab::Related::Child) { seq.push_back(TypeValueType::child); } if (r.relationTypes() & Kolab::Related::Spouse) { seq.push_back(TypeValueType::spouse); } if (r.relationTypes() & Kolab::Related::Assistant) { seq.push_back(TypeValueType::x_assistant); } if (r.relationTypes() & Kolab::Related::Manager) { seq.push_back(TypeValueType::x_manager); } if (!seq.empty()) { vcard_4_0::typeParamType type; type.text(seq); b.baseParameter().push_back(type); } related.parameters(b); } return related; } Kolab::Related toRelated(const vcard_4_0::relatedPropType &r) { Kolab::Related::DescriptionType type = Kolab::Related::Invalid; std::string textOrUri; if (r.uri()) { type = Kolab::Related::Uid; textOrUri = *r.uri(); } else if (r.text()) { type = Kolab::Related::Text; textOrUri = *r.text(); } else { ERROR("no text and no uri"); return Kolab::Related(); } Kolab::Related related(type, textOrUri); if (r.parameters()) { BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type ¶m, (*r.parameters()).baseParameter()) { if (const vcard_4_0::typeParamType *rel = dynamic_cast (¶m)) { int types = 0; BOOST_FOREACH(const std::string &s, rel->text()) { if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::child)) { types |= Kolab::Related::Child; } if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::spouse)) { types |= Kolab::Related::Spouse; } if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_assistant)) { types |= Kolab::Related::Assistant; } if (s == vcard_4_0::TypeValueType(vcard_4_0::TypeValueType::x_manager)) { types |= Kolab::Related::Manager; } } related.setRelationTypes(types); } } } return related; } vcard_4_0::vcard::adr_type fromAddress(const Kolab::Address &address) { using namespace vcard_4_0; vcard::adr_type a(vcard::adr_type::pobox_type(std::string()/*address.pobox()*/), vcard::adr_type::ext_type(std::string()/*address.ext()*/), vcard::adr_type::street_type(address.street()), vcard::adr_type::locality_type(address.locality()), vcard::adr_type::region_type(address.region()), address.code(), vcard::adr_type::country_type(address.country()) ); vcard::adr_type::parameters_type b; if (address.types()) { vcard_4_0::typeParamType::text_sequence seq; if (address.types() & Kolab::Address::Home) { seq.push_back(TypeValueType::home); } if (address.types() & Kolab::Address::Work) { seq.push_back(TypeValueType::work); } if (!seq.empty()) { vcard_4_0::typeParamType type; type.text(seq); b.baseParameter().push_back(type); } } if (!address.label().empty()) { b.baseParameter().push_back(vcard_4_0::labelParamType(address.label())); } a.parameters(b); return a; } Kolab::Address toAddress(const vcard_4_0::vcard::adr_type &adr, bool *isPreferred = 0) { using namespace vcard_4_0; Address address; if (adr.parameters()) { BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type ¶m, (*adr.parameters()).baseParameter()) { if (const vcard_4_0::labelParamType *rel = dynamic_cast (¶m)) { address.setLabel(rel->text()); } else if (isPreferred && dynamic_cast (¶m)) { *isPreferred = true; } else if (const vcard_4_0::typeParamType *rel = dynamic_cast (¶m)) { int types = 0; BOOST_FOREACH(const std::string &s, rel->text()) { if (s == TypeValueType(TypeValueType::work)) { types |= Kolab::Telephone::Work; } if (s == TypeValueType(TypeValueType::home)) { types |= Kolab::Telephone::Home; } } address.setTypes(types); } } } address.setCode(adr.code()); address.setCountry(adr.country()); address.setLocality(adr.locality()); address.setRegion(adr.region()); address.setStreet(adr.street()); return address; } std::string toGeoUri(double lat, double lon) { //lexical_cast doesn't work, so we're using stringstream std::stringstream s; s << "geo:"; s.precision(15); //can't use std::numeric_limits::max_digits10 because that's c++ 0x, it should be 17, but that seems to cause rounding problems... no idea why. s << lat << ","; s.precision(15); //Needed to get the right precision somehow... s << lon; return s.str(); } bool fromGeoUri(const std::string &uri, double &lat, double &lon) { if (uri.substr(0,4) != std::string("geo:")) { WARNING("not a geo uri"); return false; } std::size_t pos1 = uri.find(","); if (pos1 == std::string::npos) { WARNING("not a valid geo uri"); return false; } lat = boost::lexical_cast(uri.substr(4, pos1-4)); lon = boost::lexical_cast(uri.substr(pos1+1, uri.size()-pos1-1)); return true; } template void writeCard(vcard_4_0::vcard &vcard, const T &); template <> void writeCard(vcard_4_0::vcard &vcard, const Kolab::Contact &contact) { using namespace vcard_4_0; if (!contact.categories().empty()) { vcard_4_0::vcard::categories_type cat; vcard_4_0::vcard::categories_type::text_sequence seq; const std::vector &l = contact.categories(); BOOST_FOREACH(const std::string &s, l) { seq.push_back(s); } cat.text(seq); vcard.categories(cat); } if (contact.nameComponents().isValid()) { const NameComponents &nc = contact.nameComponents(); vcard::n_type n; n.surname(fromStringList(nc.surnames())); n.given(fromStringList(nc.given())); n.additional(fromStringList(nc.additional())); n.prefix(fromStringList(nc.prefixes())); n.suffix(fromStringList(nc.suffixes())); vcard.n(n); } if (!contact.note().empty()) { vcard.note(vcard::note_type(contact.note())); } if (!contact.freeBusyUrl().empty()) { vcard.fburl(vcard::fburl_type(contact.freeBusyUrl())); } if (!contact.titles().empty()) { vcard.title(fromList(contact.titles())); } if (!contact.affiliations().empty()) { vcard::group_sequence affiliations; const std::vector &l = contact.affiliations(); BOOST_FOREACH(const Affiliation &a, l) { if (a == Affiliation()) { //skip empty ones LOG("skipped empty affiliation"); continue; } affiliationPropType::org_type org; org.text().push_back(a.organisation()); const std::vector &orgUnits = a.organisationalUnits(); BOOST_FOREACH(const std::string &unit, orgUnits) { org.text().push_back(unit); } vcard::group_type group(org); if (!a.logo().empty()) { group.logo(affiliationPropType::logo_type(uriInlineEncoding(a.logo(), a.logoMimetype()))); } group.role(fromList(a.roles())); const std::vector &relateds = a.relateds(); BOOST_FOREACH(const Related &rel, relateds) { group.related().push_back(fromRelated(rel)); } const std::vector
&addersses = a.addresses(); BOOST_FOREACH(const Address &adr, addersses) { group.adr().push_back(fromAddress(adr)); } affiliations.push_back(group); } vcard.group(affiliations); } if (!contact.urls().empty()) { vcard_4_0::vcard::url_sequence urls; const std::vector &l = contact.urls(); BOOST_FOREACH(const Kolab::Url &url, l) { vcard::url_type u(url.url()); if (url.type() == Kolab::Url::Blog) { vcard::adr_type::parameters_type b; vcard_4_0::typeParamType p; p.text().push_back(vcard_4_0::TypeValueType::x_blog); b.baseParameter().push_back(p); u.parameters(b); } urls.push_back(u); } vcard.url(urls); } if (!contact.addresses().empty()) { vcard::adr_sequence adrs; int index = 0; const std::vector
&l = contact.addresses(); BOOST_FOREACH(const Kolab::Address &address, l) { vcard::adr_type a = fromAddress(address); if(contact.addressPreferredIndex() == index) { if (a.parameters()) { (*a.parameters()).baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value())); } else { vcard::adr_type::parameters_type b; b.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value())); a.parameters(b); } } index++; adrs.push_back(a); } vcard.adr(adrs); } if (!contact.nickNames().empty()) { vcard::nickname_type::text_sequence textsequence; const std::vector &l = contact.nickNames(); BOOST_FOREACH(const std::string &s, l) { textsequence.push_back(s); } vcard::nickname_type nickName; nickName.text(textsequence); vcard.nickname(nickName); } if (!contact.relateds().empty()) { vcard::related_sequence seq; const std::vector &l = contact.relateds(); BOOST_FOREACH(const Kolab::Related &r, l) { seq.push_back(fromRelated(r)); } vcard.related(seq); } if (contact.bDay().isValid()) { Kolab::cDateTime dt = contact.bDay(); if (dt.isUTC() || !dt.timezone().empty()) { WARNING("Must be local time, local time assumed"); dt.setUTC(false); } vcard.bday(fromDateTime(dt)); } if (contact.anniversary().isValid()) { Kolab::cDateTime dt = contact.anniversary(); if (dt.isUTC() || !dt.timezone().empty()) { WARNING("Must be local time, local time assumed"); dt.setUTC(false); } vcard.anniversary(fromDateTime(dt)); } if (!contact.photo().empty()) { vcard::photo_type photo(vcard_4_0::UriPropertyType::uri_type(uriInlineEncoding(contact.photo(), contact.photoMimetype()))); vcard.photo(photo); } if (contact.gender() != Contact::NotSet) { switch (contact.gender()) { case Contact::NotSpecified: vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::empty)); break; case Contact::Male: vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::M)); break; case Contact::Female: vcard.gender(vcard::gender_type(vcard::gender_type::sex_type::F)); break; default: ERROR("Unhandled gender"); } } if (!contact.languages().empty()) { vcard.lang(fromList(contact.languages())); } if (!contact.telephones().empty()) { vcard::tel_sequence seq; int index = 0; const std::vector &l = contact.telephones(); BOOST_FOREACH(const Kolab::Telephone &t, l) { vcard::tel_type tel(t.number()); vcard_4_0::typeParamType telTypeParam; if (t.types() & Kolab::Telephone::Car) { telTypeParam.text().push_back(TypeValueType::x_car); } if (t.types() & Kolab::Telephone::Cell) { telTypeParam.text().push_back(TypeValueType::cell); } if (t.types() & Kolab::Telephone::Fax) { telTypeParam.text().push_back(TypeValueType::fax); } if (t.types() & Kolab::Telephone::Home) { telTypeParam.text().push_back(TypeValueType::home); } if (t.types() & Kolab::Telephone::Work) { telTypeParam.text().push_back(TypeValueType::work); } if (t.types() & Kolab::Telephone::Text) { telTypeParam.text().push_back(TypeValueType::text); } if (t.types() & Kolab::Telephone::Voice) { telTypeParam.text().push_back(TypeValueType::voice); } if (t.types() & Kolab::Telephone::Video) { telTypeParam.text().push_back(TypeValueType::video); } if (t.types() & Kolab::Telephone::Textphone) { telTypeParam.text().push_back(TypeValueType::textphone); } if (t.types() & Kolab::Telephone::Pager) { telTypeParam.text().push_back(TypeValueType::pager); } vcard::tel_type::parameters_type params; if(contact.telephonesPreferredIndex() == index) { params.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value())); } index++; if (!telTypeParam.text().empty()) { params.baseParameter().push_back(telTypeParam); tel.parameters(params); } seq.push_back(tel); } vcard.tel(seq); } if (!contact.imAddresses().empty()) { vcard.impp(fromList(contact.imAddresses(), contact.imAddressPreferredIndex())); } if (!contact.emailAddresses().empty()) { vcard::email_sequence seq; int index = 0; const std::vector &l = contact.emailAddresses(); BOOST_FOREACH(const Kolab::Email &e, l) { vcard::email_type email(e.address()); vcard_4_0::typeParamType emailTypeParam; if (e.types() & Kolab::Email::Home) { emailTypeParam.text().push_back(TypeValueType::home); } if (e.types() & Kolab::Email::Work) { emailTypeParam.text().push_back(TypeValueType::work); } vcard::tel_type::parameters_type params; if (!emailTypeParam.text().empty()) { params.baseParameter().push_back(emailTypeParam); } if(contact.emailAddressPreferredIndex() == index) { params.baseParameter().push_back(vcard_4_0::prefParamType(vcard_4_0::prefParamType::integer_default_value())); } index++; if (!params.baseParameter().empty()) { email.parameters(params); } seq.push_back(email); } vcard.email(seq); } if (!contact.gpsPos().empty()) { vcard_4_0::vcard::geo_sequence list; const std::vector &l = contact.gpsPos(); BOOST_FOREACH(const Kolab::Geo &g, l) { list.push_back(vcard_4_0::vcard::geo_type(toGeoUri(g.latitude, g.longitude))); } vcard.geo(list); } if (contact.crypto().isValid()) { vcard::x_crypto_type crypto; const Kolab::Crypto &c = contact.crypto(); if (c.allowed()) { vcard::x_crypto_type::allowed_type::text_sequence seq; if (c.allowed() & Kolab::Crypto::PGPinline) { seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE); } if (c.allowed() & Kolab::Crypto::PGPmime) { seq.push_back(vcard::x_crypto_type::allowed_type::text_type::PGP_MIME); } if (c.allowed() & Kolab::Crypto::SMIME) { seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIME); } if (c.allowed() & Kolab::Crypto::SMIMEopaque) { seq.push_back(vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque); } vcard::x_crypto_type::allowed_type allowed; allowed.text(seq); crypto.allowed(allowed); } crypto.encryptpref(fromCryptoPref(c.encryptPref())); crypto.signpref(fromCryptoPref(c.signPref())); vcard.x_crypto(crypto); } if (!contact.keys().empty()) { vcard_4_0::vcard::key_sequence keys; const std::vector &l = contact.keys(); BOOST_FOREACH (const Kolab::Key &k, l) { switch (k.type()) { case Kolab::Key::PGP: keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(k.key(), MIME_PGP_KEYS))); break; case Kolab::Key::PKCS7_MIME: keys.push_back(vcard_4_0::keyPropType(uriInlineEncoding(k.key(), MIME_PKCS7_MIME))); break; default: LOG("Unhandled/Invalid keytype"); break; } } if (!keys.empty()) { vcard.key(keys); } } } template <> void writeCard(vcard_4_0::vcard &vcard, const Kolab::DistList &distlist) { if (!distlist.members().empty()) { vcard_4_0::vcard::member_sequence members; const std::vector &l = distlist.members(); BOOST_FOREACH (const Kolab::ContactReference &m, l) { if (!m.uid().empty()) { members.push_back(vcard_4_0::vcard::member_type(Shared::toURN(m.uid()))); } else { members.push_back(vcard_4_0::vcard::member_type(Shared::toMailto(m.email(), m.name()))); } } vcard.member(members); } } template std::string serializeCard(const T &card, const std::string prod = std::string()) { using namespace vcard_4_0; clearErrors(); try { vcard_4_0::vcard::uid_type uid(Shared::toURN(getUID(card.uid()))); setCreatedUid(Shared::fromURN(uid.uri())); vcard_4_0::vcard::x_kolab_version_type kolab_version(KOLAB_FORMAT_VERSION); vcard_4_0::vcard::prodid_type prodid(getProductId(prod)); vcard_4_0::vcard::rev_type rev(fromDateTime(timestamp())); vcard_4_0::vcard::kind_type kind(getType()); vcard_4_0::vcard::fn_type fn(card.name()); vcard_4_0::vcard vcard(uid, kolab_version, prodid, rev, kind, fn); writeCard(vcard, card); if (!card.customProperties().empty()) { const std::vector &l = card.customProperties(); BOOST_FOREACH(const Kolab::CustomProperty &a, l) { vcard.x_custom().push_back(vcard_4_0::CustomType(a.identifier, a.value)); } } VcardsType vcards(vcard); xml_schema::namespace_infomap map; map[""].name = XCARD_NAMESPACE; std::ostringstream ostringstream; vcard_4_0::vcards(ostringstream, vcards, map); return ostringstream.str(); } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to write vcard!"); return std::string(); } template boost::shared_ptr readCard(const vcard_4_0::VcardsType::vcard_type &vcard); template <> boost::shared_ptr readCard (const vcard_4_0::VcardsType::vcard_type &vcard) { using namespace vcard_4_0; boost::shared_ptr contact(new Kolab::Contact); if (vcard.categories()) { contact->setCategories(toStringList((*vcard.categories()).text())); } if (vcard.n()) { NameComponents nc; nc.setSurnames(toStringList((*vcard.n()).surname())); nc.setGiven(toStringList((*vcard.n()).given())); nc.setPrefixes(toStringList((*vcard.n()).prefix())); nc.setSuffixes(toStringList((*vcard.n()).suffix())); nc.setAdditional(toStringList((*vcard.n()).additional())); contact->setNameComponents(nc); } if (vcard.note()) { contact->setNote((*vcard.note()).text()); } if (vcard.fburl()) { contact->setFreeBusyUrl((*vcard.fburl()).uri()); } if (!vcard.title().empty()) { contact->setTitles(toTextList(vcard.title())); } if (!vcard.group().empty()) { std::vector list; BOOST_FOREACH (const vcard::group_type &group, vcard.group()) { Kolab::Affiliation aff; if (!group.org().text().empty()) { aff.setOrganisation(*group.org().text().begin()); std::vector units; for ( vcard_4_0::NonEmptyTextListPropertyType::text_const_iterator it = ++group.org().text().begin(); it != group.org().text().end(); it++) { units.push_back(*it); } aff.setOrganisationalUnits(units); } else { WARNING("No org present"); } std::string mimetype; if (group.logo()) { const std::string &logo = uriInlineDecoding((*group.logo()).uri(), mimetype); aff.setLogo(logo, mimetype); } aff.setRoles(toTextList(group.role())); std::vector relateds; BOOST_FOREACH(const vcard::group_type::related_type &rel, group.related()) { relateds.push_back(toRelated(rel)); } aff.setRelateds(relateds); std::vector
addresses; BOOST_FOREACH(const vcard::group_type::adr_type &adr, group.adr()) { addresses.push_back(toAddress(adr)); } aff.setAddresses(addresses); list.push_back(aff); } contact->setAffiliations(list); } if (!vcard.url().empty()) { std::vector urls; BOOST_FOREACH(const vcard_4_0::vcard::url_type &url, vcard.url()) { if (url.parameters()) { //We have only one fixed parameter (x-blog) urls.push_back(Kolab::Url(url.uri(), Kolab::Url::Blog)); } else { urls.push_back(Kolab::Url(url.uri())); } } contact->setUrls(urls); } if (!vcard.adr().empty()) { std::vector list; int preferredIndex = -1; int index = 0; BOOST_FOREACH(const vcard::adr_type &adr, vcard.adr()) { bool isPreferred = false; const Kolab::Address &address = toAddress(adr, &isPreferred); if (isPreferred) { preferredIndex = index; } index++; list.push_back(address); } contact->setAddresses(list, preferredIndex); } if (vcard.nickname()) { contact->setNickNames(toTextList((*vcard.nickname()).text())); } if (!vcard.related().empty()) { std::vector list; BOOST_FOREACH(const vcard_4_0::vcard::related_type &r, vcard.related()) { list.push_back(toRelated(r)); } contact->setRelateds(list); } if (vcard.bday()) { contact->setBDay(toDateTime(*vcard.bday())); } if (vcard.anniversary()) { contact->setAnniversary(toDateTime(*vcard.anniversary())); } if (vcard.photo()) { std::string mimetype; const std::string decodedPhoto = uriInlineDecoding((*vcard.photo()).uri(), mimetype); contact->setPhoto(decodedPhoto, mimetype); } if (vcard.gender()) { if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::empty) { contact->setGender(Kolab::Contact::NotSpecified); } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::M) { contact->setGender(Kolab::Contact::Male); } else if ((*vcard.gender()).sex() == vcard::gender_type::sex_type::F) { contact->setGender(Kolab::Contact::Female); } } if (!vcard.lang().empty()) { std::vector list; BOOST_FOREACH(const vcard::lang_type l, vcard.lang()) { list.push_back(l.language_tag()); } contact->setLanguages(list); } if (!vcard.tel().empty()) { std::vector list; int preferredIndex = -1; int index = 0; BOOST_FOREACH(const vcard::tel_type &tel, vcard.tel()) { Kolab::Telephone telephone; if (tel.parameters()) { BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type ¶m, (*tel.parameters()).baseParameter()) { if (dynamic_cast (¶m)) { preferredIndex = index; } else if (const vcard_4_0::typeParamType *rel = dynamic_cast (¶m)) { int types = 0; BOOST_FOREACH(const std::string &s, rel->text()) { if (s == TypeValueType(TypeValueType::work)) { types |= Kolab::Telephone::Work; } if (s == TypeValueType(TypeValueType::home)) { types |= Kolab::Telephone::Home; } if (s == TypeValueType(TypeValueType::text)) { types |= Kolab::Telephone::Text; } if (s == TypeValueType(TypeValueType::voice)) { types |= Kolab::Telephone::Voice; } if (s == TypeValueType(TypeValueType::fax)) { types |= Kolab::Telephone::Fax; } if (s == TypeValueType(TypeValueType::cell)) { types |= Kolab::Telephone::Cell; } if (s == TypeValueType(TypeValueType::video)) { types |= Kolab::Telephone::Video; } if (s == TypeValueType(TypeValueType::pager)) { types |= Kolab::Telephone::Pager; } if (s == TypeValueType(TypeValueType::textphone)) { types |= Kolab::Telephone::Textphone; } if (s == TypeValueType(TypeValueType::x_car)) { types |= Kolab::Telephone::Car; } } telephone.setTypes(types); } } } index++; telephone.setNumber(tel.text()); list.push_back(telephone); } contact->setTelephones(list, preferredIndex); } if (!vcard.impp().empty()) { int preferredIndex = -1; std::vector list; int i = 0; BOOST_FOREACH(const vcard_4_0::UriPropertyType &s, vcard.impp()) { if (s.parameters()) { BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type ¶m, (*s.parameters()).baseParameter()) { if (dynamic_cast (¶m)) { preferredIndex = i; } } } i++; list.push_back(s.uri()); } contact->setIMaddresses(list, preferredIndex); } if (!vcard.email().empty()) { int preferredIndex = -1; std::vector list; int i = 0; BOOST_FOREACH(const vcard_4_0::TextPropertyType &s, vcard.email()) { Kolab::Email email; if (s.parameters()) { BOOST_FOREACH(const vcard_4_0::ArrayOfParameters::baseParameter_type ¶m, (*s.parameters()).baseParameter()) { if (dynamic_cast (¶m)) { preferredIndex = i; } else if (const vcard_4_0::typeParamType *rel = dynamic_cast (¶m)) { int types = 0; BOOST_FOREACH(const std::string &s, rel->text()) { if (s == TypeValueType(TypeValueType::work)) { types |= Kolab::Email::Work; } if (s == TypeValueType(TypeValueType::home)) { types |= Kolab::Email::Home; } } email.setTypes(types); } } } i++; email.setAddress(s.text()); list.push_back(email); } contact->setEmailAddresses(list, preferredIndex); } if (!vcard.geo().empty()) { std::vector list; BOOST_FOREACH(const vcard_4_0::geoPropType &s, vcard.geo()) { double lon = 0.0; double lat = 0.0; if (fromGeoUri(s.uri(), lat, lon)) { list.push_back(Kolab::Geo(lat, lon)); } } contact->setGPSpos(list); } if (vcard.x_crypto()) { const vcard_4_0::vcard::x_crypto_type &crypto = *vcard.x_crypto(); Kolab::Crypto c; if (crypto.allowed()) { int allowed = 0; BOOST_FOREACH(const vcard_4_0::vcard::x_crypto_type::allowed_type::text_type &m, crypto.allowed()->text()) { if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_INLINE) { allowed |= Kolab::Crypto::PGPinline; } else if (m == vcard::x_crypto_type::allowed_type::text_type::PGP_MIME) { allowed |= Kolab::Crypto::PGPmime; } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIME) { allowed |= Kolab::Crypto::SMIME; } else if (m == vcard::x_crypto_type::allowed_type::text_type::S_MIMEOpaque) { allowed |= Kolab::Crypto::SMIMEopaque; } else { WARNING("unknown allowed property"); } } c.setAllowed(allowed); } if (crypto.encryptpref()) { c.setEncryptPref(toCryptoPref(crypto.encryptpref()->text())); } if (crypto.signpref()) { c.setSignPref(toCryptoPref(crypto.signpref()->text())); } contact->setCrypto(c); } if (!vcard.key().empty()) { std::string mimetype; std::vector keys; BOOST_FOREACH(const vcard_4_0::keyPropType &k, vcard.key()) { const std::string &key = uriInlineDecoding(k.uri(), mimetype); if (mimetype == MIME_PGP_KEYS) { keys.push_back(Kolab::Key(key, Kolab::Key::PGP)); } else if (mimetype == MIME_PKCS7_MIME) { keys.push_back(Kolab::Key(key, Kolab::Key::PKCS7_MIME)); } else { WARNING("wrong mimetype on key"); } } contact->setKeys(keys); } return contact; } template <> boost::shared_ptr readCard (const vcard_4_0::VcardsType::vcard_type &vcard) { using namespace vcard_4_0; boost::shared_ptr distlist(new Kolab::DistList); if (!vcard.member().empty()) { std::vector members; BOOST_FOREACH(const vcard_4_0::vcard::member_type & m, vcard.member()) { members.push_back(Shared::toContactReference(m.uri())); } distlist->setMembers(members); } return distlist; } template boost::shared_ptr deserializeCard(const std::string& s, bool isUrl) { clearErrors(); try { std::auto_ptr vcards; if (isUrl) { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseFile(s); if (doc.get()) { vcards = vcard_4_0::vcards(doc); } } else { xsd::cxx::xml::dom::auto_ptr doc = XMLParserWrapper::inst().parseString(s); if (doc.get()) { vcards = vcard_4_0::vcards(doc); } } if (!vcards.get()) { CRITICAL("failed to parse card!"); return boost::shared_ptr(); } boost::shared_ptr card = readCard(vcards->vcard()); card->setUid(Shared::fromURN(vcards->vcard().uid().uri())); card->setName(vcards->vcard().fn().text()); card->setLastModified(toDateTime(vcards->vcard().rev().timestamp())); setProductId( vcards->vcard().prodid().text() ); // setFormatVersion( vcards->vcard().version().text() ); // global_xCardVersion = vcalendar.properties().version().text(); setKolabVersion( vcards->vcard().x_kolab_version().text() ); if (!vcards->vcard().x_custom().empty()) { std::vector customProperties; BOOST_FOREACH(const vcard_4_0::CustomType &p, vcards->vcard().x_custom()) { customProperties.push_back(CustomProperty(p.identifier(), p.value())); } card->setCustomProperties(customProperties); } return card; } catch (const xml_schema::exception& e) { std::cerr << e << std::endl; } catch (...) { CRITICAL("Unhandled exception"); } CRITICAL("Failed to read vcard!"); return boost::shared_ptr(); } } } //Namespace #endif libkolabxml-1.1.2/testfiles/000077500000000000000000000000001262531651400160225ustar00rootroot00000000000000libkolabxml-1.1.2/testfiles/testContactMinimalFromXML.xml000066400000000000000000000005651262531651400235610ustar00rootroot00000000000000 0123456789PyKolab Format XML Bindings2011-10-25T14:31:43.6044352011-10-25T14:31:43.605026publicvanmeeuwen@kolabsys.com libkolabxml-1.1.2/testfiles/testcontact.xml000066400000000000000000000046261262531651400211070ustar00rootroot00000000000000 uid 2004-05-04T15:00:00Z 2004-05-04T15:00:00Z public (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (date, no default) (date, no default) (string(attachment filename), default empty) (string, default empty) (string, default empty) (string, default empty) (string, no default) (string, default empty) (string, default empty) (string, default empty)
(string, default home) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty)
(string, default none) 3.23 5.222
libkolabxml-1.1.2/testfiles/testevent.xml000066400000000000000000000054461262531651400205760ustar00rootroot00000000000000 uid 2004-05-04T15:00:00Z 2004-05-04T15:00:00Z public (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (string, default empty) (number, no default) 1 (string, no default) 0 2 (string, no default> (date, no default) (string, default empty) (string, default empty) (string, default none) (bool, default true) (string, default required) (string, default busy) (string, default none) 2004-05-04T15:00:00Z 2004-05-04T15:00:00Z libkolabxml-1.1.2/testfiles/xcalCalendar.xml000066400000000000000000000107231262531651400211300ustar00rootroot00000000000000 -//Example Inc.//Example Client//EN 2.0 2004-01-10T03:28:45Z US/Eastern 2000-04-04T02:00:00 YEARLY 1SU 4 EDT -05:00 -04:00 2000-10-26T02:00:00 YEARLY -1SU 10 EST -04:00 -05:00 2006-02-06T00:11:21Z US/Eastern 2006-01-02T12:00:00 PT1H DAILY 5 US/Eastern 2006-01-02T15:00:00 PT2H Event #2 We are having a meeting all this week at 12 pm for one hour, with an additional meeting on the first day 2 hours long. Please bring your own lunch for the 12 pm meetings. 00959BC664CA650E933C892C@example.com 2006-02-06T00:11:21Z US/Eastern 2006-01-04T14:00:00 PT1H US/Eastern 2006-01-04T12:00:00 Event #2 bis 00959BC664CA650E933C892C@example.com libkolabxml-1.1.2/testfiles/xcalEvent.xml000066400000000000000000000014131262531651400204740ustar00rootroot00000000000000 GREGORIAN -//Example Inc.//Example Calendar//EN 2.0 2008-02-05T19:12:24Z 2008-10-06 Planning meeting 4088E990AD89CB3DBB484909 libkolabxml-1.1.2/tests/000077500000000000000000000000001262531651400151625ustar00rootroot00000000000000libkolabxml-1.1.2/tests/CMakeLists.txt000066400000000000000000000061111262531651400177210ustar00rootroot00000000000000 #### Qt 4 and 5 #### if(QT5_BUILD) find_package(ECM 1.1.0 REQUIRED NO_MODULE) set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH}) find_package(Qt5Core REQUIRED) find_package(Qt5Test REQUIRED) include_directories(${QT_INCLUDES}) # TODO: Port away from this. if(CMAKE_VERSION VERSION_LESS 2.8.9) message(FATAL_ERROR "Akonadi Qt 5 build requires at least CMake version 2.8.9") endif() if (Qt5_POSITION_INDEPENDENT_CODE) set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() set(QT_QTCORE_LIBRARY Qt5::Core) set(QT_QTTEST_LIBRARY Qt5::Test) else() set(QT_USE_IMPORTED_TARGETS TRUE) # Qt 4 only set(QT_MIN_VERSION 4.6.2) # Qt 4 only find_package(Qt4 REQUIRED) endif() add_definitions(-DTEST_DATA_PATH="${CMAKE_CURRENT_SOURCE_DIR}") include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/.. ) include_directories(${CMAKE_CURRENT_BINARY_DIR}) include_directories(${QT_INCLUDES} ${QT_INCLUDE_DIR}) if (NOT APPLE) set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--no-undefined" ) endif() if(PHP_BINDINGS) add_test(phptest php -d enable_dl=On -d include_path='.:/usr/share/pear:${CMAKE_BINARY_DIR}/src/php' -d extension=${CMAKE_BINARY_DIR}/src/php/kolabformat.so ${CMAKE_SOURCE_DIR}/src/php/test.php --verbose) endif() if (QT4_FOUND OR Qt5Core_FOUND) if (Qt5Core_FOUND) set(CMAKE_AUTOMOC ON) set(CMAKE_INCLUDE_CURRENT_DIR ON) endif() message("Buildings tests") if (QT4_FOUND) QT4_AUTOMOC(bindingstest.cpp) QT4_AUTOMOC(conversiontest.cpp) QT4_AUTOMOC(parsingtest.cpp) QT4_AUTOMOC(validationtest.cpp) QT4_AUTOMOC(kolabconversationtest.cpp) endif() add_executable(bindingstest bindingstest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${BINDINGSTEST_MOC}) target_link_libraries(bindingstest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C}) add_test(bindingstest ${CMAKE_CURRENT_BINARY_DIR}/bindingstest) add_executable(conversiontest conversiontest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${CONVERSIONTEST_MOC}) target_link_libraries(conversiontest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C}) add_test(conversiontest ${CMAKE_CURRENT_BINARY_DIR}/conversiontest) add_executable(parsingtest parsingtest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${PARSINGTEST_MOC}) target_link_libraries(parsingtest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C}) add_test(parsingtest ${CMAKE_CURRENT_BINARY_DIR}/parsingtest) add_executable(validationtest validationtest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${VALIDATIONTEST_MOC}) target_link_libraries(validationtest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C}) add_test(validationtest ${CMAKE_CURRENT_BINARY_DIR}/validationtest) add_executable(kolabconversationtest kolabconversationtest.cpp ${CMAKE_CURRENT_BINARY_DIR}/${KOLABCONVERSATIONTEST_MOC}) target_link_libraries(kolabconversationtest ${QT_QTTEST_LIBRARY} ${QT_QTCORE_LIBRARY} kolabxml ${XERCES_C}) add_test(kolabconversationtest ${CMAKE_CURRENT_BINARY_DIR}/kolabconversationtest) else() message(WARNING "Could not build tests because qt is missing") endif() libkolabxml-1.1.2/tests/bindingstest.cpp000066400000000000000000001021741262531651400203700ustar00rootroot00000000000000#include "bindingstest.h" #include #include #include "bindings/iCalendar-props.hxx" #include "bindings/iCalendar-valtypes.hxx" #include "bindings/kolabformat.hxx" #include #include #include #include // #include #include #include #include "serializers.h" #include #include "src/containers/kolabjournal.h" #include "libkolabxml-version.h" void BindingsTest::categorycolorConfigurationCompletness() { Kolab::CategoryColor color("name"); color.setColor("color"); std::vector entries; entries.push_back(color); color.setSubcategories(entries); entries.push_back(color); color.setSubcategories(entries); entries.push_back(color); Kolab::Configuration configuration(entries); configuration.setUid("uid"); configuration.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC configuration.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC const std::string &result = Kolab::writeConfiguration(configuration); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::Configuration &re = Kolab::readConfiguration(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), configuration.uid()); QCOMPARE(re.created(), configuration.created()); QCOMPARE(re.lastModified(), configuration.lastModified()); QCOMPARE(re.type(), Kolab::Configuration::TypeCategoryColor); QCOMPARE(re.categoryColor(), entries); } void BindingsTest::dictionaryConfigurationCompletness() { Kolab::Dictionary dict("en"); std::vector entries; entries.push_back("entry1"); entries.push_back("entry2"); entries.push_back("entry3"); dict.setEntries(entries); Kolab::Configuration configuration(dict); configuration.setUid("uid"); configuration.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC configuration.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC const std::string &result = Kolab::writeConfiguration(configuration); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::Configuration &re = Kolab::readConfiguration(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), configuration.uid()); QCOMPARE(re.created(), configuration.created()); QCOMPARE(re.lastModified(), configuration.lastModified()); QCOMPARE(re.type(), Kolab::Configuration::TypeDictionary); QCOMPARE(re.dictionary(), dict); } void BindingsTest::snippetConfigurationCompletness() { std::vector list; Kolab::Snippet snippet1("name1", "text1"); snippet1.setShortCut("shrtct1"); list.push_back(snippet1); Kolab::Snippet snippet2("name1", "text1"); snippet2.setTextType(Kolab::Snippet::HTML); list.push_back(snippet2); Kolab::SnippetsCollection snippets("collectionname"); snippets.setSnippets(list); Kolab::Configuration configuration(snippets); configuration.setUid("uid"); configuration.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC configuration.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC const std::string &result = Kolab::writeConfiguration(configuration); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::Configuration &re = Kolab::readConfiguration(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), configuration.uid()); QCOMPARE(re.created(), configuration.created()); QCOMPARE(re.lastModified(), configuration.lastModified()); QCOMPARE(re.type(), Kolab::Configuration::TypeSnippet); QCOMPARE(re.snippets(), snippets); } void BindingsTest::relationConfigurationCompletness() { Kolab::Relation relation("name1", "type1"); relation.setColor("color"); relation.setIconName("icon"); relation.setParent("parent"); relation.setPriority(3); std::vector members; members.push_back("member1"); members.push_back("member2"); relation.setMembers(members); Kolab::Configuration configuration(relation); configuration.setUid("uid"); configuration.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC configuration.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC const std::string &result = Kolab::writeConfiguration(configuration); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::Configuration &re = Kolab::readConfiguration(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), configuration.uid()); QCOMPARE(re.created(), configuration.created()); QCOMPARE(re.lastModified(), configuration.lastModified()); QCOMPARE(re.type(), Kolab::Configuration::TypeRelation); QCOMPARE(re.relation(), relation); } void BindingsTest::fileDriverConfigurationCompletness() { Kolab::FileDriver fileDriver("driver", "title"); fileDriver.setEnabled(false); fileDriver.setHost("host"); fileDriver.setPort(9); fileDriver.setUsername("username"); fileDriver.setPassword("password"); Kolab::Configuration configuration(fileDriver); configuration.setUid("uid"); configuration.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC configuration.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC const std::string &result = Kolab::writeConfiguration(configuration); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::Configuration &re = Kolab::readConfiguration(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), configuration.uid()); QCOMPARE(re.created(), configuration.created()); QCOMPARE(re.lastModified(), configuration.lastModified()); QCOMPARE(re.type(), Kolab::Configuration::TypeFileDriver); QCOMPARE(re.fileDriver(), fileDriver); } void BindingsTest::noteCompletness() { Kolab::Note note; note.setUid("UID"); note.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC note.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC note.setClassification(Kolab::ClassConfidential); note.addCategory("Category"); note.setSummary("summary"); note.setDescription("description"); note.setColor("color"); std::vector attachments; Kolab::Attachment attachment; attachment.setData("data", "mimetype"); attachment.setLabel("label"); attachments.push_back(attachment); Kolab::Attachment attachment2; attachment2.setUri("data", "mimetype"); attachment2.setLabel("label2"); attachments.push_back(attachment2); note.setAttachments(attachments); const std::string &result = Kolab::writeNote(note); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::Note &re = Kolab::readNote(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), note.uid()); QCOMPARE(re.created(), note.created()); QCOMPARE(re.lastModified(), note.lastModified()); QCOMPARE(re.classification(), note.classification()); QCOMPARE(re.categories(), note.categories()); QCOMPARE(re.summary(), note.summary()); QCOMPARE(re.description(), note.description()); QCOMPARE(re.color(), note.color()); QCOMPARE(re.attachments(), note.attachments()); } void BindingsTest::fileCompletness() { Kolab::File file; file.setUid("UID"); file.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC file.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC file.setClassification(Kolab::ClassConfidential); file.addCategory("Category"); file.setNote("summary"); Kolab::Attachment attachment; attachment.setData("data", "mimetype"); attachment.setLabel("label"); file.setFile(attachment); const std::string &result = Kolab::writeFile(file); QCOMPARE(Kolab::error(), Kolab::NoError); // std::cout << result << std::endl; const Kolab::File &re = Kolab::readFile(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); QCOMPARE(re.uid(), file.uid()); QCOMPARE(re.created(), file.created()); QCOMPARE(re.lastModified(), file.lastModified()); QCOMPARE(re.classification(), file.classification()); QCOMPARE(re.categories(), file.categories()); QCOMPARE(re.note(), file.note()); QCOMPARE(re.file(), file.file()); } // void BindingsTest::eventCompletness_data() template void setIncidence(T &ev) { ev.setUid("UID"); ev.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC ev.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC ev.setSequence(1); ev.setClassification(Kolab::ClassConfidential); ev.addCategory("Category"); ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0)); Kolab::RecurrenceRule rule; rule.setFrequency(Kolab::RecurrenceRule::Daily); rule.setCount(5); std::vector list; list.push_back(1); list.push_back(3); rule.setBysecond(list); rule.setByminute(list); rule.setByhour(list); std::vector byday; byday.push_back(Kolab::DayPos(15, Kolab::Friday)); byday.push_back(Kolab::DayPos(0, Kolab::Monday)); byday.push_back(Kolab::DayPos(-3, Kolab::Monday)); rule.setByday(byday); rule.setBymonthday(list); rule.setByyearday(list); rule.setByweekno(list); rule.setBymonth(list); ev.setRecurrenceRule(rule); ev.addRecurrenceDate(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0)); ev.addExceptionDate(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0)); ev.setRecurrenceID(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0), true); ev.setSummary("summary"); ev.setDescription("description"); ev.setComment("comment"); ev.setPriority(3); ev.setStatus(Kolab::StatusConfirmed); ev.setLocation("location"); ev.setOrganizer(Kolab::ContactReference("mail", "name", "uid")); ev.setUrl("http://example.com"); Kolab::Attendee attendee(Kolab::ContactReference("mail", "name", "uid")); attendee.setPartStat(Kolab::PartDelegated); attendee.setRole(Kolab::Chair); attendee.setRSVP(true); std::vector reflist; reflist.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name")); reflist.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail2", "name2")); attendee.setDelegatedTo(reflist); attendee.setDelegatedFrom(reflist); attendee.setCutype(Kolab::CutypeResource); ev.setAttendees(std::vector() << attendee << attendee); std::vector attachments; Kolab::Attachment attach; attach.setData("data????*?*?*?*?*?", "mimetype"); attach.setLabel("label"); attachments.push_back(attach); Kolab::Attachment attach2; attach2.setUri(TEST_DATA_PATH "/testfiles/icalEvent.xml", "mimetype"); attach2.setLabel("labe2l"); attachments.push_back(attach2); Kolab::Attachment attach3; using namespace std; ifstream file (TEST_DATA_PATH "/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate); if (file.is_open()) { int size = file.tellg(); char *memblock = new char [size]; file.seekg (0, ios::beg); file.read (memblock, size); file.close(); attach3.setData(string(memblock, size), "mimetype"); delete[] memblock; } else { qWarning() << "Testfile not found"; } attach3.setLabel("labe3l"); attachments.push_back(attach3); ev.setAttachments(attachments); std::vector properties; properties.push_back(Kolab::CustomProperty("ident", "value")); properties.push_back(Kolab::CustomProperty("ident", "value")); ev.setCustomProperties(properties); std::vector alarms; // Kolab::Alarm dispAlarm("ident"); // dispAlarm.setRelativeStart(Kolab::Duration(3, true), Kolab::Start); // alarms.push_back(dispAlarm); std::vector att; att.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name")); att.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name")); Kolab::Alarm emailAlarm("ident", "value", att); emailAlarm.setStart(Kolab::cDateTime(2003,2,3,2,3,4, true)); alarms.push_back(emailAlarm); // Kolab::Attachment audiofile; // audiofile.setUri("ksdjlksdflj", "sdkljdfl"); // Kolab::Alarm audio(audiofile); // audio.setStart(Kolab::cDateTime(2003,2,3,2,3,4, true)); // alarms.push_back(audio); ev.setAlarms(alarms); } template void checkIncidence(const T &ev, const T &re) { //Common to all QCOMPARE(ev.uid(), re.uid()); QCOMPARE(ev.created(), re.created()); QCOMPARE(ev.lastModified(), re.lastModified()); QCOMPARE(ev.sequence(), re.sequence()); QCOMPARE(ev.classification(), re.classification()); QCOMPARE(ev.categories(), re.categories()); QCOMPARE(ev.start(), re.start()); //Recurrence const Kolab::RecurrenceRule &r1 = ev.recurrenceRule(); const Kolab::RecurrenceRule &r2 = re.recurrenceRule(); QCOMPARE(r1.isValid(), r2.isValid()); QCOMPARE(r1.frequency(), r2.frequency()); QCOMPARE(r1.interval(), r2.interval()); QCOMPARE(r1.weekStart(), r2.weekStart()); QCOMPARE(r1.count(), r2.count()); QCOMPARE(r1.end(), r2.end()); QCOMPARE(r1.bysecond(), r2.bysecond()); QCOMPARE(r1.byminute(), r2.byminute()); QCOMPARE(r1.byhour(), r2.byhour()); QCOMPARE(r1.byday(), r2.byday()); QCOMPARE(r1.bymonthday(), r2.bymonthday()); QCOMPARE(r1.byyearday(), r2.byyearday()); QCOMPARE(r1.byweekno(), r2.byweekno()); QCOMPARE(r1.bymonth(), r2.bymonth()); //Rest QCOMPARE(ev.recurrenceDates(), re.recurrenceDates()); QCOMPARE(ev.exceptionDates(), re.exceptionDates()); QCOMPARE(ev.recurrenceID(), re.recurrenceID()); QCOMPARE(ev.thisAndFuture(), re.thisAndFuture()); QCOMPARE(ev.summary(), re.summary()); QCOMPARE(ev.description(), re.description()); QCOMPARE(ev.comment(), re.comment()); QCOMPARE(ev.priority(), re.priority()); QCOMPARE(ev.status(), re.status()); QCOMPARE(ev.location(), re.location()); QCOMPARE(ev.organizer(), re.organizer()); QCOMPARE(ev.url(), re.url()); QCOMPARE(ev.attendees(), re.attendees()); QCOMPARE(ev.attachments(), re.attachments()); QCOMPARE(ev.customProperties(), re.customProperties()); QCOMPARE(ev.alarms(), re.alarms()); } void BindingsTest::eventCompletness() { Kolab::Event ev; setIncidence(ev); ev.setEnd(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0)); ev.setTransparency(true); std::string result = Kolab::writeEvent(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Event e = Kolab::readEvent(result, false); QVERIFY(Kolab::error() == Kolab::NoError); checkIncidence(ev, e); QCOMPARE(ev.end(), e.end()); QCOMPARE(ev.transparency(), e.transparency()); } void BindingsTest::eventDuration() { Kolab::Event ev; ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0)); ev.setDuration(Kolab::Duration(11,22,33,44, true)); const std::string result = Kolab::writeEvent(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; const Kolab::Event e = Kolab::readEvent(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QVERIFY(ev.duration().isValid()); QCOMPARE(ev.duration(), e.duration()); } void BindingsTest::eventExceptions() { Kolab::Event ev; ev.setUid("uid1"); ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0)); std::vector exceptions; Kolab::Event ex1; ex1.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0)); ex1.setUid("uid1"); ex1.setRecurrenceID(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0), true); exceptions.push_back(ex1); Kolab::Event ex2; ex2.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0)); ex2.setUid("uid1"); ex2.setRecurrenceID(Kolab::cDateTime("Europe/Zurich", 2007,1,8,12,0,0), false); exceptions.push_back(ex2); ev.setExceptions(exceptions); const std::string result = Kolab::writeEvent(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; const Kolab::Event e = Kolab::readEvent(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(e.exceptions().size(), std::size_t(2)); QCOMPARE(ev.exceptions().at(0).uid(), e.exceptions().at(0).uid()); QCOMPARE(ev.exceptions().at(0).recurrenceID(), e.exceptions().at(0).recurrenceID()); QCOMPARE(ev.exceptions().at(1).uid(), e.exceptions().at(1).uid()); QCOMPARE(ev.exceptions().at(1).recurrenceID(), e.exceptions().at(1).recurrenceID()); } void BindingsTest::todoCompletness() { Kolab::Todo ev; setIncidence(ev); ev.setDue(Kolab::cDateTime("Europe/Zurich", 2006,1,8,12,0,0)); ev.addRelatedTo("rel1"); ev.addRelatedTo("rel2"); ev.setPercentComplete(50); std::string result = Kolab::writeTodo(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Todo e = Kolab::readTodo(result, false); QVERIFY(Kolab::error() == Kolab::NoError); checkIncidence(ev, e); QCOMPARE(ev.due(), e.due()); QCOMPARE(ev.relatedTo(), e.relatedTo()); QCOMPARE(ev.percentComplete(), e.percentComplete()); } void BindingsTest::dueDateDateOnly() { Kolab::Todo ev; ev.setDue(Kolab::cDateTime(2006,1,8)); std::string result = Kolab::writeTodo(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Todo e = Kolab::readTodo(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(ev.due(), e.due()); } void BindingsTest::journalCompletness() { Kolab::Journal ev; ev.setUid("UID"); ev.setCreated(Kolab::cDateTime(2006,1,6,12,0,0,true)); //UTC ev.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0,true)); ev.setSequence(1); ev.setClassification(Kolab::ClassConfidential); ev.addCategory("Category"); ev.setStart(Kolab::cDateTime("Europe/Zurich", 2006,1,6,12,0,0)); Kolab::Attendee attendee(Kolab::ContactReference("mail", "name", "uid")); attendee.setPartStat(Kolab::PartDelegated); attendee.setRole(Kolab::Chair); attendee.setRSVP(true); std::vector reflist; reflist.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name")); reflist.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail2", "name2")); attendee.setDelegatedTo(reflist); attendee.setDelegatedFrom(reflist); attendee.setCutype(Kolab::CutypeResource); ev.setAttendees(std::vector() << attendee << attendee); std::vector attachments; Kolab::Attachment attach; attach.setData("data????*?*?*?*?*?", "mimetype"); attach.setLabel("label"); attachments.push_back(attach); Kolab::Attachment attach2; attach2.setUri(TEST_DATA_PATH "/testfiles/icalEvent.xml", "mimetype"); attach2.setLabel("labe2l"); attachments.push_back(attach2); Kolab::Attachment attach3; using namespace std; ifstream file (TEST_DATA_PATH "/testfiles/icalEvent.xml", ios::in|ios::binary|ios::ate); if (file.is_open()) { int size = file.tellg(); char *memblock = new char [size]; file.seekg (0, ios::beg); file.read (memblock, size); file.close(); attach3.setData(string(memblock, size), "mimetype"); delete[] memblock; } else { qWarning() << "Testfile not found"; } attach3.setLabel("labe3l"); attachments.push_back(attach3); ev.setAttachments(attachments); std::vector properties; properties.push_back(Kolab::CustomProperty("ident", "value")); properties.push_back(Kolab::CustomProperty("ident", "value")); ev.setCustomProperties(properties); std::string result = Kolab::writeJournal(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Journal re = Kolab::readJournal(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(ev.uid(), re.uid()); QCOMPARE(ev.created(), re.created()); QCOMPARE(ev.lastModified(), re.lastModified()); QCOMPARE(ev.sequence(), re.sequence()); QCOMPARE(ev.classification(), re.classification()); QCOMPARE(ev.categories(), re.categories()); QCOMPARE(ev.start(), re.start()); QCOMPARE(ev.summary(), re.summary()); QCOMPARE(ev.description(), re.description()); QCOMPARE(ev.status(), re.status()); QCOMPARE(ev.attendees(), re.attendees()); QCOMPARE(ev.attachments(), re.attachments()); QCOMPARE(ev.customProperties(), re.customProperties()); } void BindingsTest::freebusyCompletness() { Kolab::Freebusy ev; ev.setUid("UID"); ev.setTimestamp(Kolab::cDateTime(2006,1,6,12,0,0, true)); ev.setStart(Kolab::cDateTime(2006,1,6,12,0,0, true)); ev.setEnd(Kolab::cDateTime(2006,1,6,12,0,0, true)); ev.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name")); std::vector fbperiods; Kolab::FreebusyPeriod fbp; fbp.setType(Kolab::FreebusyPeriod::OutOfOffice); fbp.setEvent("summary", "uid", "location"); std::vector periods; periods.push_back(Kolab::Period(Kolab::cDateTime(2006,1,6,12,0,0, true),Kolab::cDateTime(2007,1,6,12,0,0, true))); periods.push_back(Kolab::Period(Kolab::cDateTime(2006,1,6,12,0,0, true),Kolab::cDateTime(2007,1,6,12,0,0, true))); fbp.setPeriods(periods); fbperiods.push_back(fbp); fbperiods.push_back(fbp); ev.setPeriods(fbperiods); Kolab::overrideTimestamp(ev.timestamp()); std::string result = Kolab::writeFreebusy(ev); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Freebusy re = Kolab::readFreebusy(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(ev.uid(), re.uid()); QCOMPARE(ev.timestamp(), re.timestamp()); QCOMPARE(ev.start(), re.start()); QCOMPARE(ev.end(), re.end()); QCOMPARE(ev.organizer(), re.organizer()); QCOMPARE(ev.periods(), re.periods()); } void BindingsTest::contactCompletness() { std::vector stringlist; stringlist.push_back("lbksdfbklsd"); stringlist.push_back("sdf"); Kolab::Contact c; c.setUid("1045b57d-ff7f-0000-d814-867b4d7f0000"); c.setLastModified(Kolab::cDateTime(2006,1,6,12,0,0, true)); c.setCategories(stringlist); c.setName("name"); Kolab::NameComponents nc; nc.setSurnames(stringlist); nc.setGiven(stringlist); nc.setAdditional(stringlist); nc.setPrefixes(stringlist); nc.setSuffixes(stringlist); c.setNameComponents(nc); c.setNote("note"); c.setFreeBusyUrl("freebusy"); c.setUrls(std::vector() << Kolab::Url("url1") << Kolab::Url("url1", Kolab::Url::Blog)); c.setNickNames(stringlist); std::vector relateds; Kolab::Related r1(Kolab::Related::Text, "text"); r1.setRelationTypes(Kolab::Related::Child); relateds.push_back(r1); Kolab::Related r2(Kolab::Related::Uid, "urn"); r2.setRelationTypes(Kolab::Related::Child|Kolab::Related::Spouse); relateds.push_back(r2); c.setRelateds(relateds); c.setBDay(Kolab::cDateTime(2001,12,10,12,12,12,false)); c.setAnniversary(Kolab::cDateTime(2001,3,2,1,1,1,false)); c.setPhoto("photo", "mimetype"); c.setGender(Kolab::Contact::Male); c.setLanguages(stringlist); c.setIMaddresses(stringlist,1); std::vector emails; emails.push_back(Kolab::Email("email1@example.org", Kolab::Email::NoType)); emails.push_back(Kolab::Email("email2@example.org", Kolab::Email::Work)); emails.push_back(Kolab::Email("email3@example.org", Kolab::Email::Work|Kolab::Email::Home)); c.setEmailAddresses(emails,0); c.setTitles(stringlist); std::vector list; Kolab::Affiliation aff; aff.setOrganisation("org"); aff.setOrganisationalUnits(stringlist); aff.setLogo("logo", "mime/miem"); aff.setRoles(stringlist); std::vector relateds2; relateds2.push_back(Kolab::Related(Kolab::Related::Text, "textRelation", Kolab::Related::Assistant)); relateds2.push_back(Kolab::Related(Kolab::Related::Uid, "textRelation", Kolab::Related::Manager)); aff.setRelateds(relateds2); std::vector adrs; Kolab::Address adr1; adr1.setLabel("label"); adrs.push_back(adr1); Kolab::Address adr2; adr2.setStreet("street"); adr2.setTypes(Kolab::Address::Work); adrs.push_back(adr2); aff.setAddresses(adrs); list.push_back(aff); Kolab::Affiliation aff2; aff2.setOrganisation("org2"); list.push_back(aff2); c.setAffiliations(list); Kolab::Address address; address.setCode("oiuoiu"); address.setCountry("werwer"); address.setLabel("lkjlkj"); address.setLocality("alla"); address.setRegion("skjdfkd"); address.setStreet("sldkflsdfj"); address.setTypes( Kolab::Address::Work | Kolab::Address::Home ); std::vector addresses; addresses.push_back(address); addresses.push_back(address); c.setAddresses(addresses); Kolab::Telephone phone; phone.setNumber("lkjsdflkjfds"); phone.setTypes(Kolab::Telephone::Work| Kolab::Telephone::Home| Kolab::Telephone::Text| Kolab::Telephone::Voice| Kolab::Telephone::Fax| Kolab::Telephone::Cell| Kolab::Telephone::Video| Kolab::Telephone::Pager| Kolab::Telephone::Textphone| Kolab::Telephone::Car ); std::vector telephones; telephones.push_back(phone); telephones.push_back(phone); c.setTelephones(telephones, 1); std::vector geo; geo << Kolab::Geo(1.3, -40.3); c.setGPSpos(geo); Kolab::Crypto crypto; crypto.setAllowed(Kolab::Crypto::PGPinline | Kolab::Crypto::SMIMEopaque); crypto.setSignPref(Kolab::Crypto::IfPossible); crypto.setEncryptPref(Kolab::Crypto::Never); c.setCrypto(crypto); std::vector keys; keys.push_back(Kolab::Key("pgp", Kolab::Key::PGP)); keys.push_back(Kolab::Key("smime", Kolab::Key::PKCS7_MIME)); c.setKeys(keys); std::vector properties; properties.push_back(Kolab::CustomProperty("ident", "value")); properties.push_back(Kolab::CustomProperty("ident", "value")); c.setCustomProperties(properties); const std::string result = Kolab::writeContact(c); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Contact e = Kolab::readContact(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(e.uid(), c.uid()); QCOMPARE(e.lastModified(), c.lastModified()); QCOMPARE(e.categories(), c.categories()); QCOMPARE(e.name(), c.name()); QCOMPARE(e.nameComponents(), c.nameComponents()); QCOMPARE(e.note(), c.note()); QCOMPARE(e.freeBusyUrl(), c.freeBusyUrl()); QCOMPARE(e.titles(), c.titles()); QCOMPARE(e.affiliations(), c.affiliations()); QCOMPARE(e.urls(), c.urls()); QCOMPARE(e.addresses(), c.addresses()); QCOMPARE(e.addressPreferredIndex(), c.addressPreferredIndex()); QCOMPARE(e.nickNames(), c.nickNames()); QCOMPARE(e.relateds(), c.relateds()); QCOMPARE(e.bDay(), c.bDay()); QCOMPARE(e.anniversary(), c.anniversary()); QCOMPARE(e.photo(), c.photo()); QCOMPARE(e.photoMimetype(), c.photoMimetype()); QCOMPARE(e.gender(), c.gender()); QCOMPARE(e.languages(), c.languages()); QCOMPARE(e.telephones(), c.telephones()); QCOMPARE(e.telephonesPreferredIndex(), c.telephonesPreferredIndex()); QCOMPARE(e.imAddresses(), c.imAddresses()); QCOMPARE(e.imAddressPreferredIndex(), c.imAddressPreferredIndex()); QCOMPARE(e.emailAddresses(), c.emailAddresses()); QCOMPARE(e.emailAddressPreferredIndex(), c.emailAddressPreferredIndex()); QCOMPARE(e.emailAddressPreferredIndex(), 0); QCOMPARE(e.gpsPos(), c.gpsPos()); QCOMPARE(e.keys(), c.keys()); QCOMPARE(e.crypto(), c.crypto()); QCOMPARE(e.customProperties(), c.customProperties()); } void BindingsTest::dateOnlyDates() { Kolab::Contact c; c.setUid("1045b57d-ff7f-0000-d814-867b4d7f0000"); c.setName("name"); c.setBDay(Kolab::cDateTime(2001,12,10)); c.setAnniversary(Kolab::cDateTime(2001,3,2)); const std::string result = Kolab::writeContact(c); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::Contact e = Kolab::readContact(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(e.bDay(), c.bDay()); QCOMPARE(e.anniversary(), c.anniversary()); } void BindingsTest::distlistCompletness() { std::vector stringlist; stringlist.push_back("lbksdfbklsd"); stringlist.push_back("sdf"); Kolab::DistList c; c.setName("name"); c.setUid("uid"); std::vector members; members.push_back(Kolab::ContactReference(Kolab::ContactReference::EmailReference, "mail", "name")); members.push_back(Kolab::ContactReference(Kolab::ContactReference::UidReference, "urn")); c.setMembers(members); std::vector properties; properties.push_back(Kolab::CustomProperty("ident", "value")); properties.push_back(Kolab::CustomProperty("ident", "value")); c.setCustomProperties(properties); const std::string result = Kolab::writeDistlist(c); QVERIFY(Kolab::error() == Kolab::NoError); // std::cout << result << endl; Kolab::DistList e = Kolab::readDistlist(result, false); QVERIFY(Kolab::error() == Kolab::NoError); QCOMPARE(e.uid(), c.uid()); QCOMPARE(e.name(), c.name()); QCOMPARE(e.members(), c.members()); QCOMPARE(e.customProperties(), c.customProperties()); } void BindingsTest::generateTimestampIfEmpty() { //xcal Kolab::Event ev; setIncidence(ev); ev.setLastModified(Kolab::cDateTime()); std::string result = Kolab::writeEvent(ev); Kolab::Event e = Kolab::readEvent(result, false); QVERIFY(e.lastModified().isValid()); QVERIFY(e.lastModified().isUTC()); //xcard Kolab::Contact c; c.setUid("1045b57d-ff7f-0000-d814-867b4d7f0000"); const std::string contactResult = Kolab::writeContact(c); Kolab::Contact retContact = Kolab::readContact(contactResult, false); QVERIFY(retContact.lastModified().isValid()); QVERIFY(retContact.lastModified().isUTC()); } void BindingsTest::versionTest() { Kolab::Todo ev; setIncidence(ev); std::string result = Kolab::writeTodo(ev); Kolab::Todo e = Kolab::readTodo(result, false); QCOMPARE(Kolab::productId(), std::string(KOLAB_LIB_VERSION_STRING)); QCOMPARE(Kolab::xKolabVersion(), std::string(KOLAB_FORMAT_VERSION)); QCOMPARE(Kolab::xCalVersion(), std::string("2.0")); } void BindingsTest::errorTest() { Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false); QCOMPARE(Kolab::error(), Kolab::Critical); QVERIFY(!Kolab::errorMessage().empty()); } //Don't break due to an error void BindingsTest::errorRecoveryTest() { Kolab::Todo e = Kolab::readTodo("klbsdfbklsdbkl", false); QCOMPARE(Kolab::error(), Kolab::Critical); Kolab::Todo ev; setIncidence(ev); const std::string result = Kolab::writeTodo(ev); Kolab::readTodo(result, false); QCOMPARE(Kolab::error(), Kolab::NoError); } void BindingsTest::BenchmarkRoundtripKolab() { const Kolab::Event &event = Kolab::readEvent(TEST_DATA_PATH "/testfiles/icalEvent.xml", true); QVERIFY(!Kolab::errorOccurred()); std::string result = Kolab::writeEvent(event); QBENCHMARK { Kolab::readEvent(result, false); } } void BindingsTest::BenchmarkRoundtrip() { const Kolab::Event &event = Kolab::readEvent(TEST_DATA_PATH "/testfiles/icalEvent.xml", true); QVERIFY(!Kolab::errorOccurred()); std::string result; QBENCHMARK { result = Kolab::writeEvent(event); Kolab::readEvent(result, false); } } void BindingsTest::preserveLatin1() { Kolab::Event event; event.setSummary("äöü%@$£é¤¼²°"); std::string result = Kolab::writeEvent(event); // std::cout << result << std::endl; Kolab::Event readEvent = Kolab::readEvent(result, false); // std::cout << readEvent.summary() << std::endl; QCOMPARE(readEvent.summary(), event.summary()); } void BindingsTest::preserveUnicode() { Kolab::Event event; event.setSummary("€Š�ـأبـ"); std::string result = Kolab::writeEvent(event); // std::cout << result << std::endl; Kolab::Event readEvent = Kolab::readEvent(result, false); // std::cout << readEvent.summary() << std::endl; QCOMPARE(readEvent.summary(), event.summary()); } QTEST_MAIN( BindingsTest ) #include "bindingstest.moc" libkolabxml-1.1.2/tests/bindingstest.h000066400000000000000000000027661262531651400200430ustar00rootroot00000000000000#ifndef BINDINGSTEST_H #define BINDINGSTEST_H #include #include /* * The test are roundtrip tests, which simply write an object out and read it again. The two objects are then compared for equality. * This assumes that containers are working (comparison operators and adding/removing values). * * Testing it properly would mean to add loads of testfiles in text so we could: * serialize => compare to text representation * deserialize => check values * * If we would do this ideally for every property on every type that would result in a lot of work. * */ class BindingsTest : public QObject { Q_OBJECT private slots: //Kolabformat void categorycolorConfigurationCompletness(); void dictionaryConfigurationCompletness(); void snippetConfigurationCompletness(); void relationConfigurationCompletness(); void fileDriverConfigurationCompletness(); void noteCompletness(); void fileCompletness(); void eventCompletness(); void eventDuration(); void eventExceptions(); void todoCompletness(); void dueDateDateOnly(); void journalCompletness(); void freebusyCompletness(); void contactCompletness(); void dateOnlyDates(); void distlistCompletness(); void generateTimestampIfEmpty(); void versionTest(); void errorTest(); void errorRecoveryTest(); void BenchmarkRoundtripKolab(); void BenchmarkRoundtrip(); void preserveLatin1(); void preserveUnicode(); }; #endiflibkolabxml-1.1.2/tests/conversiontest.cpp000066400000000000000000000274461262531651400207700ustar00rootroot00000000000000#include "conversiontest.h" #include #include #include #include #include "serializers.h" #include #include Q_DECLARE_METATYPE(Kolab::Duration); Q_DECLARE_METATYPE(Kolab::DayPos); Q_DECLARE_METATYPE(Kolab::cDateTime); Q_DECLARE_METATYPE(Kolab::ErrorSeverity); Q_DECLARE_METATYPE(std::string); using namespace Kolab::XCAL; void ConversionTest::dateComparatorTest() { QVERIFY( !(Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) == Kolab::cDateTime())); QVERIFY( Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) == Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false)); } void ConversionTest::durationParserTest_data() { QTest::addColumn("expected"); QTest::addColumn("string"); QTest::newRow("Time") << Kolab::Duration(0,2,3,4, false) << "+PT2H3M4S"; QTest::newRow("Day") << Kolab::Duration(1,2,3,4, false) << "+P1DT2H3M4S"; QTest::newRow("Week") << Kolab::Duration(1, false) << "+P1W"; QTest::newRow("Week Multidigit, negative") << Kolab::Duration(23, true) << "-P23W"; Kolab::Utils::clearErrors(); } void ConversionTest::durationParserTest() { QFETCH(QString, string); QFETCH(Kolab::Duration, expected); const Kolab::Duration result = toDuration(string.toStdString()); QCOMPARE(result, expected); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::durationSerializerTest_data() { QTest::addColumn("expected"); QTest::addColumn("duration"); QTest::newRow("Time") << "PT2H3M4S" << Kolab::Duration(0,2,3,4, false); QTest::newRow("Day") << "P1DT2H3M4S" << Kolab::Duration(1,2,3,4, false); QTest::newRow("Week positive") << "P1W" << Kolab::Duration(1, false); QTest::newRow("Week negative") << "-P3W" << Kolab::Duration(3, true); QTest::newRow("Week Multidigit, negative") << "-P23W" << Kolab::Duration(23, true); Kolab::Utils::clearErrors(); } void ConversionTest::durationSerializerTest() { QFETCH(Kolab::Duration, duration); QFETCH(QString, expected); const std::string result = fromDuration(duration); QCOMPARE(QString::fromStdString(result), expected); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::dayPosParserTest_data() { QTest::addColumn("expected"); QTest::addColumn("string"); QTest::newRow("positive") << Kolab::DayPos(15, Kolab::Wednesday) << "15WE"; QTest::newRow("positive with +") << Kolab::DayPos(15, Kolab::Wednesday) << "+15WE"; QTest::newRow("negative") << Kolab::DayPos(-15, Kolab::Wednesday) << "-15WE"; QTest::newRow("all occurrences") << Kolab::DayPos(0, Kolab::Wednesday) << "WE"; Kolab::Utils::clearErrors(); } void ConversionTest::dayPosParserTest() { QFETCH(QString, string); QFETCH(Kolab::DayPos, expected); const Kolab::DayPos result = toDayPos(string.toStdString()); QCOMPARE(result, expected); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::dayPosSerializerTest_data() { QTest::addColumn("expected"); QTest::addColumn("daypos"); QTest::newRow("pos") << "15WE" << Kolab::DayPos(15, Kolab::Wednesday); QTest::newRow("negative") << "-15WE" << Kolab::DayPos(-15, Kolab::Wednesday); QTest::newRow("all occurrences") << "WE" << Kolab::DayPos(0, Kolab::Wednesday); Kolab::Utils::clearErrors(); } void ConversionTest::dayPosSerializerTest() { QFETCH(Kolab::DayPos, daypos); QFETCH(QString, expected); const std::string result = fromDayPos(daypos); QCOMPARE(QString::fromStdString(result), expected); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::xcardDateParserTest_data() { QTest::addColumn("input"); QTest::addColumn("expected"); QTest::addColumn("errorState"); QTest::newRow("datetime local") << "20010102T030405" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false) << Kolab::NoError; QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, true) << Kolab::NoError; QTest::newRow("date only") << "20010102" << Kolab::cDateTime(2001, 01, 02) << Kolab::NoError; QTest::newRow("fail 1 short") << "20010102T03040" << Kolab::cDateTime() << Kolab::Error; QTest::newRow("fail non utc") << "20010102T030401s" << Kolab::cDateTime() << Kolab::Error; QTest::newRow("fail no time") << "20010102T" << Kolab::cDateTime() << Kolab::Error; Kolab::Utils::clearErrors(); } void ConversionTest::xcardDateParserTest() { QFETCH(QString, input); QFETCH(Kolab::cDateTime, expected); QFETCH(Kolab::ErrorSeverity, errorState); const Kolab::cDateTime &dt = Kolab::XCARD::toDateTime(input.toStdString()); QCOMPARE(dt, expected); QCOMPARE(Kolab::Utils::getError(), errorState); } void ConversionTest::xCardSerializerTest_data() { QTest::addColumn("expected"); QTest::addColumn("dt"); QTest::newRow("datetime local") << "20010102T030405" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false); QTest::newRow("datetime utc") << "20010102T030405Z" << Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, true); QTest::newRow("dateonly") << "20010102" << Kolab::cDateTime(2001, 01, 02); Kolab::Utils::clearErrors(); } void ConversionTest::xCardSerializerTest() { QFETCH(QString, expected); QFETCH(Kolab::cDateTime, dt); const std::string &s = Kolab::XCARD::fromDateTime(dt); QCOMPARE(QString::fromStdString(s), expected); if (dt.isDateOnly()) { const std::string &s2 = Kolab::XCARD::fromDate(dt); QCOMPARE(QString::fromStdString(s2), expected); } QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::uriInlineEncodingTest() { const std::string &s = Kolab::Utils::uriInlineEncoding("data", "mimetype/mime"); QCOMPARE(s, std::string("data:mimetype/mime;base64,ZGF0YQ==")); std::string mimetype; const std::string &d = Kolab::Utils::uriInlineDecoding(s, mimetype); QCOMPARE(mimetype, std::string("mimetype/mime")); QCOMPARE(d, std::string("data")); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::mailtoUriEncodingTest_data() { QTest::addColumn("email"); QTest::addColumn("name"); QTest::addColumn("resultEncoded"); //Older versions used to encode "." and "_". Not sure which version is actually required though (fixed in 7.26.0 but broken in 7.19.7, we're testing for 7.26.0) if (LIBCURL_VERSION_NUM >= 0x071a00) { QTest::newRow("1") << "email_1@email.com" << "John Doe" << "mailto:John%20Doe%3Cemail_1%40email.com%3E"; QTest::newRow("Reserved characters") << "!*'();:@&=+$,/?#[]@email.com" << "John Doe" << "mailto:John%20Doe%3C%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D%40email.com%3E"; QTest::newRow("Unreserved characters") << "Aa0-_.~@email.com" << "John Doe" << "mailto:John%20Doe%3CAa0-_.~%40email.com%3E"; } else { QTest::newRow("1") << "email_1@email.com" << "John Doe" << "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E"; QTest::newRow("Reserved characters") << "!*'();:@&=+$,/?#[]@email.com" << "John Doe" << "mailto:John%20Doe%3C%21%2A%27%28%29%3B%3A%40%26%3D%2B%24%2C%2F%3F%23%5B%5D%40email%2Ecom%3E"; QTest::newRow("Unreserved characters") << "Aa0-_.~@email.com" << "John Doe" << "mailto:John%20Doe%3CAa0%2D%5F%2E%7E%40email%2Ecom%3E"; } Kolab::Utils::clearErrors(); } void ConversionTest::mailtoUriEncodingTest() { QFETCH(QString, email); QFETCH(QString, name); QFETCH(QString, resultEncoded); const std::string &mailto = Kolab::XCARD::toMailto(email.toStdString(), name.toStdString()); // std::cout << mailto << std::endl; QCOMPARE(QString::fromStdString(mailto), resultEncoded); std::string n; const std::string &e = Kolab::XCARD::fromMailto(resultEncoded.toStdString(), n); QCOMPARE(QString::fromStdString(n), name); QCOMPARE(QString::fromStdString(e), email); } void ConversionTest::mailtoUriDecodingTest() { QString name("John Doe"); QString email("email_1@email.com"); //While we shouldn't encode '_' and '.' according to RFC 3986, we should still understand it for backwards compatiblity const std::string resultEncoded = "mailto:John%20Doe%3Cemail%5F1%40email%2Ecom%3E"; std::string n; const std::string &e = Kolab::XCARD::fromMailto(resultEncoded, n); QCOMPARE(QString::fromStdString(n), name); QCOMPARE(QString::fromStdString(e), email); } void ConversionTest::urnTest() { QCOMPARE(Kolab::Shared::toURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000")); QCOMPARE(Kolab::Shared::toURN("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000")); QCOMPARE(Kolab::Shared::fromURN("urn:uuid:1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("1045b57d-ff7f-0000-d814-867b4d7f0000")); QCOMPARE(Kolab::Shared::fromURN("1045b57d-ff7f-0000-d814-867b4d7f0000"), std::string("1045b57d-ff7f-0000-d814-867b4d7f0000")); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::geoUriTest() { QCOMPARE(Kolab::XCARD::toGeoUri(-34.056, 179.3453), std::string("geo:-34.056,179.3453")); QCOMPARE(Kolab::XCARD::toGeoUri(-34.1, 179.5), std::string("geo:-34.1,179.5")); QCOMPARE(Kolab::XCARD::toGeoUri(-34.0, 179.0), std::string("geo:-34,179")); QCOMPARE(Kolab::XCARD::toGeoUri(-34, 179), std::string("geo:-34,179")); QCOMPARE(Kolab::XCARD::toGeoUri(-34.012342356, 179.3451234553), std::string("geo:-34.012342356,179.3451234553")); double lat, lon; QVERIFY(Kolab::XCARD::fromGeoUri(std::string("geo:-34.056,179.3453"), lat, lon)); QCOMPARE(lat, -34.056); QCOMPARE(lon, 179.3453); QCOMPARE(Kolab::Utils::getError(), Kolab::NoError); } void ConversionTest::contactReferenceTest() { Kolab::ContactReference email(Kolab::ContactReference::EmailReference, "mail", "name"); QCOMPARE(Kolab::Shared::toMailto(email.email(), email.name()), std::string("mailto:name%3Cmail%3E")); Kolab::ContactReference urn(Kolab::ContactReference::UidReference, "urn"); QCOMPARE(Kolab::Shared::toURN(urn.uid()), std::string("urn:uuid:urn")); QCOMPARE(Kolab::Shared::toContactReference("urn:uuid:urn"), urn); QCOMPARE(Kolab::Shared::toContactReference("mailto:name%3Cmail%3E"), email); } void threadF() { for (int i = 0; i < 5; ++i) { std::stringstream s; // s << boost::this_thread::get_id(); std::string uid = s.str(); // std::cout << uid << std::endl; Kolab::Utils::setCreatedUid(uid); boost::this_thread::sleep(boost::posix_time::millisec(50)); QCOMPARE(Kolab::Utils::createdUid(), uid); } } void ConversionTest::threadLocalTest() { //Ensure global variables are not mixed between threads and therefore threadsafe. boost::thread t(threadF); boost::thread t2(threadF); t.join(); t2.join(); } void ConversionTest::uuidGeneratorTest() { const std::string &s = getUID(); // std::cout << s << std::endl; QVERIFY(!s.empty()); QCOMPARE(s.size(), (std::size_t)36ul); //Ensure we don't get the same uuid twice const std::string &s2 = getUID(); QVERIFY(s != s2); } void ConversionTest::uuidGeneratorTest2() { Kolab::Event event; event.setStart(Kolab::cDateTime(2001, 01, 02, 03, 04 ,05, false)); QVERIFY(Kolab::getSerializedUID().empty()); Kolab::writeEvent(event); std::string uid1 = Kolab::getSerializedUID(); QVERIFY(!uid1.empty()); Kolab::writeEvent(event); std::string uid2 = Kolab::getSerializedUID(); std::cout << uid1 << uid2; QVERIFY(!uid2.empty()); QVERIFY(uid1 != uid2); } QTEST_MAIN( ConversionTest ) #include "conversiontest.moc" libkolabxml-1.1.2/tests/conversiontest.h000066400000000000000000000017271262531651400204270ustar00rootroot00000000000000 #ifndef CONVERSIONTEST_H #define CONVERSIONTEST_H #include class ConversionTest : public QObject { Q_OBJECT private slots: void dateComparatorTest(); void durationParserTest_data(); void durationParserTest(); void durationSerializerTest_data(); void durationSerializerTest(); void dayPosParserTest_data(); void dayPosParserTest(); void dayPosSerializerTest_data(); void dayPosSerializerTest(); void xcardDateParserTest_data(); void xcardDateParserTest(); void xCardSerializerTest_data(); void xCardSerializerTest(); void uriInlineEncodingTest(); void mailtoUriEncodingTest_data(); void mailtoUriEncodingTest(); void mailtoUriDecodingTest(); void urnTest(); void contactReferenceTest(); void geoUriTest(); void threadLocalTest(); void uuidGeneratorTest(); void uuidGeneratorTest2(); }; #endif // CONVERSIONTEST_H libkolabxml-1.1.2/tests/kolabconversationtest.cpp000066400000000000000000000032531262531651400223140ustar00rootroot00000000000000/* Copyright (C) 2014 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "kolabconversationtest.h" #include #include #include #include "src/kolabconversions.h" void KolabConversationTest::configurationDeserialationTest() { boost::shared_ptr ptr = Kolab::KolabObjects::deserializeObject(TEST_DATA_PATH "/testfiles/testConfiguration.xml", true); QVERIFY(static_cast(ptr)); QVERIFY(ptr->isValid()); QCOMPARE(ptr->type(), Kolab::Configuration::TypeRelation); } void KolabConversationTest::noteDeserialationTest() { boost::shared_ptr ptr = Kolab::KolabObjects::deserializeObject(TEST_DATA_PATH "/testfiles/testNote.xml", true); QVERIFY(static_cast(ptr)); QVERIFY(ptr->isValid()); QCOMPARE(ptr->summary(), std::string("summarytext")); } QTEST_MAIN( KolabConversationTest ) #include "kolabconversationtest.moc" libkolabxml-1.1.2/tests/kolabconversationtest.h000066400000000000000000000020471262531651400217610ustar00rootroot00000000000000/* Copyright (C) 2014 Sandro Knauß This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef KOLABCONVERSATIONTEST_H #define KOLABCONVERSATIONTEST_H #include class KolabConversationTest: public QObject { Q_OBJECT private slots: void configurationDeserialationTest(); void noteDeserialationTest(); }; #endif libkolabxml-1.1.2/tests/parsingtest.cpp000066400000000000000000000023011262531651400202250ustar00rootroot00000000000000/* Copyright (C) 2012 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "parsingtest.h" #include #include #include "src/kolabformat.h" void ParsingTest::vcardParsingTest() { const Kolab::Contact &contact = Kolab::readContact(TEST_DATA_PATH "/testfiles/vcard/contact.xml", true); QCOMPARE(Kolab::error(), Kolab::NoError); std::cout << Kolab::writeContact(contact); } QTEST_MAIN( ParsingTest ) #include "parsingtest.moc" libkolabxml-1.1.2/tests/parsingtest.h000066400000000000000000000020111262531651400176700ustar00rootroot00000000000000/* Copyright (C) 2012 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef PARSINGTEST_H #define PARSINGTEST_H #include class ParsingTest: public QObject { Q_OBJECT private slots: // void vcardParsingTest_data(); void vcardParsingTest(); }; #endif libkolabxml-1.1.2/tests/serializers.h000066400000000000000000000154721262531651400177000ustar00rootroot00000000000000#ifndef SERIALIZERS_H #define SERIALIZERS_H #include #include #include namespace QTest { template<> char *toString(const Kolab::cDateTime &dt) { QByteArray ba = "Kolab::cDateTime("; ba += QByteArray::number(dt.year()) + ", " + QByteArray::number(dt.month())+ ", " + QByteArray::number(dt.day()) + ", "; ba += QByteArray::number(dt.hour()) + ", " + QByteArray::number(dt.minute()) + ", " + QByteArray::number(dt.second())+ ", "; ba += dt.isUTC()?QByteArray("UTC"):QByteArray("TZ: "+QByteArray(dt.timezone().c_str())); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ "\n"; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::Attendee &a) { QByteArray ba = "Kolab::Attendee("; ba += QByteArray(a.contact().email().c_str()) + ", " + QByteArray(a.contact().name().c_str())+ ", " + QByteArray::number(a.partStat()) + ", " + QByteArray::number(a.role()) + ", " + QByteArray::number(a.rsvp()) + ", " + QByteArray(a.contact().uid().c_str()); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ ", "; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::string &s) { QByteArray ba = "string("; ba += QByteArray(s.c_str()); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ ", "; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QString::number(v.at(i)).toLatin1()+ ", "; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::Duration &dt) { QByteArray ba = "Kolab::Duration("; ba += QByteArray::number(dt.weeks()) + ", " + QByteArray::number(dt.days())+ ", " + QByteArray::number(dt.hours()) + ", "; ba += QByteArray::number(dt.minutes()) + ", " + QByteArray::number(dt.seconds()) + ", " + QByteArray::number(dt.isNegative()); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::DayPos &dt) { QByteArray ba = "Kolab::DayPos("; ba += QByteArray::number(dt.occurence()) + ", " + QByteArray::number(dt.weekday()); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::Attachment &a) { QByteArray ba = "Kolab::Attachment("; ba += QByteArray(a.uri().c_str()) + ", " + QByteArray(a.mimetype().c_str())+ ", " + QByteArray(a.label().c_str()); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ "\n"; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::ContactReference &a) { QByteArray ba = "Kolab::ContactReference("; ba += QByteArray(a.email().c_str())+ ", "; ba += QByteArray(a.name().c_str())+ ", "; ba += QByteArray(a.uid().c_str()); ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ "\n"; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::Alarm &a) { QByteArray ba = "Kolab::Alarm("; ba += QByteArray::number(a.type()) + "\n " + QByteArray(a.summary().c_str())+ "\n " + QByteArray(a.text().c_str())+"\n " +QByteArray(toString(a.duration())) + "\n " + QByteArray::number(a.numrepeat())+ "\n " + QByteArray(toString(a.start())) + "\n " + QByteArray(toString(a.relativeStart())) + "\n " + QByteArray::number(a.relativeTo()) + "\n " + QByteArray(toString(a.audioFile())) + "\n " + QByteArray(toString(a.attendees())) + "\n "; ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ "\n"; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::Related &a) { QByteArray ba = "Kolab::Related("; ba += QByteArray(a.text().c_str())+ "\n " + QByteArray(a.uri().c_str())+"\n " + QByteArray::number(a.relationTypes()) + "\n " + QByteArray::number(a.type()) + "\n "; ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ "\n"; } ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const Kolab::Affiliation &a) { QByteArray ba = "Kolab::Affiliation("; ba += QByteArray(a.organisation().c_str())+ "\n " + QByteArray(a.logo().c_str()) + "\n " + "\n " + QByteArray(toString(a.roles())) + "\n " + QByteArray(toString(a.relateds())) + "\n " + QByteArray(toString(a.addresses())) + "\n "; ba += ")"; return qstrdup(ba.data()); } template<> char *toString(const std::vector &v) { QByteArray ba = "vector("; for (std::size_t i = 0; i < v.size(); i++) { ba += QByteArray(toString(v.at(i)))+ "\n"; } ba += ")"; return qstrdup(ba.data()); } } #endif libkolabxml-1.1.2/tests/testfiles/000077500000000000000000000000001262531651400171645ustar00rootroot00000000000000libkolabxml-1.1.2/tests/testfiles/icalEvent.xml000066400000000000000000000054631262531651400216300ustar00rootroot00000000000000 -//Example Inc.//Example Client//EN 2.0 3.0dev1 00959BC664CA650E933C892C@example.com 2006-02-06T00:11:21Z 2006-02-06T00:11:21Z /kolab.org/Europe/Zurich 2006-01-02T12:00:00 PT1H DAILY 5 /kolab.org/Europe/Zurich 2007-02-06T00:11:21 Event #2 Test. Test. Test. libkolabxml-1.1.2/tests/testfiles/testConfiguration.xml000066400000000000000000000006061262531651400234170ustar00rootroot00000000000000 6194e99c-69c0-11e4-9911-080027fe5a4c Roundcube-libkolab-1.1 Libkolabxml-1.1 2014-11-11T16:32:51Z 2014-11-11T16:32:51Z relation libkolabxml-1.1.2/tests/testfiles/testNote.xml000066400000000000000000000005511262531651400215140ustar00rootroot00000000000000 uid 2014-11-11T16:32:51Z 2014-11-11T16:32:51Z PUBLIC summarytext #ffff00 libkolabxml-1.1.2/tests/testfiles/testevent.xml000066400000000000000000000011231262531651400217240ustar00rootroot00000000000000 2011-11-10+10:10 DAILY 2 3 1 value goes here libkolabxml-1.1.2/tests/testfiles/testkolabevent.xml000066400000000000000000000012661262531651400227450ustar00rootroot00000000000000 2011-11-10+10:10 2 3 DAILY blabla blibla libkolabxml-1.1.2/tests/testfiles/vcard/000077500000000000000000000000001262531651400202635ustar00rootroot00000000000000libkolabxml-1.1.2/tests/testfiles/vcard/contact.xml000066400000000000000000000010711262531651400224370ustar00rootroot00000000000000 urn:uuid:K4pNZM8dES 3.0dev1 Libkolabxml-0.3.0 20120422T231004Z individual Testcontact Testcontact libkolabxml-1.1.2/tests/validationtest.cpp000066400000000000000000000062171262531651400207260ustar00rootroot00000000000000/* Copyright (C) 2013 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "validationtest.h" #include #include "src/kolabformat.h" using namespace Kolab; void ValidationTest::testErrorOnEmptyEvent() { Event event; writeEvent(event); QCOMPARE(Kolab::error(), Kolab::Error); } void ValidationTest::testNoErrorOnValidEvent() { Event event; event.setStart(cDateTime(2013,1,1,1,1,1)); writeEvent(event); QCOMPARE(Kolab::error(), Kolab::NoError); } void ValidationTest::testNoErrorOnValidTodo() { { Todo todo; todo.setStart(cDateTime("Europe/Zurich", 2013,1,1,1,1,1)); writeTodo(todo); QCOMPARE(Kolab::error(), Kolab::NoError); } { Todo todo; todo.setDue(cDateTime("Europe/Zurich", 2013,1,1,1,1,1)); writeTodo(todo); QCOMPARE(Kolab::error(), Kolab::NoError); } { Todo todo; todo.setStart(cDateTime("Europe/Zurich", 2013,1,1,1,1,1)); todo.setDue(cDateTime("Europe/Zurich", 2013,1,1,1,1,1)); writeTodo(todo); QCOMPARE(Kolab::error(), Kolab::NoError); } } void ValidationTest::testOlsonTimezone() { Event event; event.setStart(cDateTime("Europe/Zurich",2013,1,1,1,1,1)); writeEvent(event); QCOMPARE(Kolab::error(), Kolab::NoError); } void ValidationTest::testDifferentTimezones() { Event event; event.setStart(cDateTime("Europe/Zurich",2013,1,1,1,1,1)); event.setEnd(cDateTime("Europe/London",2013,1,1,1,1,1)); writeEvent(event); QCOMPARE(Kolab::error(), Kolab::NoError); Todo todo; todo.setStart(cDateTime("Europe/Zurich",2013,1,1,1,1,1)); todo.setDue(cDateTime("Europe/London",2013,1,1,1,1,1)); writeTodo(todo); QCOMPARE(Kolab::error(), Kolab::NoError); } void ValidationTest::testUTCwithTimezone() { Event event; cDateTime dt("Europe/Zurich",2013,1,1,1,1,1); dt.setUTC(true); event.setStart(dt); writeEvent(event); QCOMPARE(Kolab::error(), Kolab::Error); } void ValidationTest::testTimezoneZ() { Event event; event.setStart(cDateTime("Z",2013,1,1,1,1,1)); writeEvent(event); QCOMPARE(Kolab::error(), Kolab::Error); } void ValidationTest::testWindowsTimezone() { Event event; event.setStart(cDateTime("Central European Standard Time",2013,1,1,1,1,1)); writeEvent(event); QCOMPARE(Kolab::error(), Kolab::Error); } QTEST_MAIN( ValidationTest ) #include "validationtest.moc" libkolabxml-1.1.2/tests/validationtest.h000066400000000000000000000023211262531651400203630ustar00rootroot00000000000000/* Copyright (C) 2013 Christian Mollekopf This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef VALIDATIONTEST_H #define VALIDATIONTEST_H #include class ValidationTest: public QObject { Q_OBJECT private slots: void testErrorOnEmptyEvent(); void testNoErrorOnValidEvent(); void testNoErrorOnValidTodo(); void testOlsonTimezone(); void testDifferentTimezones(); void testUTCwithTimezone(); void testTimezoneZ(); void testWindowsTimezone(); }; #endif libkolabxml-1.1.2/tztable.h000066400000000000000000000234751262531651400156510ustar00rootroot00000000000000//This file was generated by the zonetabconversion.py script static const char* olsonTimezones[] = { "Europe/Andorra", "Asia/Dubai", "Asia/Kabul", "America/Antigua", "America/Anguilla", "Europe/Tirane", "Asia/Yerevan", "Africa/Luanda", "Antarctica/McMurdo", "Antarctica/South_Pole", "Antarctica/Rothera", "Antarctica/Palmer", "Antarctica/Mawson", "Antarctica/Davis", "Antarctica/Casey", "Antarctica/Vostok", "Antarctica/DumontDUrville", "Antarctica/Syowa", "America/Argentina/Buenos_Aires", "America/Argentina/Cordoba", "America/Argentina/Salta", "America/Argentina/Jujuy", "America/Argentina/Tucuman", "America/Argentina/Catamarca", "America/Argentina/La_Rioja", "America/Argentina/San_Juan", "America/Argentina/Mendoza", "America/Argentina/San_Luis", "America/Argentina/Rio_Gallegos", "America/Argentina/Ushuaia", "Pacific/Pago_Pago", "Europe/Vienna", "Australia/Lord_Howe", "Antarctica/Macquarie", "Australia/Hobart", "Australia/Currie", "Australia/Melbourne", "Australia/Sydney", "Australia/Broken_Hill", "Australia/Brisbane", "Australia/Lindeman", "Australia/Adelaide", "Australia/Darwin", "Australia/Perth", "Australia/Eucla", "America/Aruba", "Europe/Mariehamn", "Asia/Baku", "Europe/Sarajevo", "America/Barbados", "Asia/Dhaka", "Europe/Brussels", "Africa/Ouagadougou", "Europe/Sofia", "Asia/Bahrain", "Africa/Bujumbura", "Africa/Porto-Novo", "America/St_Barthelemy", "Atlantic/Bermuda", "Asia/Brunei", "America/La_Paz", "America/Kralendijk", "America/Noronha", "America/Belem", "America/Fortaleza", "America/Recife", "America/Araguaina", "America/Maceio", "America/Bahia", "America/Sao_Paulo", "America/Campo_Grande", "America/Cuiaba", "America/Santarem", "America/Porto_Velho", "America/Boa_Vista", "America/Manaus", "America/Eirunepe", "America/Rio_Branco", "America/Nassau", "Asia/Thimphu", "Africa/Gaborone", "Europe/Minsk", "America/Belize", "America/St_Johns", "America/Halifax", "America/Glace_Bay", "America/Moncton", "America/Goose_Bay", "America/Blanc-Sablon", "America/Montreal", "America/Toronto", "America/Nipigon", "America/Thunder_Bay", "America/Iqaluit", "America/Pangnirtung", "America/Resolute", "America/Atikokan", "America/Rankin_Inlet", "America/Winnipeg", "America/Rainy_River", "America/Regina", "America/Swift_Current", "America/Edmonton", "America/Cambridge_Bay", "America/Yellowknife", "America/Inuvik", "America/Creston", "America/Dawson_Creek", "America/Vancouver", "America/Whitehorse", "America/Dawson", "Indian/Cocos", "Africa/Kinshasa", "Africa/Lubumbashi", "Africa/Bangui", "Africa/Brazzaville", "Europe/Zurich", "Africa/Abidjan", "Pacific/Rarotonga", "America/Santiago", "Pacific/Easter", "Africa/Douala", "Asia/Shanghai", "Asia/Harbin", "Asia/Chongqing", "Asia/Urumqi", "Asia/Kashgar", "America/Bogota", "America/Costa_Rica", "America/Havana", "Atlantic/Cape_Verde", "America/Curacao", "Indian/Christmas", "Asia/Nicosia", "Europe/Prague", "Europe/Berlin", "Europe/Busingen", "Africa/Djibouti", "Europe/Copenhagen", "America/Dominica", "America/Santo_Domingo", "Africa/Algiers", "America/Guayaquil", "Pacific/Galapagos", "Europe/Tallinn", "Africa/Cairo", "Africa/El_Aaiun", "Africa/Asmara", "Europe/Madrid", "Africa/Ceuta", "Atlantic/Canary", "Africa/Addis_Ababa", "Europe/Helsinki", "Pacific/Fiji", "Atlantic/Stanley", "Pacific/Chuuk", "Pacific/Pohnpei", "Pacific/Kosrae", "Atlantic/Faroe", "Europe/Paris", "Africa/Libreville", "Europe/London", "America/Grenada", "Asia/Tbilisi", "America/Cayenne", "Europe/Guernsey", "Africa/Accra", "Europe/Gibraltar", "America/Godthab", "America/Danmarkshavn", "America/Scoresbysund", "America/Thule", "Africa/Banjul", "Africa/Conakry", "America/Guadeloupe", "Africa/Malabo", "Europe/Athens", "Atlantic/South_Georgia", "America/Guatemala", "Pacific/Guam", "Africa/Bissau", "America/Guyana", "Asia/Hong_Kong", "America/Tegucigalpa", "Europe/Zagreb", "America/Port-au-Prince", "Europe/Budapest", "Asia/Jakarta", "Asia/Pontianak", "Asia/Makassar", "Asia/Jayapura", "Europe/Dublin", "Asia/Jerusalem", "Europe/Isle_of_Man", "Asia/Kolkata", "Indian/Chagos", "Asia/Baghdad", "Asia/Tehran", "Atlantic/Reykjavik", "Europe/Rome", "Europe/Jersey", "America/Jamaica", "Asia/Amman", "Asia/Tokyo", "Africa/Nairobi", "Asia/Bishkek", "Asia/Phnom_Penh", "Pacific/Tarawa", "Pacific/Enderbury", "Pacific/Kiritimati", "Indian/Comoro", "America/St_Kitts", "Asia/Pyongyang", "Asia/Seoul", "Asia/Kuwait", "America/Cayman", "Asia/Almaty", "Asia/Qyzylorda", "Asia/Aqtobe", "Asia/Aqtau", "Asia/Oral", "Asia/Vientiane", "Asia/Beirut", "America/St_Lucia", "Europe/Vaduz", "Asia/Colombo", "Africa/Monrovia", "Africa/Maseru", "Europe/Vilnius", "Europe/Luxembourg", "Europe/Riga", "Africa/Tripoli", "Africa/Casablanca", "Europe/Monaco", "Europe/Chisinau", "Europe/Podgorica", "America/Marigot", "Indian/Antananarivo", "Pacific/Majuro", "Pacific/Kwajalein", "Europe/Skopje", "Africa/Bamako", "Asia/Rangoon", "Asia/Ulaanbaatar", "Asia/Hovd", "Asia/Choibalsan", "Asia/Macau", "Pacific/Saipan", "America/Martinique", "Africa/Nouakchott", "America/Montserrat", "Europe/Malta", "Indian/Mauritius", "Indian/Maldives", "Africa/Blantyre", "America/Mexico_City", "America/Cancun", "America/Merida", "America/Monterrey", "America/Matamoros", "America/Mazatlan", "America/Chihuahua", "America/Ojinaga", "America/Hermosillo", "America/Tijuana", "America/Santa_Isabel", "America/Bahia_Banderas", "Asia/Kuala_Lumpur", "Asia/Kuching", "Africa/Maputo", "Africa/Windhoek", "Pacific/Noumea", "Africa/Niamey", "Pacific/Norfolk", "Africa/Lagos", "America/Managua", "Europe/Amsterdam", "Europe/Oslo", "Asia/Kathmandu", "Pacific/Nauru", "Pacific/Niue", "Pacific/Auckland", "Pacific/Chatham", "Asia/Muscat", "America/Panama", "America/Lima", "Pacific/Tahiti", "Pacific/Marquesas", "Pacific/Gambier", "Pacific/Port_Moresby", "Asia/Manila", "Asia/Karachi", "Europe/Warsaw", "America/Miquelon", "Pacific/Pitcairn", "America/Puerto_Rico", "Asia/Gaza", "Asia/Hebron", "Europe/Lisbon", "Atlantic/Madeira", "Atlantic/Azores", "Pacific/Palau", "America/Asuncion", "Asia/Qatar", "Indian/Reunion", "Europe/Bucharest", "Europe/Belgrade", "Europe/Kaliningrad", "Europe/Moscow", "Europe/Volgograd", "Europe/Samara", "Asia/Yekaterinburg", "Asia/Omsk", "Asia/Novosibirsk", "Asia/Novokuznetsk", "Asia/Krasnoyarsk", "Asia/Irkutsk", "Asia/Yakutsk", "Asia/Khandyga", "Asia/Vladivostok", "Asia/Sakhalin", "Asia/Ust-Nera", "Asia/Magadan", "Asia/Kamchatka", "Asia/Anadyr", "Africa/Kigali", "Asia/Riyadh", "Pacific/Guadalcanal", "Indian/Mahe", "Africa/Khartoum", "Europe/Stockholm", "Asia/Singapore", "Atlantic/St_Helena", "Europe/Ljubljana", "Arctic/Longyearbyen", "Europe/Bratislava", "Africa/Freetown", "Europe/San_Marino", "Africa/Dakar", "Africa/Mogadishu", "America/Paramaribo", "Africa/Juba", "Africa/Sao_Tome", "America/El_Salvador", "America/Lower_Princes", "Asia/Damascus", "Africa/Mbabane", "America/Grand_Turk", "Africa/Ndjamena", "Indian/Kerguelen", "Africa/Lome", "Asia/Bangkok", "Asia/Dushanbe", "Pacific/Fakaofo", "Asia/Dili", "Asia/Ashgabat", "Africa/Tunis", "Pacific/Tongatapu", "Europe/Istanbul", "America/Port_of_Spain", "Pacific/Funafuti", "Asia/Taipei", "Africa/Dar_es_Salaam", "Europe/Kiev", "Europe/Uzhgorod", "Europe/Zaporozhye", "Europe/Simferopol", "Africa/Kampala", "Pacific/Johnston", "Pacific/Midway", "Pacific/Wake", "America/New_York", "America/Detroit", "America/Kentucky/Louisville", "America/Kentucky/Monticello", "America/Indiana/Indianapolis", "America/Indiana/Vincennes", "America/Indiana/Winamac", "America/Indiana/Marengo", "America/Indiana/Petersburg", "America/Indiana/Vevay", "America/Chicago", "America/Indiana/Tell_City", "America/Indiana/Knox", "America/Menominee", "America/North_Dakota/Center", "America/North_Dakota/New_Salem", "America/North_Dakota/Beulah", "America/Denver", "America/Boise", "America/Shiprock", "America/Phoenix", "America/Los_Angeles", "America/Anchorage", "America/Juneau", "America/Sitka", "America/Yakutat", "America/Nome", "America/Adak", "America/Metlakatla", "Pacific/Honolulu", "America/Montevideo", "Asia/Samarkand", "Asia/Tashkent", "Europe/Vatican", "America/St_Vincent", "America/Caracas", "America/Tortola", "America/St_Thomas", "Asia/Ho_Chi_Minh", "Pacific/Efate", "Pacific/Wallis", "Pacific/Apia", "Asia/Aden", "Indian/Mayotte", "Africa/Johannesburg", "Africa/Lusaka", "Africa/Harare" }; static const long unsigned int numOlsonTimezones = sizeof olsonTimezones / sizeof *olsonTimezones; libkolabxml-1.1.2/utils/000077500000000000000000000000001262531651400151605ustar00rootroot00000000000000libkolabxml-1.1.2/utils/CMakeLists.txt000066400000000000000000000002721262531651400177210ustar00rootroot00000000000000 find_package(Boost REQUIRED COMPONENTS program_options) add_executable(kolabformatchecker kolabformatchecker.cpp) target_link_libraries(kolabformatchecker kolabxml ${Boost_LIBRARIES}) libkolabxml-1.1.2/utils/kolabformatchecker.cpp000066400000000000000000000062321262531651400215150ustar00rootroot00000000000000/* * Copyright (C) 2011 Christian Mollekopf * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . */ #include #include #include #include #include "src/kolabformat.h" namespace po = boost::program_options; using namespace std; int main(int argc, char *argv[]) { // Declare the supported options. po::options_description desc("Allowed options"); desc.add_options() ("help", "produce help message") ("contact", "parse contact") ("distlist", "parse distlist") ("event", "parse event") ("todo", "parse todo") ("journal", "parse journal") ("freebusy", "parse freebusy") ("note", "parse note") ("configuration", "parse configuration") ("file", "parse file") ("input-file", po::value >(), "input files of given type") ; po::positional_options_description p; p.add("input-file", -1); po::variables_map vm; po::store(po::command_line_parser(argc, argv). options(desc).positional(p).run(), vm); po::notify(vm); if (vm.count("help")) { cout << desc << "\n"; return 1; } vector inputFiles; if (vm.count("input-file")) { inputFiles = vm["input-file"].as< vector >(); } else { cout << "Specify input-file"; return -1; } for(vector::const_iterator it = inputFiles.begin(); it != inputFiles.end(); it++){ if (vm.count("contact")) { Kolab::readContact(*it, true); } else if (vm.count("distlist")) { Kolab::readDistlist(*it, true); } else if (vm.count("event")) { Kolab::readEvent(*it, true); } else if (vm.count("todo")) { Kolab::readTodo(*it, true); } else if (vm.count("journal")) { Kolab::readJournal(*it, true); } else if (vm.count("freebusy")) { Kolab::readFreebusy(*it, true); } else if (vm.count("note")) { Kolab::readNote(*it, true); } else if (vm.count("configuration")) { Kolab::readConfiguration(*it, true); } else if (vm.count("file")) { Kolab::readFile(*it, true); } else { cout << "Specify type"; return -1; } if (Kolab::error()) { cout << "Error: " << Kolab::errorMessage() << endl; return -1; } else { cout << "Parsed message without error." << endl; } } return 0; }libkolabxml-1.1.2/utils/zonetabconversion.py000077500000000000000000000014441262531651400213100ustar00rootroot00000000000000#!/bin/python2.7 tztable = open("tztable.h", "w") tztable.write("//This file was generated by the zonetabconversion.py script\n"); tztable.write("static const char* olsonTimezones[] = {\n"); zonefile = open("/usr/share/zoneinfo/zone.tab", "r") first = True for line in zonefile: # print line if line.startswith('#'): # print "continue" continue else: tz = line.split(None)[2] print tz if first: first = False tztable.write(" \"") else: tztable.write(",\n \"") tztable.write(tz) tztable.write("\"") tztable.write("\n};\n") tztable.write("\n") tztable.write("static const int numOlsonTimezones = sizeof olsonTimezones / sizeof *olsonTimezones;\n") tztable.write("\n")