Imported Upstream version 1.2
authorRuss Allbery <rra@debian.org>
Wed, 5 Aug 2009 22:35:34 +0000 (15:35 -0700)
committerRuss Allbery <rra@debian.org>
Wed, 5 Aug 2009 22:35:34 +0000 (15:35 -0700)
110 files changed:
Makefile.am
Makefile.in
config.h.in
config_win32.h
configure
configure.ac
cpp-xmltooling.sln
depend
doc/README.txt
doxygen.m4
pkginfo
postinstall
xmltooling.spec
xmltooling.spec.in
xmltooling/AbstractAttributeExtensibleXMLObject.cpp
xmltooling/AbstractComplexElement.cpp
xmltooling/AbstractDOMCachingXMLObject.cpp
xmltooling/AbstractXMLObject.cpp
xmltooling/Makefile.am
xmltooling/Makefile.in
xmltooling/Namespace.cpp
xmltooling/QName.cpp
xmltooling/XMLObjectBuilder.cpp
xmltooling/XMLToolingConfig.cpp
xmltooling/base.h
xmltooling/char_traits.h [new file with mode: 0644]
xmltooling/config_pub.h
xmltooling/config_pub.h.in
xmltooling/config_pub_win32.h
xmltooling/encryption/Encryption.h
xmltooling/encryption/impl/Decrypter.cpp
xmltooling/encryption/impl/Encrypter.cpp
xmltooling/encryption/impl/EncryptionImpl.cpp
xmltooling/exceptions.cpp
xmltooling/impl/AnyElement.cpp
xmltooling/impl/MemoryStorageService.cpp
xmltooling/impl/UnknownElement.cpp
xmltooling/internal.h
xmltooling/io/AbstractXMLObjectMarshaller.cpp
xmltooling/io/AbstractXMLObjectUnmarshaller.cpp
xmltooling/io/GenericRequest.h
xmltooling/security/AbstractPKIXTrustEngine.h
xmltooling/security/BasicX509Credential.h
xmltooling/security/SecurityHelper.h [new file with mode: 0644]
xmltooling/security/X509Credential.h
xmltooling/security/impl/AbstractPKIXTrustEngine.cpp
xmltooling/security/impl/BasicX509Credential.cpp
xmltooling/security/impl/ChainingCredentialResolver.cpp
xmltooling/security/impl/ChainingTrustEngine.cpp
xmltooling/security/impl/CredentialCriteria.cpp
xmltooling/security/impl/CredentialResolver.cpp
xmltooling/security/impl/ExplicitKeyTrustEngine.cpp
xmltooling/security/impl/FilesystemCredentialResolver.cpp
xmltooling/security/impl/InlineKeyResolver.cpp
xmltooling/security/impl/KeyInfoResolver.cpp
xmltooling/security/impl/SecurityHelper.cpp [new file with mode: 0644]
xmltooling/security/impl/StaticPKIXTrustEngine.cpp
xmltooling/security/impl/TrustEngine.cpp
xmltooling/signature/impl/KeyInfoImpl.cpp
xmltooling/signature/impl/XMLSecSignatureImpl.cpp
xmltooling/soap/SOAP.h
xmltooling/soap/SOAPTransport.h
xmltooling/soap/impl/CURLSOAPTransport.cpp
xmltooling/soap/impl/SOAPClient.cpp
xmltooling/soap/impl/SOAPImpl.cpp
xmltooling/unicode.cpp
xmltooling/unicode.h
xmltooling/util/CurlNetAccessor.cpp [deleted file]
xmltooling/util/CurlNetAccessor.hpp [deleted file]
xmltooling/util/CurlURLInputStream.cpp
xmltooling/util/CurlURLInputStream.h [new file with mode: 0644]
xmltooling/util/CurlURLInputStream.hpp [deleted file]
xmltooling/util/DateTime.cpp
xmltooling/util/DateTime.h
xmltooling/util/ParserPool.cpp
xmltooling/util/ParserPool.h
xmltooling/util/PathResolver.cpp
xmltooling/util/PathResolver.h
xmltooling/util/ReloadableXMLFile.cpp
xmltooling/util/ReloadableXMLFile.h
xmltooling/util/StorageService.cpp
xmltooling/util/TemplateEngine.cpp
xmltooling/util/TemplateEngine.h
xmltooling/util/Threads.h
xmltooling/util/URLEncoder.h
xmltooling/util/Win32Threads.cpp
xmltooling/util/XMLConstants.cpp
xmltooling/util/XMLHelper.cpp
xmltooling/util/XMLHelper.h
xmltooling/version.h
xmltooling/xmltooling-lite.vcproj
xmltooling/xmltooling.rc
xmltooling/xmltooling.vcproj
xmltoolingtest/ComplexXMLObjectTest.h
xmltoolingtest/DateTimeTest.h [new file with mode: 0644]
xmltoolingtest/Makefile.am
xmltoolingtest/Makefile.in
xmltoolingtest/MarshallingTest.h
xmltoolingtest/SecurityHelperTest.h [new file with mode: 0644]
xmltoolingtest/SignatureTest.h
xmltoolingtest/TemplateEngineTest.h
xmltoolingtest/UnmarshallingTest.h
xmltoolingtest/XMLObjectBaseTestCase.h
xmltoolingtest/data/cert.der [new file with mode: 0644]
xmltoolingtest/data/key.der [new file with mode: 0644]
xmltoolingtest/data/key2.pem [new file with mode: 0644]
xmltoolingtest/data/template.in
xmltoolingtest/data/template.out
xmltoolingtest/data/test.pfx [new file with mode: 0644]
xmltoolingtest/xmltoolingtest.vcproj

index 89132b2..ebcdeb3 100644 (file)
@@ -15,7 +15,6 @@ SUBDIRS = doc schemas xmltooling xmltoolingtest
 
 if DX_COND_doc
 all-local: doxygen-doc xmltooling.spec pkginfo
-APIDOCS = doc/api
 else
 all-local: xmltooling.spec pkginfo
 endif
@@ -37,7 +36,6 @@ pkginfo: pkginfo.in Makefile
        mv $@.tmp $@
 
 EXTRA_DIST = $(DX_CONFIG) \
-        $(APIDOCS) \
         cpp-xmltooling.sln \
         acx_pthread.m4 \
         acinclude.m4 \
index a10e90e..c0cf9ed 100644 (file)
@@ -299,9 +299,7 @@ ACLOCAL_AMFLAGS = -I .
 
 MOSTLYCLEANFILES = $(DX_CLEANFILES)
 SUBDIRS = doc schemas xmltooling xmltoolingtest
-@DX_COND_doc_TRUE@APIDOCS = doc/api
 EXTRA_DIST = $(DX_CONFIG) \
-        $(APIDOCS) \
         cpp-xmltooling.sln \
         acx_pthread.m4 \
         acinclude.m4 \
@@ -517,7 +515,6 @@ distclean-tags:
 distdir: $(DISTFILES)
        $(am__remove_distdir)
        mkdir $(distdir)
-       $(mkdir_p) $(distdir)/doc
        @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
        list='$(DISTFILES)'; for file in $$list; do \
index cd91c9e..13bb04d 100644 (file)
@@ -1,12 +1,12 @@
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
-/* Define if C++ compiler supports covariant virtual methods. */
+/* Define to 1 if C++ compiler supports covariant virtual methods. */
 #undef HAVE_COVARIANT_RETURNS
 
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
-/* Define if you have an STL implementation that supports useful string
+/* Define to 1 if you have an STL implementation that supports useful string
    specialization. */
 #undef HAVE_GOOD_STL
 
@@ -23,7 +23,7 @@
 /* Define to 1 if you have the `dl' library (-ldl). */
 #undef HAVE_LIBDL
 
-/* Define if Xerces-C library was found */
+/* Define to 1 if Xerces-C library was found */
 #undef HAVE_LIBXERCESC
 
 /* Define to 1 if you have the <memory.h> header file. */
@@ -74,6 +74,9 @@
 /* Define to 1 if you have the <unistd.h> header file. */
 #undef HAVE_UNISTD_H
 
+/* Define to 1 if you have the 'xsecsize_t' type. */
+#undef HAVE_XSECSIZE_T
+
 /* Name of package */
 #undef PACKAGE
 
 /* Version number of package */
 #undef VERSION
 
-/* Define if log4cpp library is used. */
+/* Define to 1 if log4cpp library is used. */
 #undef XMLTOOLING_LOG4CPP
 
-/* Define if log4shib library is used. */
+/* Define to 1 if log4shib library is used. */
 #undef XMLTOOLING_LOG4SHIB
 
-/* Define if you wish to disable XML-Security-dependent features. */
+/* Define to 1 if you wish to disable XML-Security-dependent features. */
 #undef XMLTOOLING_NO_XMLSEC
 
+/* Define to 1 if Xerces has a 64-bit-safe API. */
+#undef XMLTOOLING_XERCESC_64BITSAFE
+
+/* Define to 1 if Xerces DOM ID methods take extra parameter. */
+#undef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+
+/* Define to 1 if Xerces supports a compliant DOMLS API. */
+#undef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+
+/* Define to 1 if Xerces InputStream class requires getContentType. */
+#undef XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
index 2f9815a..d2c25c1 100644 (file)
 /* Define to 1 if you have the <unistd.h> header file. */
 /* #undef HAVE_UNISTD_H */
 
+#include <xercesc/util/XercesVersion.hpp>
+
+#if (XERCES_VERSION_MAJOR >= 3)
+# define XMLTOOLING_XERCESC_COMPLIANT_DOMLS     1
+# define XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE  1
+# define XMLTOOLING_XERCESC_64BITSAFE           1
+# define XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE 1
+#endif
+
+/* Define to 1 if you have the `xsecsize_t' type. */
+#define HAVE_XSECSIZE_T 1
+
 /* Name of package */
 #define PACKAGE "xmltooling"
 
 #define PACKAGE_NAME "xmltooling"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "xmltooling 1.0"
+#define PACKAGE_STRING "xmltooling 1.2"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "xmltooling"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0"
+#define PACKAGE_VERSION "1.2"
 
 /* Define to the necessary symbol if this constant uses a non-standard name on
    your system. */
 /* #undef TM_IN_SYS_TIME */
 
 /* Version number of package */
-#define VERSION "1.0"
+#define VERSION "1.2"
 
 /* Define if you wish to disable XML-Security-dependent features. */
 /* #undef XMLTOOLING_NO_XMLSEC */
index e88aa56..6ae3f27 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for xmltooling 1.1.
+# Generated by GNU Autoconf 2.59 for xmltooling 1.2.
 #
 # Report bugs to <mace-opensaml-users@internet2.edu>.
 #
@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='xmltooling'
 PACKAGE_TARNAME='xmltooling'
-PACKAGE_VERSION='1.1'
-PACKAGE_STRING='xmltooling 1.1'
+PACKAGE_VERSION='1.2'
+PACKAGE_STRING='xmltooling 1.2'
 PACKAGE_BUGREPORT='mace-opensaml-users@internet2.edu'
 
 # Factoring default headers for most tests.
@@ -464,7 +464,7 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DX_PROJECT DX_CONFIG DX_DOCDIR DX_ENV DX_FLAG_doc DX_DOXYGEN ac_pt_DX_DOXYGEN DX_FLAG_[]DX_CURRENT_FEATURE DX_PERL ac_pt_DX_PERL DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_doc_TRUE DX_COND_doc_FALSE DX_FLAG_dot DX_FLAG_[]DX_CURRENT_FEATURE DX_DOT ac_pt_DX_DOT DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_dot_TRUE DX_COND_dot_FALSE DX_FLAG_man DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_man_TRUE DX_COND_man_FALSE DX_FLAG_rtf DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_rtf_TRUE DX_COND_rtf_FALSE DX_FLAG_xml DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_xml_TRUE DX_COND_xml_FALSE DX_FLAG_chm DX_FLAG_[]DX_CURRENT_FEATURE DX_HHC ac_pt_DX_HHC DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_chm_TRUE DX_COND_chm_FALSE DX_FLAG_chi DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_chi_TRUE DX_COND_chi_FALSE DX_FLAG_html DX_FLAG_[]DX_CURRENT_FEATURE DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_html_TRUE DX_COND_html_FALSE DX_FLAG_ps DX_FLAG_[]DX_CURRENT_FEATURE DX_LATEX ac_pt_DX_LATEX DX_FLAG_[]DX_CURRENT_FEATURE DX_MAKEINDEX ac_pt_DX_MAKEINDEX DX_FLAG_[]DX_CURRENT_FEATURE DX_DVIPS ac_pt_DX_DVIPS DX_FLAG_[]DX_CURRENT_FEATURE DX_EGREP ac_pt_DX_EGREP DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_ps_TRUE DX_COND_ps_FALSE DX_FLAG_pdf DX_FLAG_[]DX_CURRENT_FEATURE DX_PDFLATEX ac_pt_DX_PDFLATEX DX_FLAG_[]DX_CURRENT_FEATURE DX_FLAG_[]DX_CURRENT_FEATURE DX_FLAG_[]DX_CURRENT_FEATURE DX_COND_pdf_TRUE DX_COND_pdf_FALSE DX_COND_latex_TRUE DX_COND_latex_FALSE DOXYGEN_PAPER_SIZE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS BUILD_PTHREAD_TRUE BUILD_PTHREAD_FALSE LOG4SHIB_CONFIG LOG4CPP_CONFIG PKG_CONFIG CURL_CONFIG XMLSEC_LIBS BUILD_XMLSEC_TRUE BUILD_XMLSEC_FALSE CXXTEST CXXTESTFLAGS BUILD_UNITTEST_TRUE BUILD_UNITTEST_FALSE LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DX_PROJECT DX_CONFIG DX_DOCDIR DX_ENV DX_FLAG_doc DX_DOXYGEN ac_pt_DX_DOXYGEN DX_PERL ac_pt_DX_PERL DX_COND_doc_TRUE DX_COND_doc_FALSE DX_FLAG_dot DX_DOT ac_pt_DX_DOT DX_COND_dot_TRUE DX_COND_dot_FALSE DX_FLAG_man DX_COND_man_TRUE DX_COND_man_FALSE DX_FLAG_rtf DX_COND_rtf_TRUE DX_COND_rtf_FALSE DX_FLAG_xml DX_COND_xml_TRUE DX_COND_xml_FALSE DX_FLAG_chm DX_HHC ac_pt_DX_HHC DX_COND_chm_TRUE DX_COND_chm_FALSE DX_FLAG_chi DX_COND_chi_TRUE DX_COND_chi_FALSE DX_FLAG_html DX_COND_html_TRUE DX_COND_html_FALSE DX_FLAG_ps DX_LATEX ac_pt_DX_LATEX DX_MAKEINDEX ac_pt_DX_MAKEINDEX DX_DVIPS ac_pt_DX_DVIPS DX_EGREP ac_pt_DX_EGREP DX_COND_ps_TRUE DX_COND_ps_FALSE DX_FLAG_pdf DX_PDFLATEX ac_pt_DX_PDFLATEX DX_COND_pdf_TRUE DX_COND_pdf_FALSE DX_COND_latex_TRUE DX_COND_latex_FALSE DOXYGEN_PAPER_SIZE CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE build build_cpu build_vendor build_os host host_cpu host_vendor host_os EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL acx_pthread_config PTHREAD_CC PTHREAD_LIBS PTHREAD_CFLAGS BUILD_PTHREAD_TRUE BUILD_PTHREAD_FALSE LOG4SHIB_CONFIG LOG4CPP_CONFIG PKG_CONFIG CURL_CONFIG XMLSEC_LIBS BUILD_XMLSEC_TRUE BUILD_XMLSEC_FALSE CXXTEST CXXTESTFLAGS BUILD_UNITTEST_TRUE BUILD_UNITTEST_FALSE LIBOBJS LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -957,7 +957,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures xmltooling 1.1 to adapt to many kinds of systems.
+\`configure' configures xmltooling 1.2 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1023,7 +1023,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of xmltooling 1.1:";;
+     short | recursive ) echo "Configuration of xmltooling 1.2:";;
    esac
   cat <<\_ACEOF
 
@@ -1183,7 +1183,7 @@ fi
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-xmltooling configure 1.1
+xmltooling configure 1.2
 generated by GNU Autoconf 2.59
 
 Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1197,7 +1197,7 @@ cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by xmltooling $as_me 1.1, which was
+It was created by xmltooling $as_me 1.2, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
@@ -1844,7 +1844,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=xmltooling
- VERSION=1.1
+ VERSION=1.2
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2028,6 +2028,9 @@ DX_ENV=""
 
 
 
+# Compatibility with older autoconf versions.
+
+
 ## --------------- ##
 ## Private macros. ##
 ## --------------- ##
@@ -6081,7 +6084,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6084 "configure"' > conftest.$ac_ext
+  echo '#line 6087 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7189,7 +7192,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:7192:" \
+echo "$as_me:7195:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -8227,11 +8230,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8230: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8233: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8234: \$? = $ac_status" >&5
+   echo "$as_me:8237: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -8460,11 +8463,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8463: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8466: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8467: \$? = $ac_status" >&5
+   echo "$as_me:8470: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -8520,11 +8523,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8523: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8526: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8527: \$? = $ac_status" >&5
+   echo "$as_me:8530: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -9854,7 +9857,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 9857 "configure"' > conftest.$ac_ext
+    echo '#line 9860 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -10725,7 +10728,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10728 "configure"
+#line 10731 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10823,7 +10826,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10826 "configure"
+#line 10829 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -13006,11 +13009,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13009: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13012: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13013: \$? = $ac_status" >&5
+   echo "$as_me:13016: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -13066,11 +13069,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13069: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13072: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13073: \$? = $ac_status" >&5
+   echo "$as_me:13076: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -13577,7 +13580,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 13580 "configure"' > conftest.$ac_ext
+    echo '#line 13583 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -14448,7 +14451,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 14451 "configure"
+#line 14454 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -14546,7 +14549,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 14549 "configure"
+#line 14552 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -15373,11 +15376,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15376: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15379: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15380: \$? = $ac_status" >&5
+   echo "$as_me:15383: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -15433,11 +15436,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15436: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15439: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:15440: \$? = $ac_status" >&5
+   echo "$as_me:15443: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -16747,7 +16750,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 16750 "configure"' > conftest.$ac_ext
+    echo '#line 16753 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -17492,11 +17495,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17495: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17498: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17499: \$? = $ac_status" >&5
+   echo "$as_me:17502: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -17725,11 +17728,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17728: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17731: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:17732: \$? = $ac_status" >&5
+   echo "$as_me:17735: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
@@ -17785,11 +17788,11 @@ else
    -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:17788: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:17791: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:17792: \$? = $ac_status" >&5
+   echo "$as_me:17795: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -19119,7 +19122,7 @@ linux*)
   libsuff=
   case "$host_cpu" in
   x86_64*|s390x*|powerpc64*)
-    echo '#line 19122 "configure"' > conftest.$ac_ext
+    echo '#line 19125 "configure"' > conftest.$ac_ext
     if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -19990,7 +19993,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 19993 "configure"
+#line 19996 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -20088,7 +20091,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 20091 "configure"
+#line 20094 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
 
+echo "$as_me:$LINENO: checking whether Xerces is 64-bit clean" >&5
+echo $ECHO_N "checking whether Xerces is 64-bit clean... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <xercesc/framework/MemBufInputSource.hpp>
+int
+main ()
+{
+using namespace XERCES_CPP_NAMESPACE;
+      XMLFilePos testvar;
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define XMLTOOLING_XERCESC_64BITSAFE 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking whether Xerces BinInputStream requires getContentType" >&5
+echo $ECHO_N "checking whether Xerces BinInputStream requires getContentType... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <xercesc/util/BinMemInputStream.hpp>
+int
+main ()
+{
+using namespace XERCES_CPP_NAMESPACE;
+      XMLByte buf[1024];
+      BinMemInputStream in(buf,1024);
+      in.getContentType();
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking whether Xerces DOMLS API is compliant" >&5
+echo $ECHO_N "checking whether Xerces DOMLS API is compliant... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <xercesc/dom/DOM.hpp>
+int
+main ()
+{
+using namespace XERCES_CPP_NAMESPACE;
+        DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(NULL);
+        DOMLSSerializer *ls = ((DOMImplementationLS*)impl)->createLSSerializer();
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define XMLTOOLING_XERCESC_COMPLIANT_DOMLS 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+echo "$as_me:$LINENO: checking whether Xerces has setIdAttribute(XMLCh*, bool)" >&5
+echo $ECHO_N "checking whether Xerces has setIdAttribute(XMLCh*, bool)... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <xercesc/dom/DOM.hpp>
+int
+main ()
+{
+using namespace XERCES_CPP_NAMESPACE;
+          DOMElement * elt;
+          elt->setIdAttribute(NULL, false);
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
 
 # XML-Security settings
 
@@ -24321,6 +24555,70 @@ echo "$as_me: error: unable to link with XML-Security" >&2;}
 fi
 rm -f conftest.err conftest.$ac_objext \
       conftest$ac_exeext conftest.$ac_ext
+    echo "$as_me:$LINENO: checking for xsecsize_t" >&5
+echo $ECHO_N "checking for xsecsize_t... $ECHO_C" >&6
+if test "${ac_cv_type_xsecsize_t+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+int
+main ()
+{
+if ((xsecsize_t *) 0)
+  return 0;
+if (sizeof (xsecsize_t))
+  return 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_cxx_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_type_xsecsize_t=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_type_xsecsize_t=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_type_xsecsize_t" >&5
+echo "${ECHO_T}$ac_cv_type_xsecsize_t" >&6
+if test $ac_cv_type_xsecsize_t = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_XSECSIZE_T 1
+_ACEOF
+
+fi
+
 
        # restore master libs
        LIBS="$save_LIBS"
@@ -25352,7 +25650,7 @@ _ASBOX
 } >&5
 cat >&5 <<_CSEOF
 
-This file was extended by xmltooling $as_me 1.1, which was
+This file was extended by xmltooling $as_me 1.2, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -25415,7 +25713,7 @@ _ACEOF
 
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-xmltooling config.status 1.1
+xmltooling config.status 1.2
 configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -25647,70 +25945,49 @@ s,@DX_ENV@,$DX_ENV,;t t
 s,@DX_FLAG_doc@,$DX_FLAG_doc,;t t
 s,@DX_DOXYGEN@,$DX_DOXYGEN,;t t
 s,@ac_pt_DX_DOXYGEN@,$ac_pt_DX_DOXYGEN,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_PERL@,$DX_PERL,;t t
 s,@ac_pt_DX_PERL@,$ac_pt_DX_PERL,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_doc_TRUE@,$DX_COND_doc_TRUE,;t t
 s,@DX_COND_doc_FALSE@,$DX_COND_doc_FALSE,;t t
 s,@DX_FLAG_dot@,$DX_FLAG_dot,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_DOT@,$DX_DOT,;t t
 s,@ac_pt_DX_DOT@,$ac_pt_DX_DOT,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_dot_TRUE@,$DX_COND_dot_TRUE,;t t
 s,@DX_COND_dot_FALSE@,$DX_COND_dot_FALSE,;t t
 s,@DX_FLAG_man@,$DX_FLAG_man,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_man_TRUE@,$DX_COND_man_TRUE,;t t
 s,@DX_COND_man_FALSE@,$DX_COND_man_FALSE,;t t
 s,@DX_FLAG_rtf@,$DX_FLAG_rtf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_rtf_TRUE@,$DX_COND_rtf_TRUE,;t t
 s,@DX_COND_rtf_FALSE@,$DX_COND_rtf_FALSE,;t t
 s,@DX_FLAG_xml@,$DX_FLAG_xml,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_xml_TRUE@,$DX_COND_xml_TRUE,;t t
 s,@DX_COND_xml_FALSE@,$DX_COND_xml_FALSE,;t t
 s,@DX_FLAG_chm@,$DX_FLAG_chm,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_HHC@,$DX_HHC,;t t
 s,@ac_pt_DX_HHC@,$ac_pt_DX_HHC,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_chm_TRUE@,$DX_COND_chm_TRUE,;t t
 s,@DX_COND_chm_FALSE@,$DX_COND_chm_FALSE,;t t
 s,@DX_FLAG_chi@,$DX_FLAG_chi,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_chi_TRUE@,$DX_COND_chi_TRUE,;t t
 s,@DX_COND_chi_FALSE@,$DX_COND_chi_FALSE,;t t
 s,@DX_FLAG_html@,$DX_FLAG_html,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_html_TRUE@,$DX_COND_html_TRUE,;t t
 s,@DX_COND_html_FALSE@,$DX_COND_html_FALSE,;t t
 s,@DX_FLAG_ps@,$DX_FLAG_ps,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_LATEX@,$DX_LATEX,;t t
 s,@ac_pt_DX_LATEX@,$ac_pt_DX_LATEX,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_MAKEINDEX@,$DX_MAKEINDEX,;t t
 s,@ac_pt_DX_MAKEINDEX@,$ac_pt_DX_MAKEINDEX,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_DVIPS@,$DX_DVIPS,;t t
 s,@ac_pt_DX_DVIPS@,$ac_pt_DX_DVIPS,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_EGREP@,$DX_EGREP,;t t
 s,@ac_pt_DX_EGREP@,$ac_pt_DX_EGREP,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_ps_TRUE@,$DX_COND_ps_TRUE,;t t
 s,@DX_COND_ps_FALSE@,$DX_COND_ps_FALSE,;t t
 s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_PDFLATEX@,$DX_PDFLATEX,;t t
 s,@ac_pt_DX_PDFLATEX@,$ac_pt_DX_PDFLATEX,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
-s,@DX_FLAG_pdf@,$DX_FLAG_pdf,;t t
 s,@DX_COND_pdf_TRUE@,$DX_COND_pdf_TRUE,;t t
 s,@DX_COND_pdf_FALSE@,$DX_COND_pdf_FALSE,;t t
 s,@DX_COND_latex_TRUE@,$DX_COND_latex_TRUE,;t t
index 2edc85e..7caeb35 100644 (file)
@@ -1,8 +1,8 @@
 AC_PREREQ([2.50])
-AC_INIT([xmltooling], [1.1], [mace-opensaml-users@internet2.edu], [xmltooling])
+AC_INIT([xmltooling], [1.2], [mace-opensaml-users@internet2.edu], [xmltooling])
 AM_CONFIG_HEADER(config.h)
 AM_CONFIG_HEADER(xmltooling/config_pub.h)
-AM_INIT_AUTOMAKE([xmltooling], [1.1])
+AM_INIT_AUTOMAKE([xmltooling], [1.2])
 
 sinclude(doxygen.m4)
 sinclude(acx_pthread.m4)
@@ -92,7 +92,7 @@ AC_CXX_NAMESPACES
 AC_TRY_LINK(
      [ class base { public: virtual base *GetPtr( void ) { return this; } }; ],
      [ class derived: virtual public base { public: virtual derived *GetPtr( void ) { return this; } }; ],
-     [AC_DEFINE(HAVE_COVARIANT_RETURNS,1,[Define if C++ compiler supports covariant virtual methods.])])
+     [AC_DEFINE([HAVE_COVARIANT_RETURNS], [1], [Define to 1 if C++ compiler supports covariant virtual methods.])])
 
 # log4shib settings (favor this version over the log4cpp code)
 AC_PATH_PROG(LOG4SHIB_CONFIG,log4shib-config)
@@ -112,7 +112,7 @@ if test -f "${LOG4SHIB_CONFIG}"; then
                [#include <log4shib/Category.hh>
 #include <log4shib/CategoryStream.hh>],
                [log4shib::Category::getInstance("foo").errorStream() << log4shib::eol],
-               [AC_DEFINE(XMLTOOLING_LOG4SHIB,1,[Define if log4shib library is used.])],
+               [AC_DEFINE([XMLTOOLING_LOG4SHIB], [1], [Define to 1 if log4shib library is used.])],
                [AC_MSG_ERROR([unable to link with log4shib])])
 else
     AC_MSG_WARN([log4shib-config not found, may need to use --with-log4shib option])
@@ -137,7 +137,7 @@ else
                        [#include <log4cpp/Category.hh>
 #include <log4cpp/CategoryStream.hh>],
                        [log4cpp::Category::getInstance("foo").errorStream() << log4cpp::eol],
-                       [AC_DEFINE(XMLTOOLING_LOG4CPP,1,[Define if log4cpp library is used.])],
+                       [AC_DEFINE([XMLTOOLING_LOG4CPP], [1], [Define to 1 if log4cpp library is used.])],
                        [AC_MSG_ERROR([unable to link with log4cpp, need version 1.0 or later])])
        else
            AC_MSG_ERROR([log4cpp-config not found, may need to use --with-log4cpp option])
@@ -166,9 +166,48 @@ int i = 0;
 AC_TRY_LINK(
         [#include <xercesc/util/PlatformUtils.hpp>],
         [xercesc::XMLPlatformUtils::Initialize()],
-        [AC_DEFINE(HAVE_LIBXERCESC,1,[Define if Xerces-C library was found])],
+        [AC_DEFINE([HAVE_LIBXERCESC], [1], [Define to 1 if Xerces-C library was found])],
         [AC_MSG_ERROR([unable to link with Xerces])])
 
+AC_MSG_CHECKING([whether Xerces is 64-bit clean])
+AC_TRY_COMPILE([#include <xercesc/framework/MemBufInputSource.hpp>],
+    [using namespace XERCES_CPP_NAMESPACE;
+      XMLFilePos testvar;
+    ],
+    [AC_MSG_RESULT([yes])]
+    [AC_DEFINE([XMLTOOLING_XERCESC_64BITSAFE], [1], [Define to 1 if Xerces has a 64-bit-safe API.])],
+    [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether Xerces BinInputStream requires getContentType])
+AC_TRY_COMPILE([#include <xercesc/util/BinMemInputStream.hpp>],
+    [using namespace XERCES_CPP_NAMESPACE;
+      XMLByte buf[1024];
+      BinMemInputStream in(buf,1024);
+      in.getContentType();
+    ],
+    [AC_MSG_RESULT([yes])]
+    [AC_DEFINE([XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE], [1], [Define to 1 if Xerces InputStream class requires getContentType.])],
+    [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether Xerces DOMLS API is compliant])
+AC_TRY_COMPILE([#include <xercesc/dom/DOM.hpp>],
+    [using namespace XERCES_CPP_NAMESPACE;
+        DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(NULL);
+        DOMLSSerializer *ls = ((DOMImplementationLS*)impl)->createLSSerializer();
+    ],
+    [AC_MSG_RESULT([yes])]
+    [AC_DEFINE([XMLTOOLING_XERCESC_COMPLIANT_DOMLS], [1], [Define to 1 if Xerces supports a compliant DOMLS API.])],
+    [AC_MSG_RESULT([no])])
+
+AC_MSG_CHECKING([whether Xerces has setIdAttribute(XMLCh*, bool)])
+AC_TRY_COMPILE([#include <xercesc/dom/DOM.hpp>],
+      [using namespace XERCES_CPP_NAMESPACE;
+          DOMElement * elt;
+          elt->setIdAttribute(NULL, false);
+      ],
+      [AC_MSG_RESULT([yes])]
+      [AC_DEFINE([XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE], [1], [Define to 1 if Xerces DOM ID methods take extra parameter.])],
+      [AC_MSG_RESULT([no])])
 
 # XML-Security settings
 AC_ARG_WITH(xmlsec,
@@ -249,6 +288,7 @@ int i = 0;
             [#include <xsec/utils/XSECPlatformUtils.hpp>],
             [XSECPlatformUtils::Initialise()],,
             [AC_MSG_ERROR([unable to link with XML-Security])])
+    AC_CHECK_TYPE([xsecsize_t],[AC_DEFINE([HAVE_XSECSIZE_T], [1], [Define to 1 if you have the 'xsecsize_t' type.])])
 
        # restore master libs
        LIBS="$save_LIBS"
@@ -287,8 +327,7 @@ int i = 0;
        AC_SUBST(XMLSEC_LIBS)
 else
     AC_MSG_WARN([xmlsec disabled, building without signature/encryption support])
-    AC_DEFINE(XMLTOOLING_NO_XMLSEC,1,
-        [Define if you wish to disable XML-Security-dependent features.])
+    AC_DEFINE([XMLTOOLING_NO_XMLSEC], [1], [Define to 1 if you wish to disable XML-Security-dependent features.])
 fi
 AM_CONDITIONAL(BUILD_XMLSEC,test x_$with_xmlsec != x_no)
 
@@ -296,13 +335,13 @@ AM_CONDITIONAL(BUILD_XMLSEC,test x_$with_xmlsec != x_no)
 AC_TRY_LINK(
         [#include <string>],
         [std::basic_string<unsigned short> foo; foo=foo+(unsigned short)65],
-        [AC_DEFINE(HAVE_GOOD_STL,1,
-            [Define if you have an STL implementation that supports useful string specialization.])],
+        [AC_DEFINE([HAVE_GOOD_STL], [1],
+            [Define to 1 if you have an STL implementation that supports useful string specialization.])],
         )
 AC_TRY_LINK(
         [#include <vector>],
         [std::iterator_traits<std::vector<int>::iterator>::value_type foo=0],
-        [AC_DEFINE(HAVE_ITERATOR_TRAITS,1,
+        [AC_DEFINE([HAVE_ITERATOR_TRAITS], [1],
             [Define to 1 if you have an STL implementation that supports std::iterator_traits.])],
         )
 
index f980d37..fc5fdc9 100644 (file)
@@ -1,26 +1,14 @@
 ï»¿\r
-Microsoft Visual Studio Solution File, Format Version 9.00\r
-# Visual Studio 2005\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual Studio 2008\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltooling", "xmltooling\xmltooling.vcproj", "{06B55A46-D3B3-41AE-B5A5-B57830BA010D}"\r
-       ProjectSection(WebsiteProperties) = preProject\r
-               Debug.AspNetCompiler.Debug = "True"\r
-               Release.AspNetCompiler.Debug = "False"\r
-       EndProjectSection\r
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltoolingtest", "xmltoolingtest\xmltoolingtest.vcproj", "{3E34CDCC-FCBA-490D-A165-1CB6F4559799}"\r
-       ProjectSection(WebsiteProperties) = preProject\r
-               Debug.AspNetCompiler.Debug = "True"\r
-               Release.AspNetCompiler.Debug = "False"\r
-       EndProjectSection\r
        ProjectSection(ProjectDependencies) = postProject\r
                {06B55A46-D3B3-41AE-B5A5-B57830BA010D} = {06B55A46-D3B3-41AE-B5A5-B57830BA010D}\r
        EndProjectSection\r
 EndProject\r
 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xmltooling-lite", "xmltooling\xmltooling-lite.vcproj", "{06B55A46-D3B3-41AE-B5A5-B57830BA010E}"\r
-       ProjectSection(WebsiteProperties) = preProject\r
-               Debug.AspNetCompiler.Debug = "True"\r
-               Release.AspNetCompiler.Debug = "False"\r
-       EndProjectSection\r
 EndProject\r
 Global\r
        GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
diff --git a/depend b/depend
index f3ebd3e..cb6591d 100644 (file)
--- a/depend
+++ b/depend
@@ -1,5 +1,5 @@
 P SHIBossl OpenSSL
-       0.9.8g
+       0.9.8h
 P SHIBxerces xerces-c
        2.8.0
 P SHIBxmlsec xml-security-c
index 1f9cd13..81ece25 100644 (file)
@@ -1,8 +1,8 @@
-VERSION 1.1\r
+VERSION 1.2\r
 \r
 Issues addressed by this release:\r
 ---------------------------------\r
-https://bugs.internet2.edu/jira/secure/IssueNavigator.jspa?reset=true&&pid=10009&fixfor=10134&status=5&status=6&sorter/field=issuekey&sorter/order=ASC\r
+https://bugs.internet2.edu/jira/secure/IssueNavigator.jspa?reset=true&&pid=10009&fixfor=10161&status=5&status=6&sorter/field=issuekey&sorter/order=ASC\r
 \r
 Documentation:\r
 --------------\r
index e4688de..9bda4f6 100644 (file)
@@ -51,6 +51,9 @@ AC_DEFUN([DX_FEATURE_xml],  OFF)
 AC_DEFUN([DX_FEATURE_pdf],  ON)
 AC_DEFUN([DX_FEATURE_ps],   ON)
 
+# Compatibility with older autoconf versions.
+m4_ifdef([AS_HELP_STRING], , [m4_define([AS_HELP_STRING], m4_defn([AC_HELP_STRING]))])
+
 ## --------------- ##
 ## Private macros. ##
 ## --------------- ##
@@ -78,7 +81,7 @@ AC_DEFUN([DX_REQUIRE_PROG], [
 AC_PATH_TOOL([$1], [$2])
 if test "$DX_FLAG_[]DX_CURRENT_FEATURE$$1" = 1; then
     AC_MSG_WARN([$2 not found - will not DX_CURRENT_DESCRIPTION])
-    AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+    AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
 fi
 ])
 
@@ -101,7 +104,7 @@ test "$DX_FLAG_$1" = "$2" \
 # ----------------------------------------------------------
 # Turn off the DX_CURRENT_FEATURE if the required feature is off.
 AC_DEFUN([DX_CLEAR_DEPEND], [
-test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_[]DX_CURRENT_FEATURE], 0)
+test "$DX_FLAG_$1" = "$2" || AC_SUBST([DX_FLAG_]DX_CURRENT_FEATURE, 0)
 ])
 
 # DX_FEATURE_ARG(FEATURE, DESCRIPTION,
diff --git a/pkginfo b/pkginfo
index 3b210ae..f7c02fe 100644 (file)
--- a/pkginfo
+++ b/pkginfo
@@ -1,5 +1,5 @@
 PKG=SHIBxmltool
-VERSION=1.1
+VERSION=1.2
 NAME=xmltooling-c
 CATEGORY=application,textproc,security
 DESC=Library for DOM processing with Signature/Encryption for C++
index 6301db6..bc80af9 100644 (file)
@@ -2,7 +2,7 @@
 
 cd ${CLIENT_BASEDIR}/share/xml/xmltooling
 
-sed "s|uri=\".*${CLIENT_BASEDIR}|uri=\"${CLIENT_BASEDIR}|1" catalog.xml > catalog.xml.tmp
+sed "s|uri=\".*/share/xml/xmltooling/\(.*\)\"|uri=\"${CLIENT_BASEDIR}/share/xml/xmltooling/\1\"|1" catalog.xml > catalog.xml.tmp
 mv catalog.xml.tmp catalog.xml
 chmod 644 catalog.xml
 
index 75abc36..800b74a 100644 (file)
@@ -1,6 +1,6 @@
 Name:          xmltooling
 Summary:       Open source XMLTooling library
-Version:       1.1
+Version:       1.2
 Release:       1
 Group:         System Environment/Libraries
 Vendor:                Internet2
@@ -8,7 +8,11 @@ License:       Apache 2.0
 URL:           http://www.opensaml.org/
 Source0:       %{name}-%{version}.tar.gz
 BuildRoot:     %{_tmppath}/%{name}-%{version}-root
+%if 0%{?suse_version} > 1030
+BuildRequires:  libXerces-c-devel >= 2.8.0
+%else
 BuildRequires:  xerces%{?xercesver}-c-devel >= 2.8.0
+%endif
 BuildRequires: xml-security-c-devel >= 1.4.0
 BuildRequires: openssl-devel, curl-devel >= 7.10.6
 %{?_with_log4cpp:BuildRequires:        log4cpp-devel >= 1.0}
@@ -27,6 +31,15 @@ This package contains the xmltooling runtime library.
 Summary: XMLTooling development Headers
 Group: Development/Libraries
 Requires: %{name} = %{version}
+%if 0%{?suse_version} > 1030
+Requires: libXerces-c-devel >= 2.8.0
+%else
+Requires: xerces%{?xercesver}-c-devel >= 2.8.0
+%endif
+Requires: xml-security-c-devel >= 1.4.0
+Requires: openssl-devel, curl-devel >= 7.10.6
+%{?_with_log4cpp:Requires: log4cpp-devel >= 1.0}
+%{!?_with_log4cpp:Requires: log4shib-devel}
 
 %description devel
 The XMLTooling library contains generic XML parsing and processing
@@ -59,7 +72,7 @@ XMLTooling Library API documentation generated by doxygen.
 find $RPM_BUILD_ROOT/%{_bindir} -type f |
   %{__sed} -e "s|$RPM_BUILD_ROOT||" | sort > rpm.binlist
 
-%check || :
+%check
 %{__make} check
 
 %clean
@@ -98,6 +111,10 @@ find $RPM_BUILD_ROOT/%{_bindir} -type f |
 %doc %{_datadir}/doc/xmltooling/api
 
 %changelog
+* Wed Dec 3 2008  Scott Cantor  <cantor.2@osu.edu>  - 1.2-1
+- Bumping for minor update.
+- Fixing SUSE Xerces dependency name.
+
 * Tue Jul 1 2008  Scott Cantor  <cantor.2@osu.edu>  - 1.1-1
 - Bumping for minor update.
 
index 3537821..b016883 100644 (file)
@@ -8,7 +8,11 @@ License:       Apache 2.0
 URL:           http://www.opensaml.org/
 Source0:       %{name}-%{version}.tar.gz
 BuildRoot:     %{_tmppath}/%{name}-%{version}-root
+%if 0%{?suse_version} > 1030
+BuildRequires:  libXerces-c-devel >= 2.8.0
+%else
 BuildRequires:  xerces%{?xercesver}-c-devel >= 2.8.0
+%endif
 BuildRequires: xml-security-c-devel >= 1.4.0
 BuildRequires: openssl-devel, curl-devel >= 7.10.6
 %{?_with_log4cpp:BuildRequires:        log4cpp-devel >= 1.0}
@@ -27,6 +31,15 @@ This package contains the xmltooling runtime library.
 Summary: XMLTooling development Headers
 Group: Development/Libraries
 Requires: %{name} = %{version}
+%if 0%{?suse_version} > 1030
+Requires: libXerces-c-devel >= 2.8.0
+%else
+Requires: xerces%{?xercesver}-c-devel >= 2.8.0
+%endif
+Requires: xml-security-c-devel >= 1.4.0
+Requires: openssl-devel, curl-devel >= 7.10.6
+%{?_with_log4cpp:Requires: log4cpp-devel >= 1.0}
+%{!?_with_log4cpp:Requires: log4shib-devel}
 
 %description devel
 The XMLTooling library contains generic XML parsing and processing
@@ -59,7 +72,7 @@ XMLTooling Library API documentation generated by doxygen.
 find $RPM_BUILD_ROOT/%{_bindir} -type f |
   %{__sed} -e "s|$RPM_BUILD_ROOT||" | sort > rpm.binlist
 
-%check || :
+%check
 %{__make} check
 
 %clean
@@ -98,6 +111,10 @@ find $RPM_BUILD_ROOT/%{_bindir} -type f |
 %doc %{_datadir}/doc/xmltooling/api
 
 %changelog
+* Wed Dec 3 2008  Scott Cantor  <cantor.2@osu.edu>  - 1.2-1
+- Bumping for minor update.
+- Fixing SUSE Xerces dependency name.
+
 * Tue Jul 1 2008  Scott Cantor  <cantor.2@osu.edu>  - 1.1-1
 - Bumping for minor update.
 
index 2efde22..b24ee87 100644 (file)
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::DOMAttr;
+using xercesc::DOMElement;
+using xercesc::XMLString;
+
 set<QName> AttributeExtensibleXMLObject::m_idAttributeSet;
 
 AbstractAttributeExtensibleXMLObject::~AbstractAttributeExtensibleXMLObject()
@@ -80,7 +84,11 @@ void AbstractAttributeExtensibleXMLObject::unmarshallExtensionAttribute(const DO
     bool ID = attribute->isId() || isRegisteredIDAttribute(q);
     setAttribute(q,attribute->getNodeValue(),ID);
     if (ID) {
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+        attribute->getOwnerElement()->setIdAttributeNode(attribute, true);
+#else
         attribute->getOwnerElement()->setIdAttributeNode(attribute);
+#endif
     }
 }
 
@@ -92,7 +100,12 @@ void AbstractAttributeExtensibleXMLObject::marshallExtensionAttributes(DOMElemen
             attr->setPrefix(i->first.getPrefix());
         attr->setNodeValue(i->second);
         domElement->setAttributeNodeNS(attr);
-        if (m_idAttribute==i)
+        if (m_idAttribute==i) {
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+            domElement->setIdAttributeNode(attr, true);
+#else
             domElement->setIdAttributeNode(attr);
+#endif
+        }
     }
 }
index d9ab944..335520f 100644 (file)
@@ -28,6 +28,8 @@
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::XMLString;
+
 AbstractComplexElement::~AbstractComplexElement() {
     for_each(m_children.begin(), m_children.end(), cleanup<XMLObject>());
     for (vector<XMLCh*>::iterator i=m_text.begin(); i!=m_text.end(); ++i)
index 9417e31..b8d3b42 100644 (file)
@@ -30,6 +30,7 @@
 #include <functional>
 
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 AbstractDOMCachingXMLObject::~AbstractDOMCachingXMLObject()
index a8461a4..aeb0817 100644 (file)
@@ -28,6 +28,8 @@
 
 using namespace xmltooling;
 
+using xercesc::XMLString;
+
 AbstractXMLObject::AbstractXMLObject(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
     : m_log(logging::Category::getInstance(XMLTOOLING_LOGCAT".XMLObject")),
        m_schemaLocation(NULL), m_noNamespaceSchemaLocation(NULL), m_nil(xmlconstants::XML_BOOL_NULL),
@@ -132,7 +134,7 @@ DateTime* AbstractXMLObject::prepareForAssignment(DateTime* oldValue, time_t new
 {
     delete oldValue;
     releaseThisandParentDOM();
-    DateTime* ret = new DateTime(newValue);
+    DateTime* ret = new DateTime(newValue, duration);
     if (duration)
         ret->parseDuration();
     else
index a580e53..52ab907 100644 (file)
@@ -33,6 +33,7 @@ libxmltoolinginclude_HEADERS = \
        AttributeExtensibleXMLObject.h \
        base.h \
        ConcreteXMLObjectBuilder.h \
+       char_traits.h \
        config_pub.h \
        ElementExtensibleXMLObject.h \
        ElementProxy.h \
@@ -77,6 +78,7 @@ secinclude_HEADERS = \
        security/KeyInfoCredentialContext.h \
        security/KeyInfoResolver.h \
        security/OpenSSLCredential.h \
+       security/SecurityHelper.h \
        security/SignatureTrustEngine.h \
        security/TrustEngine.h \
        security/X509Credential.h \
@@ -99,8 +101,7 @@ soapinclude_HEADERS = \
        soap/OpenSSLSOAPTransport.h
 
 utilinclude_HEADERS = \
-    util/CurlNetAccessor.hpp \
-    util/CurlURLInputStream.hpp \
+    util/CurlURLInputStream.h \
        util/DateTime.h \
        util/NDC.h \
        util/ParserPool.h \
@@ -141,6 +142,7 @@ xmlsec_sources = \
        security/impl/InlineKeyResolver.cpp \
        security/impl/KeyInfoResolver.cpp \
        security/impl/OpenSSLCryptoX509CRL.cpp \
+       security/impl/SecurityHelper.cpp \
        security/impl/StaticPKIXTrustEngine.cpp \
        security/impl/TrustEngine.cpp \
        security/impl/XSECCryptoX509CRL.cpp \
@@ -149,7 +151,6 @@ xmlsec_sources = \
        signature/impl/SignatureValidator.cpp \
        signature/impl/XMLSecSignatureImpl.cpp \
        soap/impl/CURLSOAPTransport.cpp \
-       util/CurlNetAccessor.cpp \
        util/CurlURLInputStream.cpp \
        util/ReplayCache.cpp \
        util/StorageService.cpp
@@ -195,10 +196,10 @@ common_sources = \
 libxmltooling_lite_la_SOURCES = \
        ${common_sources}
 libxmltooling_lite_la_CPPFLAGS = -DXMLTOOLING_LITE
-libxmltooling_lite_la_LDFLAGS = -version-info 2:0:0
+libxmltooling_lite_la_LDFLAGS = -version-info 3:0:0
 
 if BUILD_XMLSEC
-libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 2:0:0
+libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 3:0:0
 libxmltooling_la_SOURCES = \
        ${common_sources} \
        ${xmlsec_sources}
index f40220a..dcd3655 100644 (file)
@@ -148,6 +148,7 @@ am__libxmltooling_la_SOURCES_DIST =  \
        security/impl/InlineKeyResolver.cpp \
        security/impl/KeyInfoResolver.cpp \
        security/impl/OpenSSLCryptoX509CRL.cpp \
+       security/impl/SecurityHelper.cpp \
        security/impl/StaticPKIXTrustEngine.cpp \
        security/impl/TrustEngine.cpp \
        security/impl/XSECCryptoX509CRL.cpp \
@@ -155,9 +156,8 @@ am__libxmltooling_la_SOURCES_DIST =  \
        signature/impl/KeyInfoSchemaValidators.cpp \
        signature/impl/SignatureValidator.cpp \
        signature/impl/XMLSecSignatureImpl.cpp \
-       soap/impl/CURLSOAPTransport.cpp util/CurlNetAccessor.cpp \
-       util/CurlURLInputStream.cpp util/ReplayCache.cpp \
-       util/StorageService.cpp
+       soap/impl/CURLSOAPTransport.cpp util/CurlURLInputStream.cpp \
+       util/ReplayCache.cpp util/StorageService.cpp
 @BUILD_PTHREAD_TRUE@am__objects_3 = PThreads.lo
 am__objects_4 = AbstractAttributeExtensibleXMLObject.lo \
        AbstractComplexElement.lo AbstractDOMCachingXMLObject.lo \
@@ -177,12 +177,12 @@ am__objects_5 = Decrypter.lo EncryptedKeyResolver.lo Encrypter.lo \
        ChainingTrustEngine.lo CredentialCriteria.lo \
        CredentialResolver.lo ExplicitKeyTrustEngine.lo \
        FilesystemCredentialResolver.lo InlineKeyResolver.lo \
-       KeyInfoResolver.lo OpenSSLCryptoX509CRL.lo \
+       KeyInfoResolver.lo OpenSSLCryptoX509CRL.lo SecurityHelper.lo \
        StaticPKIXTrustEngine.lo TrustEngine.lo XSECCryptoX509CRL.lo \
        KeyInfoImpl.lo KeyInfoSchemaValidators.lo \
        SignatureValidator.lo XMLSecSignatureImpl.lo \
-       CURLSOAPTransport.lo CurlNetAccessor.lo CurlURLInputStream.lo \
-       ReplayCache.lo StorageService.lo
+       CURLSOAPTransport.lo CurlURLInputStream.lo ReplayCache.lo \
+       StorageService.lo
 @BUILD_XMLSEC_TRUE@am_libxmltooling_la_OBJECTS = $(am__objects_4) \
 @BUILD_XMLSEC_TRUE@    $(am__objects_5)
 libxmltooling_la_OBJECTS = $(am_libxmltooling_la_OBJECTS)
@@ -407,6 +407,7 @@ libxmltoolinginclude_HEADERS = \
        AttributeExtensibleXMLObject.h \
        base.h \
        ConcreteXMLObjectBuilder.h \
+       char_traits.h \
        config_pub.h \
        ElementExtensibleXMLObject.h \
        ElementProxy.h \
@@ -451,6 +452,7 @@ secinclude_HEADERS = \
        security/KeyInfoCredentialContext.h \
        security/KeyInfoResolver.h \
        security/OpenSSLCredential.h \
+       security/SecurityHelper.h \
        security/SignatureTrustEngine.h \
        security/TrustEngine.h \
        security/X509Credential.h \
@@ -473,8 +475,7 @@ soapinclude_HEADERS = \
        soap/OpenSSLSOAPTransport.h
 
 utilinclude_HEADERS = \
-    util/CurlNetAccessor.hpp \
-    util/CurlURLInputStream.hpp \
+    util/CurlURLInputStream.h \
        util/DateTime.h \
        util/NDC.h \
        util/ParserPool.h \
@@ -515,6 +516,7 @@ xmlsec_sources = \
        security/impl/InlineKeyResolver.cpp \
        security/impl/KeyInfoResolver.cpp \
        security/impl/OpenSSLCryptoX509CRL.cpp \
+       security/impl/SecurityHelper.cpp \
        security/impl/StaticPKIXTrustEngine.cpp \
        security/impl/TrustEngine.cpp \
        security/impl/XSECCryptoX509CRL.cpp \
@@ -523,7 +525,6 @@ xmlsec_sources = \
        signature/impl/SignatureValidator.cpp \
        signature/impl/XMLSecSignatureImpl.cpp \
        soap/impl/CURLSOAPTransport.cpp \
-       util/CurlNetAccessor.cpp \
        util/CurlURLInputStream.cpp \
        util/ReplayCache.cpp \
        util/StorageService.cpp
@@ -566,8 +567,8 @@ libxmltooling_lite_la_SOURCES = \
        ${common_sources}
 
 libxmltooling_lite_la_CPPFLAGS = -DXMLTOOLING_LITE
-libxmltooling_lite_la_LDFLAGS = -version-info 2:0:0
-@BUILD_XMLSEC_TRUE@libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 2:0:0
+libxmltooling_lite_la_LDFLAGS = -version-info 3:0:0
+@BUILD_XMLSEC_TRUE@libxmltooling_la_LDFLAGS = $(XMLSEC_LIBS) -version-info 3:0:0
 @BUILD_XMLSEC_TRUE@libxmltooling_la_SOURCES = \
 @BUILD_XMLSEC_TRUE@    ${common_sources} \
 @BUILD_XMLSEC_TRUE@    ${xmlsec_sources}
@@ -685,7 +686,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ChainingTrustEngine.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CredentialCriteria.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CredentialResolver.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CurlNetAccessor.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CurlURLInputStream.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DateTime.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Decrypter.Plo@am__quote@
@@ -713,6 +713,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SOAPClient.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SOAPImpl.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SOAPSchemaValidators.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SecurityHelper.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SignatureValidator.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StaticPKIXTrustEngine.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/StorageService.Plo@am__quote@
@@ -1243,6 +1244,13 @@ OpenSSLCryptoX509CRL.lo: security/impl/OpenSSLCryptoX509CRL.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o OpenSSLCryptoX509CRL.lo `test -f 'security/impl/OpenSSLCryptoX509CRL.cpp' || echo '$(srcdir)/'`security/impl/OpenSSLCryptoX509CRL.cpp
 
+SecurityHelper.lo: security/impl/SecurityHelper.cpp
+@am__fastdepCXX_TRUE@  if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT SecurityHelper.lo -MD -MP -MF "$(DEPDIR)/SecurityHelper.Tpo" -c -o SecurityHelper.lo `test -f 'security/impl/SecurityHelper.cpp' || echo '$(srcdir)/'`security/impl/SecurityHelper.cpp; \
+@am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/SecurityHelper.Tpo" "$(DEPDIR)/SecurityHelper.Plo"; else rm -f "$(DEPDIR)/SecurityHelper.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='security/impl/SecurityHelper.cpp' object='SecurityHelper.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o SecurityHelper.lo `test -f 'security/impl/SecurityHelper.cpp' || echo '$(srcdir)/'`security/impl/SecurityHelper.cpp
+
 StaticPKIXTrustEngine.lo: security/impl/StaticPKIXTrustEngine.cpp
 @am__fastdepCXX_TRUE@  if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT StaticPKIXTrustEngine.lo -MD -MP -MF "$(DEPDIR)/StaticPKIXTrustEngine.Tpo" -c -o StaticPKIXTrustEngine.lo `test -f 'security/impl/StaticPKIXTrustEngine.cpp' || echo '$(srcdir)/'`security/impl/StaticPKIXTrustEngine.cpp; \
 @am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/StaticPKIXTrustEngine.Tpo" "$(DEPDIR)/StaticPKIXTrustEngine.Plo"; else rm -f "$(DEPDIR)/StaticPKIXTrustEngine.Tpo"; exit 1; fi
@@ -1299,13 +1307,6 @@ CURLSOAPTransport.lo: soap/impl/CURLSOAPTransport.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CURLSOAPTransport.lo `test -f 'soap/impl/CURLSOAPTransport.cpp' || echo '$(srcdir)/'`soap/impl/CURLSOAPTransport.cpp
 
-CurlNetAccessor.lo: util/CurlNetAccessor.cpp
-@am__fastdepCXX_TRUE@  if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CurlNetAccessor.lo -MD -MP -MF "$(DEPDIR)/CurlNetAccessor.Tpo" -c -o CurlNetAccessor.lo `test -f 'util/CurlNetAccessor.cpp' || echo '$(srcdir)/'`util/CurlNetAccessor.cpp; \
-@am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/CurlNetAccessor.Tpo" "$(DEPDIR)/CurlNetAccessor.Plo"; else rm -f "$(DEPDIR)/CurlNetAccessor.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='util/CurlNetAccessor.cpp' object='CurlNetAccessor.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@ $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o CurlNetAccessor.lo `test -f 'util/CurlNetAccessor.cpp' || echo '$(srcdir)/'`util/CurlNetAccessor.cpp
-
 CurlURLInputStream.lo: util/CurlURLInputStream.cpp
 @am__fastdepCXX_TRUE@  if $(LIBTOOL) --tag=CXX --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT CurlURLInputStream.lo -MD -MP -MF "$(DEPDIR)/CurlURLInputStream.Tpo" -c -o CurlURLInputStream.lo `test -f 'util/CurlURLInputStream.cpp' || echo '$(srcdir)/'`util/CurlURLInputStream.cpp; \
 @am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/CurlURLInputStream.Tpo" "$(DEPDIR)/CurlURLInputStream.Plo"; else rm -f "$(DEPDIR)/CurlURLInputStream.Tpo"; exit 1; fi
index ec272c0..57ca9d6 100644 (file)
@@ -25,6 +25,8 @@
 
 using namespace xmltooling;
 
+using xercesc::XMLString;
+
 Namespace::Namespace(const XMLCh* uri, const XMLCh* prefix, bool alwaysDeclare) : m_pinned(alwaysDeclare)
 {
 #ifndef HAVE_GOOD_STL
index b161da6..868725c 100644 (file)
@@ -26,6 +26,8 @@
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::XMLString;
+
 QName::QName(const XMLCh* uri, const XMLCh* localPart, const XMLCh* prefix)
 {
 #ifndef HAVE_GOOD_STL
index 982f6a2..972e212 100644 (file)
@@ -30,6 +30,8 @@ using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::DOMElement;
+
 map<QName,XMLObjectBuilder*> XMLObjectBuilder::m_map;
 XMLObjectBuilder* XMLObjectBuilder::m_default=NULL;
 
index ee9cc3c..9773dcd 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * XMLToolingConfig.cpp
- * 
- * Library configuration 
+ *
+ * Library configuration
  */
 
 #include "internal.h"
@@ -69,6 +69,8 @@ using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::XMLPlatformUtils;
+
 DECL_XMLTOOLING_EXCEPTION_FACTORY(XMLParserException,xmltooling);
 DECL_XMLTOOLING_EXCEPTION_FACTORY(XMLObjectException,xmltooling);
 DECL_XMLTOOLING_EXCEPTION_FACTORY(MarshallingException,xmltooling);
@@ -99,7 +101,7 @@ namespace xmltooling {
         else
             g_openssl_locks[n]->unlock();
     }
-    
+
 # ifndef WIN32
     extern "C" unsigned long openssl_thread_id(void)
     {
@@ -126,7 +128,7 @@ bool XMLToolingInternalConfig::log_config(const char* config)
             config=getenv("XMLTOOLING_LOG_CONFIG");
         if (!config || !*config)
             config="WARN";
-        
+
         bool level=false;
         Category& root = Category::getRoot();
         if (!strcmp(config,"DEBUG")) {
@@ -170,14 +172,14 @@ bool XMLToolingInternalConfig::log_config(const char* config)
         }
         else {
             string path(config);
-            PropertyConfigurator::configure(m_pathResolver ? m_pathResolver->resolve(path, PathResolver::XMLTOOLING_CFG_FILE).c_str() : config);
+            PropertyConfigurator::configure(m_pathResolver ? m_pathResolver->resolve(path, PathResolver::XMLTOOLING_CFG_FILE) : path);
         }
     }
     catch (const ConfigureFailure& e) {
         Category::getInstance(XMLTOOLING_LOGCAT".Logging").crit("failed to initialize log4cpp: %s", e.what());
         return false;
     }
-    
+
     return true;
 }
 
@@ -236,7 +238,7 @@ bool XMLToolingInternalConfig::init()
         m_parserPool=new ParserPool();
         m_validatingPool=new ParserPool(true,true);
         m_lock=XMLPlatformUtils::makeMutex();
-        
+
         // Load catalogs from path.
         if (!catalog_path.empty()) {
             char* catpath=strdup(catalog_path.c_str());
@@ -266,7 +268,7 @@ bool XMLToolingInternalConfig::init()
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(UnknownAttributeException,xmltooling);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(ValidationException,xmltooling);
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(IOException,xmltooling);
-        
+
 #ifndef XMLTOOLING_NO_XMLSEC
         XMLObjectBuilder::registerBuilder(QName(xmlconstants::XMLSIG_NS,Signature::LOCAL_NAME),new SignatureBuilder());
         REGISTER_XMLTOOLING_EXCEPTION_FACTORY(XMLSecurityException,xmltooling);
@@ -286,10 +288,10 @@ bool XMLToolingInternalConfig::init()
 
         m_pathResolver = new PathResolver();
         m_urlEncoder = new URLEncoder();
-        
-        // Register xml:id as an ID attribute.        
+
+        // Register xml:id as an ID attribute.
         static const XMLCh xmlid[] = UNICODE_LITERAL_2(i,d);
-        AttributeExtensibleXMLObject::registerIDAttribute(QName(xmlconstants::XML_NS, xmlid)); 
+        AttributeExtensibleXMLObject::registerIDAttribute(QName(xmlconstants::XML_NS, xmlid));
     }
     catch (const xercesc::XMLException&) {
         log.fatal("caught exception while initializing Xerces");
@@ -344,7 +346,7 @@ void XMLToolingInternalConfig::term()
 
     delete m_pathResolver;
     m_pathResolver = NULL;
-    
+
     delete m_templateEngine;
     m_templateEngine = NULL;
 
@@ -367,7 +369,7 @@ void XMLToolingInternalConfig::term()
 #endif
     }
     m_libhandles.clear();
-    
+
     delete m_parserPool;
     m_parserPool=NULL;
     delete m_validatingPool;
@@ -385,7 +387,7 @@ void XMLToolingInternalConfig::term()
 
 #ifndef XMLTOOLING_NO_XMLSEC
     curl_global_cleanup();
-#endif   
+#endif
 #ifdef _DEBUG
     xmltooling::NDC ndc("term");
 #endif
@@ -415,13 +417,13 @@ bool XMLToolingInternalConfig::load_library(const char* path, void* context)
 
     string resolved(path);
     m_pathResolver->resolve(resolved, PathResolver::XMLTOOLING_LIB_FILE);
-    
+
 #if defined(WIN32)
     HMODULE handle=NULL;
     for (string::iterator i = resolved.begin(); i != resolved.end(); ++i)
         if (*i == '/')
             *i = '\\';
-    
+
     UINT em=SetErrorMode(SEM_FAILCRITICALERRORS);
     try {
         handle=LoadLibraryEx(resolved.c_str(),NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
@@ -436,12 +438,11 @@ bool XMLToolingInternalConfig::load_library(const char* path, void* context)
             throw runtime_error(string("detected error in xmltooling_extension_init: ") + resolved);
         SetErrorMode(em);
     }
-    catch(runtime_error& e) {
-        log.error(e.what());
+    catch(exception&) {
         if (handle)
             FreeLibrary(handle);
         SetErrorMode(em);
-        return false;
+        throw;
     }
 
 #elif defined(HAVE_DLFCN_H)
@@ -460,11 +461,10 @@ bool XMLToolingInternalConfig::load_library(const char* path, void* context)
         if (fn(context)!=0)
             throw runtime_error(string("detected error in xmltooling_extension_init in ") + resolved);
     }
-    catch(runtime_error& e) {
-        log.error(e.what());
+    catch(exception&) {
         if (handle)
             dlclose(handle);
-        return false;
+        throw;
     }
 #else
 # error "Don't know about dynamic loading on this platform!"
@@ -529,3 +529,14 @@ void XMLToolingInternalConfig::registerXMLAlgorithms()
     registerXMLAlgorithm(DSIGConstants::s_unicodeStrURIKW_AES256, "AES", 256);
 }
 #endif
+
+#ifdef WIN32
+
+extern "C" __declspec(dllexport) BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID)
+{
+    if (fdwReason == DLL_THREAD_DETACH || fdwReason == DLL_PROCESS_DETACH)
+        ThreadKey::onDetach();
+    return TRUE;
+}
+
+#endif
index 05128dd..827213a 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- *  Copyright 2001-2007 Internet2\r
+ *  Copyright 2001-2008 Internet2\r
  *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -26,6 +26,9 @@
 \r
 #include <typeinfo>\r
 \r
+/* Required for sprintf, used by integer XML attribute macros. */\r
+#include <cstdio>\r
+\r
 #if defined (_MSC_VER) || defined(__BORLANDC__)\r
   #include <xmltooling/config_pub_win32.h>\r
 #else\r
 # define XMLTOOLING_NO_XMLSEC 1\r
 #endif\r
 \r
+#if defined(XMLTOOLING_NO_XMLSEC) || !defined(HAVE_XSECSIZE_T)\r
+# ifdef XMLTOOLING_XERCESC_64BITSAFE\r
+#   include <xercesc/util/XercesDefs.hpp>\r
+    typedef XMLSize_t xsecsize_t;\r
+# else\r
+    typedef unsigned int xsecsize_t;\r
+# endif\r
+#endif\r
+\r
 // Windows and GCC4 Symbol Visibility Macros\r
 #ifdef WIN32\r
   #define XMLTOOL_IMPORT __declspec(dllimport)\r
         void set##proper(const DateTime* proper) { \\r
             m_##proper = prepareForAssignment(m_##proper,proper); \\r
             if (m_##proper) \\r
-                m_##proper##Epoch=m_##proper->getEpoch(); \\r
+                m_##proper##Epoch=m_##proper->getEpoch(duration); \\r
         } \\r
         void set##proper(time_t proper) { \\r
             m_##proper = prepareForAssignment(m_##proper,proper,duration); \\r
         void set##proper(const XMLCh* proper) { \\r
             m_##proper = prepareForAssignment(m_##proper,proper,duration); \\r
             if (m_##proper) \\r
-                m_##proper##Epoch=m_##proper->getEpoch(); \\r
+                m_##proper##Epoch=m_##proper->getEpoch(duration); \\r
         }\r
 \r
 /**\r
         }\r
 \r
 /**\r
+ * Implements get/set methods and a private member for a typed, qualified XML attribute.\r
+ *\r
+ * @param proper    the proper name of the attribute\r
+ * @param type      the attribute's data type\r
+ */\r
+#define IMPL_XMLOBJECT_FOREIGN_ATTRIB(proper,type) \\r
+    protected: \\r
+    XMLCh* m_##proper##Prefix; \\r
+        type* m_##proper; \\r
+    public: \\r
+        const type* get##proper() const { \\r
+            return m_##proper; \\r
+        } \\r
+        void set##proper(const type* proper) { \\r
+            m_##proper = prepareForAssignment(m_##proper,proper); \\r
+            XMLString::release(&m_##proper##Prefix); \\r
+            m_##proper##Prefix = NULL; \\r
+        }\r
+\r
+/**\r
  * Declares abstract set method for a typed XML child object in a foreign namespace.\r
  * The get method is omitted.\r
  *\r
         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, qstr.get()); \\r
     }\r
 \r
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE\r
 /**\r
  * Implements marshalling for an ID attribute\r
  *\r
  * @param ucase         the upcased name of the attribute\r
  * @param namespaceURI  the XML namespace of the attribute\r
  */\r
-#define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \\r
+# define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \\r
+    if (m_##proper && *m_##proper) { \\r
+        domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \\r
+        domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, true); \\r
+    }\r
+#else\r
+/**\r
+ * Implements marshalling for an ID attribute\r
+ *\r
+ * @param proper        the proper name of the attribute\r
+ * @param ucase         the upcased name of the attribute\r
+ * @param namespaceURI  the XML namespace of the attribute\r
+ */\r
+# define MARSHALL_ID_ATTRIB(proper,ucase,namespaceURI) \\r
     if (m_##proper && *m_##proper) { \\r
         domElement->setAttributeNS(namespaceURI, ucase##_ATTRIB_NAME, m_##proper); \\r
         domElement->setIdAttributeNS(namespaceURI, ucase##_ATTRIB_NAME); \\r
     }\r
+#endif\r
 \r
 /**\r
  * Implements unmarshalling process branch for a string attribute\r
         return; \\r
     }\r
 \r
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE\r
 /**\r
  * Implements unmarshalling process branch for an ID attribute\r
  *\r
  * @param ucase         the upcased name of the attribute\r
  * @param namespaceURI  the XML namespace of the attribute\r
  */\r
-#define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \\r
+# define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \\r
+    if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \\r
+        set##proper(attribute->getValue()); \\r
+        attribute->getOwnerElement()->setIdAttributeNode(attribute, true); \\r
+        return; \\r
+    }\r
+#else\r
+/**\r
+ * Implements unmarshalling process branch for an ID attribute\r
+ *\r
+ * @param proper        the proper name of the attribute\r
+ * @param ucase         the upcased name of the attribute\r
+ * @param namespaceURI  the XML namespace of the attribute\r
+ */\r
+# define PROC_ID_ATTRIB(proper,ucase,namespaceURI) \\r
     if (xmltooling::XMLHelper::isNodeNamed(attribute, namespaceURI, ucase##_ATTRIB_NAME)) { \\r
         set##proper(attribute->getValue()); \\r
         attribute->getOwnerElement()->setIdAttributeNode(attribute); \\r
         return; \\r
     }\r
+#endif\r
 \r
 /**\r
  * Implements unmarshalling process branch for a DateTime attribute\r
     { \\r
     public: \\r
         virtual ~cname##Impl() {} \\r
-        cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) \\r
+        cname##Impl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType) \\r
             : xmltooling::AbstractXMLObject(nsURI, localName, prefix, schemaType) { \\r
         } \\r
         cname##Impl(const cname##Impl& src) \\r
  */\r
 #define IMPL_XMLOBJECTBUILDER(cname) \\r
     cname* cname##Builder::buildObject( \\r
-        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \\r
+        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \\r
         ) const \\r
     { \\r
         return new cname##Impl(nsURI,localName,prefix,schemaType); \\r
  */\r
 #define IMPL_XMLOBJECTBUILDER(cname) \\r
     xmltooling::XMLObject* cname##Builder::buildObject( \\r
-        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \\r
+        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType \\r
         ) const \\r
     { \\r
         return new cname##Impl(nsURI,localName,prefix,schemaType); \\r
diff --git a/xmltooling/char_traits.h b/xmltooling/char_traits.h
new file mode 100644 (file)
index 0000000..fac30bb
--- /dev/null
@@ -0,0 +1,170 @@
+/*
+ *  Copyright 2001-2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * @file xmltooling/char_traits.h
+ *
+ * Traits template for basic_string<unsigned short> instantiation on strict compilers.
+ */
+
+#ifndef __xmltooling_chartraits_h__
+#define __xmltooling_chartraits_h__
+
+#include <xmltooling/base.h>
+
+#include <cstring>
+#include <algorithm>
+
+namespace xmltooling {
+
+  /// @cond OFF
+
+  template <class _CharT>
+    struct _Char_types
+    {
+      typedef unsigned long   int_type;
+      typedef std::streampos  pos_type;
+      typedef std::streamoff  off_type;
+      typedef std::mbstate_t  state_type;
+    };
+
+
+  template<typename _CharT>
+    struct char_traits
+    {
+      typedef _CharT                                    char_type;
+      typedef typename _Char_types<_CharT>::int_type    int_type;
+      typedef typename _Char_types<_CharT>::pos_type    pos_type;
+      typedef typename _Char_types<_CharT>::off_type    off_type;
+      typedef typename _Char_types<_CharT>::state_type  state_type;
+
+      static void
+      assign(char_type& __c1, const char_type& __c2)
+      { __c1 = __c2; }
+
+      static bool
+      eq(const char_type& __c1, const char_type& __c2)
+      { return __c1 == __c2; }
+
+      static bool
+      lt(const char_type& __c1, const char_type& __c2)
+      { return __c1 < __c2; }
+
+      static int
+      compare(const char_type* __s1, const char_type* __s2, std::size_t __n);
+
+      static std::size_t
+      length(const char_type* __s);
+
+      static const char_type*
+      find(const char_type* __s, std::size_t __n, const char_type& __a);
+
+      static char_type*
+      move(char_type* __s1, const char_type* __s2, std::size_t __n);
+
+      static char_type*
+      copy(char_type* __s1, const char_type* __s2, std::size_t __n);
+
+      static char_type*
+      assign(char_type* __s, std::size_t __n, char_type __a);
+
+      static char_type
+      to_char_type(const int_type& __c)
+      { return static_cast<char_type>(__c); }
+
+      static int_type
+      to_int_type(const char_type& __c)
+      { return static_cast<int_type>(__c); }
+
+      static bool
+      eq_int_type(const int_type& __c1, const int_type& __c2)
+      { return __c1 == __c2; }
+
+      static int_type
+      eof()
+      { return static_cast<int_type>(EOF); }
+
+      static int_type
+      not_eof(const int_type& __c)
+      { return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
+    };
+
+  template<typename _CharT>
+    int
+    char_traits<_CharT>::
+    compare(const char_type* __s1, const char_type* __s2, std::size_t __n)
+    {
+      for (size_t __i = 0; __i < __n; ++__i)
+    if (lt(__s1[__i], __s2[__i]))
+      return -1;
+    else if (lt(__s2[__i], __s1[__i]))
+      return 1;
+      return 0;
+    }
+
+  template<typename _CharT>
+    std::size_t
+    char_traits<_CharT>::
+    length(const char_type* __p)
+    {
+      std::size_t __i = 0;
+      while (!eq(__p[__i], char_type()))
+        ++__i;
+      return __i;
+    }
+
+  template<typename _CharT>
+    const typename char_traits<_CharT>::char_type*
+    char_traits<_CharT>::
+    find(const char_type* __s, std::size_t __n, const char_type& __a)
+    {
+      for (std::size_t __i = 0; __i < __n; ++__i)
+        if (eq(__s[__i], __a))
+          return __s + __i;
+      return 0;
+    }
+
+  template<typename _CharT>
+    typename char_traits<_CharT>::char_type*
+    char_traits<_CharT>::
+    move(char_type* __s1, const char_type* __s2, std::size_t __n)
+    {
+      return static_cast<_CharT*>(std::memmove(__s1, __s2,
+                           __n * sizeof(char_type)));
+    }
+
+  template<typename _CharT>
+    typename char_traits<_CharT>::char_type*
+    char_traits<_CharT>::
+    copy(char_type* __s1, const char_type* __s2, std::size_t __n)
+    {
+      std::copy(__s2, __s2 + __n, __s1);
+      return __s1;
+    }
+
+  template<typename _CharT>
+    typename char_traits<_CharT>::char_type*
+    char_traits<_CharT>::
+    assign(char_type* __s, std::size_t __n, char_type __a)
+    {
+      std::fill_n(__s, __n, __a);
+      return __s;
+    }
+
+    /// @endcond
+}
+
+#endif // __xmltooling_chartraits_h__
index 4855032..78fa382 100644 (file)
 
 /* Define to 1 to disable XML-Security-dependent features. */
 /* #undef XMLTOOLING_NO_XMLSEC */
+
+/* Define to 1 if Xerces supports a compliant DOMLS API. */
+#define XMLTOOLING_XERCESC_COMPLIANT_DOMLS 1
+
+/* Define to 1 if Xerces DOM ID methods take extra parameter.  */
+#define XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE 1
+
+/* Define to 1 if Xerces has a 64-bit-safe API. */
+#define XMLTOOLING_XERCESC_64BITSAFE 1
+
+/* Define to 1 if you have the `xsecsize_t' type. */
+/* #undef HAVE_XSECSIZE_T */
index 1ae9290..736d7ec 100644 (file)
 
 /* Define to 1 to disable XML-Security-dependent features. */
 #undef XMLTOOLING_NO_XMLSEC
+
+/* Define to 1 if Xerces supports a compliant DOMLS API. */
+#undef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+
+/* Define to 1 if Xerces DOM ID methods take extra parameter.  */
+#undef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+
+/* Define to 1 if Xerces has a 64-bit-safe API. */
+#undef XMLTOOLING_XERCESC_64BITSAFE
+
+/* Define to 1 if you have the `xsecsize_t' type. */
+#undef HAVE_XSECSIZE_T
index bf1053b..2652bb9 100644 (file)
 
 /* Define if you wish to disable Xalan-dependent features. */
 #define XSEC_NO_XALAN
+
+#include <xercesc/util/XercesVersion.hpp>
+
+#if (XERCES_VERSION_MAJOR >= 3)
+# define XMLTOOLING_XERCESC_COMPLIANT_DOMLS     1
+# define XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE  1
+# define XMLTOOLING_XERCESC_64BITSAFE           1
+#endif
+
+/* Define to 1 if you have the `xsecsize_t' type. */
+#define HAVE_XSECSIZE_T 1
index c1fb590..dc3d2c8 100644 (file)
@@ -24,6 +24,7 @@
 #define __xmltooling_encryption_h__
 
 #include <xmltooling/signature/KeyInfo.h>
+#include <cstdio>
 
 /**
  * Macro for declaring encryption builders.
index a87fa89..b29ca13 100644 (file)
@@ -39,6 +39,7 @@
 using namespace xmlencryption;
 using namespace xmlsignature;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 Decrypter::~Decrypter()
@@ -164,7 +165,7 @@ void Decrypter::decryptData(ostream& out, const EncryptedData& encryptedData, XS
         auto_ptr<XSECBinTXFMInputStream> in(m_cipher->decryptToBinInputStream(encryptedData.getDOM()));
         
         XMLByte buf[8192];
-        unsigned int count = in->readBytes(buf, sizeof(buf));
+        xsecsize_t count = in->readBytes(buf, sizeof(buf));
         while (count > 0)
             out.write(reinterpret_cast<char*>(buf),count);
     }
index ae184e9..21601b8 100644 (file)
@@ -34,6 +34,7 @@
 using namespace xmlencryption;
 using namespace xmlsignature;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 Encrypter::~Encrypter()
index ffabf41..a6d0af7 100644 (file)
@@ -34,6 +34,7 @@
 
 using namespace xmlencryption;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 using xmlconstants::XMLENC_NS;
 using xmlconstants::XMLSIG_NS;
@@ -71,7 +72,7 @@ namespace xmlencryption {
             XMLString::release(&m_Algorithm);
         }
 
-        EncryptionMethodImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EncryptionMethodImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -129,7 +130,7 @@ namespace xmlencryption {
     public:
         virtual ~TransformsImpl() {}
 
-        TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -170,7 +171,7 @@ namespace xmlencryption {
             XMLString::release(&m_URI);
         }
 
-        CipherReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        CipherReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -221,7 +222,7 @@ namespace xmlencryption {
     public:
         virtual ~CipherDataImpl() {}
 
-        CipherDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        CipherDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -263,7 +264,7 @@ namespace xmlencryption {
             XMLString::release(&m_Target);
         }
 
-        EncryptionPropertyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EncryptionPropertyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -286,7 +287,7 @@ namespace xmlencryption {
         IMPL_STRING_ATTRIB(Target);
         IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject, m_children.end());
 
-        void setAttribute(const QName& qualifiedName, const XMLCh* value, bool ID=false) {
+        void setAttribute(const xmltooling::QName& qualifiedName, const XMLCh* value, bool ID=false) {
             if (!qualifiedName.hasNamespaceURI()) {
                 if (XMLString::equals(qualifiedName.getLocalPart(),ID_ATTRIB_NAME)) {
                     setId(value);
@@ -331,7 +332,7 @@ namespace xmlencryption {
             XMLString::release(&m_Id);
         }
 
-        EncryptionPropertiesImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EncryptionPropertiesImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -388,7 +389,7 @@ namespace xmlencryption {
             XMLString::release(&m_URI);
         }
 
-        ReferenceTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        ReferenceTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -426,7 +427,7 @@ namespace xmlencryption {
     public:
         virtual ~DataReferenceImpl() {}
 
-        DataReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        DataReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
             
         DataReferenceImpl(const DataReferenceImpl& src) : AbstractXMLObject(src), ReferenceTypeImpl(src) {}
@@ -442,7 +443,7 @@ namespace xmlencryption {
     public:
         virtual ~KeyReferenceImpl() {}
 
-        KeyReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        KeyReferenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
             
         KeyReferenceImpl(const KeyReferenceImpl& src) : AbstractXMLObject(src), ReferenceTypeImpl(src) {}
@@ -462,7 +463,7 @@ namespace xmlencryption {
     public:
         virtual ~ReferenceListImpl() {}
 
-        ReferenceListImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        ReferenceListImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -534,7 +535,7 @@ namespace xmlencryption {
             XMLString::release(&m_Encoding);
         }
 
-        EncryptedTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EncryptedTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -596,7 +597,7 @@ namespace xmlencryption {
     public:
         virtual ~EncryptedDataImpl() {}
 
-        EncryptedDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EncryptedDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
             
         EncryptedDataImpl(const EncryptedDataImpl& src) : AbstractXMLObject(src), EncryptedTypeImpl(src) {}
@@ -626,7 +627,7 @@ namespace xmlencryption {
             XMLString::release(&m_Recipient);
         }
 
-        EncryptedKeyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EncryptedKeyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
index 1d0e883..170f9d9 100644 (file)
@@ -1,5 +1,5 @@
 /*\r
- *  Copyright 2001-2007 Internet2\r
+ *  Copyright 2001-2009 Internet2\r
  * \r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
@@ -33,6 +33,7 @@
 #include <xercesc/util/XMLUniDefs.hpp>\r
 \r
 using namespace xmltooling;\r
+using namespace xercesc;\r
 using namespace std;\r
 using xmlconstants::XMLTOOLING_NS;\r
 \r
@@ -129,13 +130,13 @@ inline const char* get_digit_character()
     return s_mid;\r
 }\r
 \r
-inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, int i)\r
+inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, size_t i)\r
 {\r
     char* psz=buf + cchBuf - 1;     // Set psz to last char\r
     *psz = 0;                       // Set terminating null\r
 \r
     do {\r
-        unsigned int lsd = i % 10;  // Get least significant\r
+        size_t lsd = i % 10;  // Get least significant\r
                                     // digit\r
 \r
         i /= 10;                    // Prepare for next most\r
@@ -153,7 +154,7 @@ inline const char* unsigned_integer_to_string(char* buf, size_t cchBuf, int i)
 void XMLToolingException::addProperties(const params& p)\r
 {\r
     m_processedmsg.erase();\r
-    int i=m_params.size()+1;\r
+    map<string,string>::size_type i=m_params.size()+1;\r
     char buf[20];\r
     const vector<const char*>& v=p.get();\r
     for (vector<const char*>::const_iterator ci=v.begin(); ci!=v.end(); ci++) {\r
@@ -248,9 +249,10 @@ string XMLToolingException::toString() const
     const char* msg=getMessage();\r
     if (msg)\r
         xml_encode(xml, "<message>", msg, "</message>");\r
+    const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();\r
     for (map<string,string>::const_iterator i=m_params.begin(); i!=m_params.end(); i++) {\r
         xml_encode(xml, "<param name='", i->first.c_str(), "'");\r
-        xml_encode(xml, ">", i->second.c_str(), "</param>");\r
+        xml_encode(xml, ">", encoder->encode(i->second.c_str()).c_str(), "</param>");\r
     }\r
     xml+="</exception>";\r
     return xml;\r
@@ -294,13 +296,16 @@ XMLToolingException* XMLToolingException::fromStream(std::istream& in)
         excep->setMessage(m.get());\r
     }\r
     \r
+    const URLEncoder* encoder = XMLToolingConfig::getConfig().getURLEncoder();\r
     child=XMLHelper::getFirstChildElement(root,XMLTOOLING_NS,param);\r
     while (child && child->hasChildNodes()) {\r
         auto_ptr_char n(child->getAttributeNS(NULL,name));\r
-        char* v=toUTF8(child->getFirstChild()->getNodeValue());\r
-        if (n.get() && v)\r
-            excep->addProperty(n.get(), v);\r
-        delete[] v;\r
+        char* encoded = XMLString::transcode(child->getFirstChild()->getNodeValue());\r
+        if (n.get() && encoded) {\r
+            encoder->decode(encoded);\r
+            excep->addProperty(n.get(), encoded);\r
+        }\r
+        XMLString::release(&encoded);\r
         child=XMLHelper::getNextSiblingElement(child,XMLTOOLING_NS,param);\r
     }\r
 \r
index 1e4e2f0..8fb4cfc 100644 (file)
@@ -29,6 +29,7 @@
 #include <xercesc/util/XMLUniDefs.hpp>
 
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 XMLObject* AnyElementImpl::clone() const {
@@ -62,7 +63,7 @@ void AnyElementImpl::processAttribute(const DOMAttr* attribute) {
 }
 
 XMLObject* AnyElementBuilder::buildObject(
-    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType
+    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType
     ) const {
     return new AnyElementImpl(nsURI, localName, prefix, schemaType);
 }
index b297d65..7e9b845 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
  *  Copyright 2001-2007 Internet2\r
- * \r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * You may obtain a copy of the License at\r
@@ -16,7 +16,7 @@
 \r
 /**\r
  * MemoryStorageService.cpp\r
- * \r
+ *\r
  * In-memory "persistent" storage, suitable for simple applications.\r
  */\r
 \r
@@ -34,18 +34,20 @@ using namespace xmltooling::logging;
 using namespace xmltooling;\r
 using namespace std;\r
 \r
+using xercesc::DOMElement;\r
+\r
 namespace xmltooling {\r
     class XMLTOOL_DLLLOCAL MemoryStorageService : public StorageService\r
     {\r
     public:\r
         MemoryStorageService(const DOMElement* e);\r
         virtual ~MemoryStorageService();\r
-        \r
+\r
         bool createString(const char* context, const char* key, const char* value, time_t expiration);\r
         int readString(const char* context, const char* key, string* pvalue=NULL, time_t* pexpiration=NULL, int version=0);\r
         int updateString(const char* context, const char* key, const char* value=NULL, time_t expiration=0, int version=0);\r
         bool deleteString(const char* context, const char* key);\r
-        \r
+\r
         bool createText(const char* context, const char* key, const char* value, time_t expiration) {\r
             return createString(context, key, value, expiration);\r
         }\r
@@ -58,7 +60,7 @@ namespace xmltooling {
         bool deleteText(const char* context, const char* key) {\r
             return deleteString(context, key);\r
         }\r
-        \r
+\r
         void reap(const char* context);\r
         void updateContext(const char* context, time_t expiration);\r
         void deleteContext(const char* context) {\r
@@ -69,7 +71,7 @@ namespace xmltooling {
 \r
     private:\r
         void cleanup();\r
-    \r
+\r
         struct XMLTOOL_DLLLOCAL Record {\r
             Record() : expiration(0), version(1) {}\r
             Record(const string& s, time_t t) : data(s), expiration(t), version(1) {}\r
@@ -77,7 +79,7 @@ namespace xmltooling {
             time_t expiration;\r
             int version;\r
         };\r
-        \r
+\r
         struct XMLTOOL_DLLLOCAL Context {\r
             Context() {}\r
             Context(const Context& src) {\r
@@ -143,6 +145,7 @@ MemoryStorageService::~MemoryStorageService()
     shutdown_wait->signal();\r
     cleanup_thread->join(NULL);\r
 \r
+    delete cleanup_thread;\r
     delete shutdown_wait;\r
     delete m_lock;\r
 }\r
@@ -152,7 +155,7 @@ void* MemoryStorageService::cleanup_fn(void* cache_p)
     MemoryStorageService* cache = reinterpret_cast<MemoryStorageService*>(cache_p);\r
 \r
 #ifndef WIN32\r
-    // First, let's block all signals \r
+    // First, let's block all signals\r
     Thread::mask_all_signals();\r
 #endif\r
 \r
@@ -176,14 +179,14 @@ void MemoryStorageService::cleanup()
         shutdown_wait->timedwait(mutex.get(), m_cleanupInterval);\r
         if (shutdown)\r
             break;\r
-        \r
+\r
         unsigned long count=0;\r
         time_t now = time(NULL);\r
         m_lock->wrlock();\r
         SharedLock locker(m_lock, false);\r
         for (map<string,Context>::iterator i=m_contextMap.begin(); i!=m_contextMap.end(); ++i)\r
             count += i->second.reap(now);\r
-        \r
+\r
         if (count)\r
             m_log.info("purged %d expired record(s) from storage", count);\r
     }\r
@@ -234,9 +237,9 @@ bool MemoryStorageService::createString(const char* context, const char* key, co
         // It's dead, so we can just remove it now and create the new record.\r
         ctx.m_dataMap.erase(i);\r
     }\r
-    \r
+\r
     ctx.m_dataMap[key]=Record(value,expiration);\r
-    \r
+\r
     m_log.debug("inserted record (%s) in context (%s)", key, context);\r
     return true;\r
 }\r
@@ -270,7 +273,7 @@ int MemoryStorageService::updateString(const char* context, const char* key, con
         return 0;\r
     else if (time(NULL) >= i->second.expiration)\r
         return 0;\r
-    \r
+\r
     if (version > 0 && version != i->second.version)\r
         return -1;  // caller's out of sync\r
 \r
@@ -278,7 +281,7 @@ int MemoryStorageService::updateString(const char* context, const char* key, con
         i->second.data = value;\r
         ++(i->second.version);\r
     }\r
-        \r
+\r
     if (expiration && expiration != i->second.expiration)\r
         i->second.expiration = expiration;\r
 \r
@@ -290,7 +293,7 @@ bool MemoryStorageService::deleteString(const char* context, const char* key)
 {\r
     Context& ctx = writeContext(context);\r
     SharedLock locker(m_lock, false);\r
-    \r
+\r
     // Find the record.\r
     map<string,Record>::iterator i=ctx.m_dataMap.find(key);\r
     if (i!=ctx.m_dataMap.end()) {\r
index af4d12e..b1bc80f 100644 (file)
@@ -33,6 +33,7 @@
 
 using namespace xmltooling::logging;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 #ifndef XMLTOOLING_NO_XMLSEC
 using xmlsignature::Signature;
@@ -204,7 +205,7 @@ XMLObject* UnknownElementImpl::unmarshall(DOMElement* element, bool bindDocument
 }
 
 XMLObject* UnknownElementBuilder::buildObject(
-    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType
+    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType
     ) const {
     return new UnknownElementImpl(nsURI,localName,prefix);
 }
index 3a86e3b..6760ace 100644 (file)
@@ -40,8 +40,6 @@
 #include "XMLToolingConfig.h"
 #include "util/ParserPool.h"
 
-using namespace xercesc;
-
 #include <vector>
 #ifndef XMLTOOLING_NO_XMLSEC
     #include <xsec/framework/XSECProvider.hpp>
index 622240d..7e2cf3c 100644 (file)
@@ -40,6 +40,7 @@
 #endif
 using namespace xmlconstants;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 DOMElement* AbstractXMLObjectMarshaller::marshall(
index 5a07591..66ae055 100644 (file)
@@ -32,6 +32,7 @@
 
 using namespace xmlconstants;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 
index af983d5..e540b2e 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * @file xmltooling/io/GenericRequest.h
- * 
- * Interface to generic protocol requests that transport XML messages. 
+ *
+ * Interface to generic protocol requests that transport XML messages.
  */
 
 #ifndef __xmltooling_genreq_h__
 #endif
 
 namespace xmltooling {
-    
+
     /**
      * Interface to generic protocol requests that transport XML messages.
-     * 
+     *
      * <p>This interface need not be threadsafe.
      */
     class XMLTOOL_API GenericRequest {
@@ -45,60 +45,60 @@ namespace xmltooling {
         GenericRequest() {}
     public:
         virtual ~GenericRequest() {}
-        
+
         /**
          * Returns the URL scheme of the request (http, https, ftp, ldap, etc.)
-         * 
+         *
          * @return the URL scheme
          */
         virtual const char* getScheme() const=0;
-        
+
         /**
          * Returns true iff the request is over a confidential channel.
-         * 
+         *
          * @return confidential channel indicator
          */
         virtual bool isSecure() const=0;
-        
+
         /**
          * Returns hostname of service that received request.
-         * 
+         *
          * @return hostname of service
          */
         virtual const char* getHostname() const=0;
 
         /**
          * Returns incoming port.
-         * 
-         * @return  incoming port 
+         *
+         * @return  incoming port
          */
         virtual int getPort() const=0;
-        
+
         /**
          * Returns the MIME type of the request, if known.
-         * 
+         *
          * @return the MIME type, or an empty string
          */
         virtual std::string getContentType() const=0;
 
         /**
          * Returns the length of the request body, if known.
-         * 
+         *
          * @return the content length, or -1 if unknown
          */
         virtual long getContentLength() const=0;
 
         /**
          * Returns the raw request body.
-         * 
+         *
          * @return the request body, or NULL
          */
         virtual const char* getRequestBody() const=0;
-        
+
         /**
          * Returns a decoded named parameter value from the request.
          * If a parameter has multiple values, only one will be returned.
-         * 
+         *
          * @param name  the name of the parameter to return
          * @return a single parameter value or NULL
          */
@@ -107,11 +107,11 @@ namespace xmltooling {
         /**
          * Returns all of the decoded values of a named parameter from the request.
          * All values found will be returned.
-         * 
+         *
          * @param name      the name of the parameter to return
          * @param values    a vector in which to return pointers to the decoded values
          * @return  the number of values returned
-         */            
+         */
         virtual std::vector<const char*>::size_type getParameters(
             const char* name, std::vector<const char*>& values
             ) const=0;
@@ -119,29 +119,38 @@ namespace xmltooling {
         /**
          * Returns the transport-authenticated identity associated with the request,
          * if authentication is solely handled by the transport.
-         * 
+         *
          * @return the authenticated username or an empty string
          */
         virtual std::string getRemoteUser() const=0;
 
         /**
+         * Gets the authentication type associated with the request.
+         *
+         * @return  the authentication type or NULL
+         */
+        virtual std::string getAuthType() const {
+            return "";
+        }
+
+        /**
          * Returns the IP address of the client.
-         * 
+         *
          * @return the client's IP address
          */
         virtual std::string getRemoteAddr() const=0;
-        
+
         /**
          * Returns the chain of certificates sent by the client.
          * They are not guaranteed to be valid according to any particular definition.
-         * 
-         * @return the client's certificate chain 
+         *
+         * @return the client's certificate chain
          */
         virtual const
 #ifndef XMLTOOLING_NO_XMLSEC
             std::vector<XSECCryptoX509*>&
 #else
-            std::vector<std::string>& 
+            std::vector<std::string>&
 #endif
             getClientCertificates() const=0;
     };
index 9c60888..617bb47 100644 (file)
@@ -43,6 +43,7 @@ namespace xmltooling {
          * If a DOM is supplied, the following XML content is supported:
          * 
          * <ul>
+         *  <li>fullCRLChain boolean attribute
          *  <li>&lt;KeyInfoResolver&gt; elements with a type attribute
          * </ul>
          * 
@@ -50,7 +51,9 @@ namespace xmltooling {
          * 
          * @param e DOM to supply configuration for provider
          */
-        AbstractPKIXTrustEngine(const xercesc::DOMElement* e=NULL) : TrustEngine(e) {}
+        AbstractPKIXTrustEngine(const xercesc::DOMElement* e=NULL);
+
+        bool m_fullCRLChain;
         
         /**
          * Checks that either the name of the peer with the given credentials or the names
@@ -63,7 +66,7 @@ namespace xmltooling {
          * @return true the name check succeeds, false if not
          */
         bool checkEntityNames(X509* certEE, const CredentialResolver& credResolver, const CredentialCriteria& criteria) const;
-        
+
     public:
         virtual ~AbstractPKIXTrustEngine() {}
 
@@ -160,6 +163,15 @@ namespace xmltooling {
         virtual PKIXValidationInfoIterator* getPKIXValidationInfoIterator(
             const CredentialResolver& pkixSource, CredentialCriteria* criteria=NULL
             ) const=0;
+
+    private:
+        bool validateWithCRLs(
+            X509* certEE,
+            STACK_OF(X509)* certChain,
+            const CredentialResolver& credResolver,
+            CredentialCriteria* criteria=NULL,
+            const std::vector<XSECCryptoX509CRL*>* inlineCRLs=NULL
+            ) const;
     };
 };
 
index 9241fd0..ac58933 100644 (file)
@@ -41,7 +41,7 @@ namespace xmltooling {
          * 
          * @param ownCerts  true iff any certificates subsequently stored should be freed by destructor
          */
-        BasicX509Credential(bool ownCerts) : m_key(NULL), m_ownCerts(ownCerts), m_crl(NULL), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+        BasicX509Credential(bool ownCerts) : m_key(NULL), m_ownCerts(ownCerts), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
         }
 
         /**
@@ -52,7 +52,20 @@ namespace xmltooling {
          * @param crl   optional CRL
          */
         BasicX509Credential(XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& certs, XSECCryptoX509CRL* crl=NULL)
-                : m_key(key), m_xseccerts(certs), m_ownCerts(true), m_crl(crl), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+                : m_key(key), m_xseccerts(certs), m_ownCerts(true), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
+            if (crl)
+                m_crls.push_back(crl);
+        }
+
+        /**
+         * Constructor.
+         * 
+         * @param key   key pair or secret key
+         * @param certs array of X.509 certificates, the first entry being the entity certificate
+         * @param crls  array of X.509 CRLs
+         */
+        BasicX509Credential(XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& certs, const std::vector<XSECCryptoX509CRL*>& crls)
+                : m_key(key), m_xseccerts(certs), m_ownCerts(true), m_crls(crls), m_keyInfo(NULL), m_compactKeyInfo(NULL) {
         }
 
         /** The private/secret key/keypair. */
@@ -76,8 +89,8 @@ namespace xmltooling {
         /** Indicates whether to destroy certificates. */
         bool m_ownCerts;
 
-        /** The X.509 CRL. */
-        XSECCryptoX509CRL* m_crl;
+        /** The X.509 CRLs. */
+        std::vector<XSECCryptoX509CRL*> m_crls;
 
         /** The KeyInfo object representing the information. */
         xmlsignature::KeyInfo* m_keyInfo;
@@ -134,7 +147,11 @@ namespace xmltooling {
         }
 
         XSECCryptoX509CRL* getCRL() const {
-            return m_crl;
+            return m_crls.empty() ? NULL : m_crls.front();
+        }
+
+        const std::vector<XSECCryptoX509CRL*>& getCRLs() const {
+            return m_crls;
         }
 
         const char* getSubjectName() const {
diff --git a/xmltooling/security/SecurityHelper.h b/xmltooling/security/SecurityHelper.h
new file mode 100644 (file)
index 0000000..0f0207d
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ *  Copyright 2001-2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * @file xmltooling/security/SecurityHelper.h
+ *
+ * A helper class for working with keys, certificates, etc.
+ */
+
+#if !defined(__xmltooling_sechelper_h__) && !defined(XMLTOOLING_NO_XMLSEC)
+#define __xmltooling_sechelper_h__
+
+#include <xmltooling/security/XSECCryptoX509CRL.h>
+#include <xmltooling/soap/SOAPTransport.h>
+
+#include <vector>
+#include <xsec/enc/XSECCryptoKey.hpp>
+#include <xsec/enc/XSECCryptoX509.hpp>
+
+namespace xmltooling {
+    class XMLTOOL_API Credential;
+
+    /**
+     * A helper class for working with keys, certificates, etc.
+     */
+    class XMLTOOL_API SecurityHelper
+    {
+    public:
+        /**
+         * Access a file to try and guess the encoding format used.
+         *
+         * @param pathname  path to file
+         * @return  constant identifying encoding format
+         */
+        static const char* guessEncodingFormat(const char* pathname);
+
+        /**
+         * Loads a private key from a local file.
+         *
+         * @param pathname  path to file containing key
+         * @param format    optional constant identifying key encoding format
+         * @param password  optional password to decrypt key
+         * @return  a populated key object
+         */
+        static XSECCryptoKey* loadKeyFromFile(const char* pathname, const char* format=NULL, const char* password=NULL);
+
+        /**
+         * Loads certificate(s) from a local file.
+         *
+         * @param certs     array to populate with certificate(s)
+         * @param pathname  path to file containing certificate(s)
+         * @param format    optional constant identifying certificate encoding format
+         * @return  size of the resulting array
+         */
+        static std::vector<XSECCryptoX509*>::size_type loadCertificatesFromFile(
+            std::vector<XSECCryptoX509*>& certs, const char* pathname, const char* format=NULL, const char* password=NULL
+            );
+
+        /**
+         * Loads CRL(s) from a local file.
+         *
+         * @param crls      array to populate with CRL(s)
+         * @param pathname  path to file containing CRL(s)
+         * @param format    optional constant identifying CRL encoding format
+         * @return  size of the resulting array
+         */
+        static std::vector<XSECCryptoX509CRL*>::size_type loadCRLsFromFile(
+            std::vector<XSECCryptoX509CRL*>& crls, const char* pathname, const char* format=NULL
+            );
+
+        /**
+         * Loads a private key from a URL.
+         *
+         * @param transport object to use to acquire key
+         * @param backing   backing file for key (written to or read from if download fails)
+         * @param format    optional constant identifying key encoding format
+         * @param password  optional password to decrypt key
+         * @return  a populated key object
+         */
+        static XSECCryptoKey* loadKeyFromURL(SOAPTransport& transport, const char* backing, const char* format=NULL, const char* password=NULL);
+
+        /**
+         * Loads certificate(s) from a URL.
+         *
+         * @param certs     array to populate with certificate(s)
+         * @param transport object to use to acquire certificate(s)
+         * @param backing   backing file for certificate(s) (written to or read from if download fails)
+         * @param format    optional constant identifying certificate encoding format
+         * @return  size of the resulting array
+         */
+        static std::vector<XSECCryptoX509*>::size_type loadCertificatesFromURL(
+            std::vector<XSECCryptoX509*>& certs, SOAPTransport& transport, const char* backing, const char* format=NULL, const char* password=NULL
+            );
+
+        /**
+         * Loads CRL(s) from a URL.
+         *
+         * @param crls      array to populate with CRL(s)
+         * @param transport object to use to acquire CRL(s)
+         * @param backing   backing file for CRL(s) (written to or read from if download fails)
+         * @param format    optional constant identifying CRL encoding format
+         * @return  size of the resulting array
+         */
+        static std::vector<XSECCryptoX509CRL*>::size_type loadCRLsFromURL(
+            std::vector<XSECCryptoX509CRL*>& crls, SOAPTransport& transport, const char* backing, const char* format=NULL
+            );
+
+        /**
+         * Compares two keys for equality.
+         *
+         * @param key1 first key to compare
+         * @param key2 second key to compare
+         * @return  true iff the keys match
+         */
+        static bool matches(const XSECCryptoKey& key1, const XSECCryptoKey& key2);
+
+        /**
+         * Returns the base64-encoded DER encoding of a public key in SubjectPublicKeyInfo format.
+         *
+         * @param cred      the credential containing the key to encode
+         * @param hash      if true, the DER encoded data is hashed with SHA-1 before base64 encoding
+         * @param nowrap    if true, any linefeeds will be stripped from the result
+         * @return  the base64 encoded key value
+         */
+        static std::string getDEREncoding(const Credential& cred, bool hash=false, bool nowrap=true);
+
+        /**
+         * Returns the base64-encoded DER encoding of a public key in SubjectPublicKeyInfo format.
+         *
+         * @param key       the key to encode
+         * @param hash      if true, the DER encoded data is hashed with SHA-1 before base64 encoding
+         * @param nowrap    if true, any linefeeds will be stripped from the result
+         * @return  the base64 encoded key value
+         */
+        static std::string getDEREncoding(const XSECCryptoKey& key, bool hash=false, bool nowrap=true);
+
+        /**
+         * Returns the base64-encoded DER encoding of a certifiate's public key in SubjectPublicKeyInfo format.
+         *
+         * @param cert      the certificate's key to encode
+         * @param hash      if true, the DER encoded data is hashed with SHA-1 before base64 encoding
+         * @param nowrap    if true, any linefeeds will be stripped from the result
+         * @return  the base64 encoded key value
+         */
+        static std::string getDEREncoding(const XSECCryptoX509& cert, bool hash=false, bool nowrap=true);
+    };
+};
+
+#endif /* __xmltooling_sechelper_h__ */
index 59dcd07..edd83f4 100644 (file)
@@ -67,6 +67,8 @@ namespace xmltooling {
         virtual const std::vector<XSECCryptoX509*>& getEntityCertificateChain() const=0;
 
         /**
+         * @deprecated
+         *
          * Gets a CRL associated with the credential.
          * 
          * @return CRL associated with the credential
@@ -74,6 +76,14 @@ namespace xmltooling {
         virtual XSECCryptoX509CRL* getCRL() const=0;
 
         /**
+         * Gets an immutable collection of all CRLs associated with the credential.
+         * 
+         * @return CRLs associated with the credential
+         */
+        virtual const std::vector<XSECCryptoX509CRL*>& getCRLs() const=0;
+
+
+        /**
          * Gets the subject name of the first certificate in the chain.
          *
          * @return the Subject DN
index 69e24f3..791290b 100644 (file)
@@ -35,6 +35,7 @@
 #include <xmltooling/security/X509Credential.h>
 #include <xmltooling/signature/SignatureValidator.h>
 #include <xmltooling/util/NDC.h>
+#include <xercesc/util/XMLUniDefs.hpp>
 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
 
 using namespace xmlsignature;
@@ -52,13 +53,17 @@ namespace {
     }
 
     static bool XMLTOOL_DLLLOCAL validate(
-        X509* EE, STACK_OF(X509)* untrusted, AbstractPKIXTrustEngine::PKIXValidationInfoIterator* pkixInfo
+        X509* EE,
+        STACK_OF(X509)* untrusted,
+        AbstractPKIXTrustEngine::PKIXValidationInfoIterator* pkixInfo,
+        bool fullCRLChain,
+        const vector<XSECCryptoX509CRL*>* inlineCRLs=NULL
         )
     {
         Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine");
     
         // First we build a stack of CA certs. These objects are all referenced in place.
-        log.debug("building CA list from PKIX Validation information");
+        log.debug("supplying PKIX Validation information");
     
         // We need this for CRL support.
         X509_STORE* store=X509_STORE_new();
@@ -66,32 +71,53 @@ namespace {
             log_openssl();
             return false;
         }
-    #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
-        X509_STORE_set_flags(store,X509_V_FLAG_CRL_CHECK_ALL);
-    #endif
     
         STACK_OF(X509)* CAstack = sk_X509_new_null();
         
         // This contains the state of the validate operation.
+        int count=0;
         X509_STORE_CTX ctx;
         
         const vector<XSECCryptoX509*>& CAcerts = pkixInfo->getTrustAnchors();
         for (vector<XSECCryptoX509*>::const_iterator i=CAcerts.begin(); i!=CAcerts.end(); ++i) {
             if ((*i)->getProviderName()==DSIGConstants::s_unicodeStrPROVOpenSSL) {
                 sk_X509_push(CAstack,static_cast<OpenSSLCryptoX509*>(*i)->getOpenSSLX509());
+                ++count;
             }
         }
 
+        log.debug("supplied (%d) CA certificate(s)", count);
+
+#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+        count=0;
+        if (inlineCRLs) {
+            for (vector<XSECCryptoX509CRL*>::const_iterator j=inlineCRLs->begin(); j!=inlineCRLs->end(); ++j) {
+                if ((*j)->getProviderName()==DSIGConstants::s_unicodeStrPROVOpenSSL) {
+                    // owned by store
+                    X509_STORE_add_crl(store, X509_CRL_dup(static_cast<OpenSSLCryptoX509CRL*>(*j)->getOpenSSLX509CRL()));
+                    ++count;
+                }
+            }
+        }
         const vector<XSECCryptoX509CRL*>& crls = pkixInfo->getCRLs();
         for (vector<XSECCryptoX509CRL*>::const_iterator j=crls.begin(); j!=crls.end(); ++j) {
             if ((*j)->getProviderName()==DSIGConstants::s_unicodeStrPROVOpenSSL) {
                 // owned by store
                 X509_STORE_add_crl(store, X509_CRL_dup(static_cast<OpenSSLCryptoX509CRL*>(*j)->getOpenSSLX509CRL()));
+                ++count;
             }
         }
-     
+        log.debug("supplied (%d) CRL(s)", count);
+        if (count > 0)
+            X509_STORE_set_flags(store, fullCRLChain ? (X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL) : (X509_V_FLAG_CRL_CHECK));
+#else
+        if ((inlineCRLs && !inlineCRLs->empty()) || !pkixInfo->getCRLs().empty()) {
+            log.warn("OpenSSL versions < 0.9.7 do not support CRL checking");
+        }
+#endif
+
         // AFAICT, EE and untrusted are passed in but not owned by the ctx.
-    #if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
+#if (OPENSSL_VERSION_NUMBER >= 0x00907000L)
         if (X509_STORE_CTX_init(&ctx,store,EE,untrusted)!=1) {
             log_openssl();
             log.error("unable to initialize X509_STORE_CTX");
@@ -99,9 +125,9 @@ namespace {
             X509_STORE_free(store);
             return false;
         }
-    #else
+#else
         X509_STORE_CTX_init(&ctx,store,EE,untrusted);
-    #endif
+#endif
     
         // Seems to be most efficient to just pass in the CA stack.
         X509_STORE_CTX_trusted_stack(&ctx,CAstack);
@@ -136,6 +162,13 @@ namespace {
     }
 };
 
+AbstractPKIXTrustEngine::AbstractPKIXTrustEngine(const xercesc::DOMElement* e) : TrustEngine(e), m_fullCRLChain(false)
+{
+    static XMLCh fullCRLChain[] = UNICODE_LITERAL_12(f,u,l,l,C,R,L,C,h,a,i,n);
+    const XMLCh* flag = e ? e->getAttributeNS(NULL, fullCRLChain) : NULL;
+    m_fullCRLChain = (flag && (*flag == xercesc::chLatin_t || *flag == xercesc::chDigit_1));
+}
+
 bool AbstractPKIXTrustEngine::checkEntityNames(
     X509* certEE, const CredentialResolver& credResolver, const CredentialCriteria& criteria
     ) const
@@ -243,15 +276,16 @@ bool AbstractPKIXTrustEngine::checkEntityNames(
     return false;
 }
 
-bool AbstractPKIXTrustEngine::validate(
+bool AbstractPKIXTrustEngine::validateWithCRLs(
     X509* certEE,
     STACK_OF(X509)* certChain,
     const CredentialResolver& credResolver,
-    CredentialCriteria* criteria
+    CredentialCriteria* criteria,
+    const std::vector<XSECCryptoX509CRL*>* inlineCRLs
     ) const
 {
 #ifdef _DEBUG
-    NDC ndc("validate");
+    NDC ndc("validateWithCRLs");
 #endif
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine.PKIX");
 
@@ -274,7 +308,7 @@ bool AbstractPKIXTrustEngine::validate(
 
     auto_ptr<PKIXValidationInfoIterator> pkix(getPKIXValidationInfoIterator(credResolver, criteria));
     while (pkix->next()) {
-        if (::validate(certEE,certChain,pkix.get())) {
+        if (::validate(certEE,certChain,pkix.get(),m_fullCRLChain,inlineCRLs)) {
             return true;
         }
     }
@@ -284,6 +318,16 @@ bool AbstractPKIXTrustEngine::validate(
 }
 
 bool AbstractPKIXTrustEngine::validate(
+    X509* certEE,
+    STACK_OF(X509)* certChain,
+    const CredentialResolver& credResolver,
+    CredentialCriteria* criteria
+    ) const
+{
+    return validateWithCRLs(certEE,certChain,credResolver,criteria);
+}
+
+bool AbstractPKIXTrustEngine::validate(
     XSECCryptoX509* certEE,
     const vector<XSECCryptoX509*>& certChain,
     const CredentialResolver& credResolver,
@@ -332,7 +376,7 @@ bool AbstractPKIXTrustEngine::validate(
 
     // Pull the certificate chain out of the signature.
     X509Credential* x509cred;
-    auto_ptr<Credential> cred(inlineResolver->resolve(&sig,X509Credential::RESOLVE_CERTS));
+    auto_ptr<Credential> cred(inlineResolver->resolve(&sig,X509Credential::RESOLVE_CERTS|X509Credential::RESOLVE_CRLS));
     if (!cred.get() || !(x509cred=dynamic_cast<X509Credential*>(cred.get()))) {
         log.error("unable to perform PKIX validation, signature does not contain any certificates");
         return false;
@@ -362,11 +406,22 @@ bool AbstractPKIXTrustEngine::validate(
         }
     }
     
-    if (certEE)
-        return validate(certEE,certs,credResolver,criteria);
-        
-    log.debug("failed to verify signature with embedded certificates");
-    return false;
+    if (!certEE) {
+        log.debug("failed to verify signature with embedded certificates");
+        return false;
+    }
+    else if (certEE->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+        log.error("only the OpenSSL XSEC provider is supported");
+        return false;
+    }
+
+    STACK_OF(X509)* untrusted=sk_X509_new_null();
+    for (vector<XSECCryptoX509*>::const_iterator i=certs.begin(); i!=certs.end(); ++i)
+        sk_X509_push(untrusted,static_cast<OpenSSLCryptoX509*>(*i)->getOpenSSLX509());
+    const vector<XSECCryptoX509CRL*>& crls = x509cred->getCRLs();
+    bool ret = validateWithCRLs(static_cast<OpenSSLCryptoX509*>(certEE)->getOpenSSLX509(), untrusted, credResolver, criteria, &crls);
+    sk_X509_free(untrusted);
+    return ret;
 }
 
 bool AbstractPKIXTrustEngine::validate(
index 50da3ed..570b682 100644 (file)
@@ -37,7 +37,7 @@ BasicX509Credential::~BasicX509Credential()
     delete m_key;
     if (m_ownCerts)
         for_each(m_xseccerts.begin(), m_xseccerts.end(), xmltooling::cleanup<XSECCryptoX509>());
-    delete m_crl;
+    for_each(m_crls.begin(), m_crls.end(), xmltooling::cleanup<XSECCryptoX509CRL>());
     delete m_keyInfo;
     delete m_compactKeyInfo;
 }
index f98ec7c..abbe6b2 100644 (file)
@@ -33,6 +33,8 @@ using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::DOMElement;
+
 namespace xmltooling {
     class XMLTOOL_DLLLOCAL ChainingCredentialResolver : public CredentialResolver
     {
index 4b5aa2c..358d3b9 100644 (file)
@@ -33,6 +33,8 @@ using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::DOMElement;
+
 namespace xmltooling {
     TrustEngine* XMLTOOL_DLLLOCAL ChainingTrustEngineFactory(const DOMElement* const & e)
     {
index 9d3cabd..6187771 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2008 Internet2
+ *
  * 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
@@ -16,7 +16,7 @@
 
 /**
  * CredentialCriteria.cpp
- * 
+ *
  * Class for specifying criteria by which a CredentialResolver should resolve credentials.
  */
 
@@ -25,6 +25,7 @@
 #include "security/Credential.h"
 #include "security/CredentialCriteria.h"
 #include "security/KeyInfoResolver.h"
+#include "security/SecurityHelper.h"
 
 #include <openssl/dsa.h>
 #include <openssl/rsa.h>
@@ -80,28 +81,5 @@ bool CredentialCriteria::matches(const Credential& credential) const
     if (!key2)
         return true;   // no key here, so we can't test it
 
-    if (key1->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL ||
-        key2->getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
-        logging::Category::getInstance(XMLTOOLING_LOGCAT".Credential").warn("comparison of non-OpenSSL credentials are not supported");
-        return false;
-    }
-
-    if (key1->getKeyType()==XSECCryptoKey::KEY_RSA_PUBLIC || key1->getKeyType()==XSECCryptoKey::KEY_RSA_PAIR) {
-        if (key2->getKeyType()!=XSECCryptoKey::KEY_RSA_PUBLIC && key2->getKeyType()!=XSECCryptoKey::KEY_RSA_PAIR)
-            return false;
-        const RSA* rsa1 = static_cast<const OpenSSLCryptoKeyRSA*>(key1)->getOpenSSLRSA();
-        const RSA* rsa2 = static_cast<const OpenSSLCryptoKeyRSA*>(key2)->getOpenSSLRSA();
-        return (BN_cmp(rsa1->n,rsa2->n) == 0 && BN_cmp(rsa1->e,rsa2->e) == 0);
-    }
-
-    if (key1->getKeyType()==XSECCryptoKey::KEY_DSA_PUBLIC || key1->getKeyType()==XSECCryptoKey::KEY_DSA_PAIR) {
-        if (key2->getKeyType()!=XSECCryptoKey::KEY_DSA_PUBLIC && key2->getKeyType()!=XSECCryptoKey::KEY_DSA_PAIR)
-            return false;
-        const DSA* dsa1 = static_cast<const OpenSSLCryptoKeyDSA*>(key1)->getOpenSSLDSA();
-        const DSA* dsa2 = static_cast<const OpenSSLCryptoKeyDSA*>(key2)->getOpenSSLDSA();
-        return (BN_cmp(dsa1->pub_key,dsa2->pub_key) == 0);
-    }
-    
-    logging::Category::getInstance(XMLTOOLING_LOGCAT".CredentialCriteria").warn("unsupported key type for comparison");
-    return false;
+    return SecurityHelper::matches(*key1, *key2);
 }
index 82bb279..75585d5 100644 (file)
@@ -26,8 +26,8 @@
 using namespace xmltooling;
 
 namespace xmltooling {
-    XMLTOOL_DLLLOCAL PluginManager<CredentialResolver,std::string,const DOMElement*>::Factory FilesystemCredentialResolverFactory; 
-    XMLTOOL_DLLLOCAL PluginManager<CredentialResolver,std::string,const DOMElement*>::Factory ChainingCredentialResolverFactory; 
+    XMLTOOL_DLLLOCAL PluginManager<CredentialResolver,std::string,const xercesc::DOMElement*>::Factory FilesystemCredentialResolverFactory; 
+    XMLTOOL_DLLLOCAL PluginManager<CredentialResolver,std::string,const xercesc::DOMElement*>::Factory ChainingCredentialResolverFactory; 
 };
 
 void XMLTOOL_API xmltooling::registerCredentialResolvers()
index 346c35f..0cdb78a 100644 (file)
@@ -40,6 +40,8 @@ using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::DOMElement;
+
 namespace xmltooling {
     class XMLTOOL_DLLLOCAL ExplicitKeyTrustEngine : public SignatureTrustEngine, public OpenSSLTrustEngine
     {
index b36eef0..2ae0edd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2008 Internet2
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
 #include "security/CredentialResolver.h"
 #include "security/KeyInfoResolver.h"
 #include "security/OpenSSLCredential.h"
-#include "security/OpenSSLCryptoX509CRL.h"
+#include "security/SecurityHelper.h"
 #include "util/NDC.h"
 #include "util/PathResolver.h"
 #include "util/XMLHelper.h"
 #include <openssl/pkcs12.h>
 #include <xercesc/util/XMLUniDefs.hpp>
 #include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
-#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
 
 using namespace xmlsignature;
 using namespace xmltooling::logging;
 using namespace xmltooling;
 using namespace std;
 
-// OpenSSL password callback...
-static int passwd_callback(char* buf, int len, int verify, void* passwd)
-{
-    if(!verify)
-    {
-        if(passwd && len > strlen(reinterpret_cast<char*>(passwd)))
-        {
-            strcpy(buf,reinterpret_cast<char*>(passwd));
-            return strlen(buf);
-        }
-    }
-    return 0;
-}
+using xercesc::DOMElement;
+using xercesc::chLatin_f;
+using xercesc::chDigit_0;
 
 namespace xmltooling {
 
-#if defined (_MSC_VER)
-    #pragma warning( push )
-    #pragma warning( disable : 4250 )
+    // The ManagedResource classes handle memory management, loading of the files
+    // and staleness detection. A copy of the active objects is always stored in
+    // these instances.
+
+    class XMLTOOL_DLLLOCAL ManagedResource {
+    protected:
+        ManagedResource() : local(true), reloadChanges(true), filestamp(0), reloadInterval(0) {}
+        ~ManagedResource() {}
+
+        SOAPTransport* getTransport() {
+            SOAPTransport::Address addr("FilesystemCredentialResolver", source.c_str(), source.c_str());
+            string scheme(addr.m_endpoint, strchr(addr.m_endpoint,':') - addr.m_endpoint);
+            return XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), addr);
+        }
+
+    public:
+        bool stale(Category& log, RWLock* lock=NULL) {
+            if (local) {
+#ifdef WIN32
+                struct _stat stat_buf;
+                if (_stat(source.c_str(), &stat_buf) != 0)
+                    return false;
+#else
+                struct stat stat_buf;
+                if (stat(source.c_str(), &stat_buf) != 0)
+                    return false;
 #endif
+                if (filestamp >= stat_buf.st_mtime)
+                    return false;
+
+                // If necessary, elevate lock and recheck.
+                if (lock) {
+                    log.debug("timestamp of local resource changed, elevating to a write lock");
+                    lock->unlock();
+                    lock->wrlock();
+                    if (filestamp >= stat_buf.st_mtime) {
+                        // Somebody else handled it, just downgrade.
+                        log.debug("update of local resource handled by another thread, downgrading lock");
+                        lock->unlock();
+                        lock->rdlock();
+                        return false;
+                    }
+                }
 
-    class XMLTOOL_DLLLOCAL FilesystemCredentialResolver;
-    class XMLTOOL_DLLLOCAL FilesystemCredential : public OpenSSLCredential, public BasicX509Credential
-    {
+                // Update the timestamp regardless. No point in repeatedly trying.
+                filestamp = stat_buf.st_mtime;
+                log.info("change detected, reloading local resource...");
+            }
+            else {
+                time_t now = time(NULL);
+
+                // Time to reload?
+                if (now - filestamp < reloadInterval)
+                    return false;
+
+                // If necessary, elevate lock and recheck.
+                if (lock) {
+                    log.debug("reload interval for remote resource elapsed, elevating to a write lock");
+                    lock->unlock();
+                    lock->wrlock();
+                    if (now - filestamp < reloadInterval) {
+                        // Somebody else handled it, just downgrade.
+                        log.debug("update of remote resource handled by another thread, downgrading lock");
+                        lock->unlock();
+                        lock->rdlock();
+                        return false;
+                    }
+                }
+
+                filestamp = now;
+                log.info("reloading remote resource...");
+            }
+            return true;
+        }
+
+        bool local,reloadChanges;
+        string format,source,backing;
+        time_t filestamp,reloadInterval;
+    };
+
+    class XMLTOOL_DLLLOCAL ManagedKey : public ManagedResource {
     public:
-        FilesystemCredential(
-            FilesystemCredentialResolver* resolver, XSECCryptoKey* key, const std::vector<XSECCryptoX509*>& xseccerts, XSECCryptoX509CRL* crl=NULL
-            ) : BasicX509Credential(key, xseccerts, crl), m_resolver(resolver), m_usage(UNSPECIFIED_CREDENTIAL) {
-            extract();
+        ManagedKey() : key(NULL) {}
+        ~ManagedKey() { delete key; }
+        void load(Category& log, const char* password) {
+            if (source.empty())
+                return;
+            XSECCryptoKey* nkey=NULL;
+            if (local) {
+                nkey = SecurityHelper::loadKeyFromFile(source.c_str(), format.c_str(), password);
+            }
+            else {
+                auto_ptr<SOAPTransport> t(getTransport());
+                log.info("loading private key from URL (%s)", source.c_str());
+                nkey = SecurityHelper::loadKeyFromURL(*t.get(), backing.c_str(), format.c_str(), password);
+            }
+            delete key;
+            key = nkey;
+            if (format.empty())
+                format = SecurityHelper::guessEncodingFormat(local ? source.c_str() : backing.c_str());
         }
-        virtual ~FilesystemCredential() {
+
+        XSECCryptoKey* key;
+    };
+
+    class XMLTOOL_DLLLOCAL ManagedCert : public ManagedResource {
+    public:
+        ManagedCert() {}
+        ~ManagedCert() { for_each(certs.begin(), certs.end(), xmltooling::cleanup<XSECCryptoX509>()); }
+        void load(Category& log, const char* password) {
+            if (source.empty())
+                return;
+            vector<XSECCryptoX509*> ncerts;
+            if (local) {
+                SecurityHelper::loadCertificatesFromFile(ncerts, source.c_str(), format.c_str(), password);
+            }
+            else {
+                auto_ptr<SOAPTransport> t(getTransport());
+                log.info("loading certificate(s) from URL (%s)", source.c_str());
+                SecurityHelper::loadCertificatesFromURL(ncerts, *t.get(), backing.c_str(), format.c_str(), password);
+            }
+            for_each(certs.begin(), certs.end(), xmltooling::cleanup<XSECCryptoX509>());
+            certs = ncerts;
+            if (format.empty())
+                format = SecurityHelper::guessEncodingFormat(local ? source.c_str() : backing.c_str());
         }
+        vector<XSECCryptoX509*> certs;
+    };
 
-        unsigned int getUsage() const {
-            return m_usage;
-        }
-
-        void setUsage(const XMLCh* usage) {
-            if (usage && *usage) {
-                auto_ptr_char u(usage);
-                if (!strcmp(u.get(), "signing"))
-                    m_usage = SIGNING_CREDENTIAL | TLS_CREDENTIAL;
-                else if (!strcmp(u.get(), "TLS"))
-                    m_usage = TLS_CREDENTIAL;
-                else if (!strcmp(u.get(), "encryption"))
-                    m_usage = ENCRYPTION_CREDENTIAL;
+    class XMLTOOL_DLLLOCAL ManagedCRL : public ManagedResource {
+    public:
+        ManagedCRL() {}
+        ~ManagedCRL() { for_each(crls.begin(), crls.end(), xmltooling::cleanup<XSECCryptoX509CRL>()); }
+        void load(Category& log) {
+            if (source.empty())
+                return;
+            vector<XSECCryptoX509CRL*> ncrls;
+            if (local) {
+                SecurityHelper::loadCRLsFromFile(ncrls, source.c_str(), format.c_str());
+            }
+            else {
+                auto_ptr<SOAPTransport> t(getTransport());
+                log.info("loading CRL(s) from URL (%s)", source.c_str());
+                SecurityHelper::loadCRLsFromURL(ncrls, *t.get(), backing.c_str(), format.c_str());
             }
+            for_each(crls.begin(), crls.end(), xmltooling::cleanup<XSECCryptoX509CRL>());
+            crls = ncrls;
+            if (format.empty())
+                format = SecurityHelper::guessEncodingFormat(local ? source.c_str() : backing.c_str());
         }
+        vector<XSECCryptoX509CRL*> crls;
+    };
 
-        void addKeyNames(const DOMElement* e);
+    class XMLTOOL_DLLLOCAL FilesystemCredential;
+    class XMLTOOL_DLLLOCAL FilesystemCredentialResolver : public CredentialResolver
+    {
+        friend class XMLTOOL_DLLLOCAL FilesystemCredential;
+    public:
+        FilesystemCredentialResolver(const DOMElement* e);
+        virtual ~FilesystemCredentialResolver();
 
-        void initKeyInfo(unsigned int types=0) {
-            BasicX509Credential::initKeyInfo(types);
+        Lockable* lock();
+        void unlock() {
+            m_lock->unlock();
         }
 
-        void attach(SSL_CTX* ctx) const;
+        const Credential* resolve(const CredentialCriteria* criteria=NULL) const;
+
+        virtual vector<const Credential*>::size_type resolve(
+            vector<const Credential*>& results, const CredentialCriteria* criteria=NULL
+            ) const;
 
     private:
-        FilesystemCredentialResolver* m_resolver;
-        unsigned int m_usage;
+        Credential* getCredential();
+
+        RWLock* m_lock;
+        Credential* m_credential;
+        string m_keypass,m_certpass;
+        unsigned int m_keyinfomask,m_usage;
+        vector<string> m_keynames;
+
+        ManagedKey m_key;
+        vector<ManagedCert> m_certs;
+        vector<ManagedCRL> m_crls;
     };
 
 #if defined (_MSC_VER)
-    #pragma warning( pop )
+    #pragma warning( push )
+    #pragma warning( disable : 4250 )
 #endif
 
-    class XMLTOOL_DLLLOCAL FilesystemCredentialResolver : public CredentialResolver
+    class XMLTOOL_DLLLOCAL FilesystemCredential : public OpenSSLCredential, public BasicX509Credential
     {
     public:
-        FilesystemCredentialResolver(const DOMElement* e);
-        virtual ~FilesystemCredentialResolver() {
-            delete m_credential;
-            for_each(m_certs.begin(),m_certs.end(),X509_free);
+        FilesystemCredential(
+            FilesystemCredentialResolver* resolver, XSECCryptoKey* key, const vector<XSECCryptoX509*>& xseccerts, const vector<XSECCryptoX509CRL*>& crls
+            ) : BasicX509Credential(key ? key : (xseccerts.empty() ? NULL : xseccerts.front()->clonePublicKey()), xseccerts, crls), m_resolver(resolver) {
+            extract();
+            m_keyNames.insert(m_resolver->m_keynames.begin(), m_resolver->m_keynames.end());
         }
 
-        Lockable* lock() { return this; }
-        void unlock() {}
+        virtual ~FilesystemCredential() {
+        }
 
-        const Credential* resolve(const CredentialCriteria* criteria=NULL) const {
-            return (criteria ? (criteria->matches(*m_credential) ? m_credential : NULL) : m_credential);
+        unsigned int getUsage() const {
+            return m_resolver->m_usage;
         }
 
-        virtual vector<const Credential*>::size_type resolve(
-            vector<const Credential*>& results, const CredentialCriteria* criteria=NULL
-            ) const {
-            if (!criteria || criteria->matches(*m_credential)) {
-                results.push_back(m_credential);
-                return 1;
-            }
-            return 0;
+        void initKeyInfo(unsigned int types=0) {
+            BasicX509Credential::initKeyInfo(types);
         }
 
         void attach(SSL_CTX* ctx) const;
 
     private:
-        XSECCryptoKey* loadKey();
-        XSECCryptoX509CRL* loadCRL();
-
-        enum format_t { PEM=SSL_FILETYPE_PEM, DER=SSL_FILETYPE_ASN1, _PKCS12, UNKNOWN };
-
-        format_t getEncodingFormat(BIO* in) const;
-        string formatToString(format_t format) const;
-        format_t xmlFormatToFormat(const XMLCh* format_xml) const;
-
-        format_t m_keyformat,m_crlformat;
-        string m_keypath,m_keypass,m_crlpath;
-        vector<X509*> m_certs;
-        FilesystemCredential* m_credential;
+        FilesystemCredentialResolver* m_resolver;
     };
 
+#if defined (_MSC_VER)
+    #pragma warning( pop )
+#endif
+
     CredentialResolver* XMLTOOL_DLLLOCAL FilesystemCredentialResolverFactory(const DOMElement* const & e)
     {
         return new FilesystemCredentialResolver(e);
     }
 
-    static const XMLCh _CredentialResolver[] =  UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
+    static const XMLCh backingFilePath[] =  UNICODE_LITERAL_15(b,a,c,k,i,n,g,F,i,l,e,P,a,t,h);
+    static const XMLCh _CredentialResolver[] = UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
     static const XMLCh CAPath[] =           UNICODE_LITERAL_6(C,A,P,a,t,h);
     static const XMLCh Certificate[] =      UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);
     static const XMLCh _certificate[] =     UNICODE_LITERAL_11(c,e,r,t,i,f,i,c,a,t,e);
     static const XMLCh CRL[] =              UNICODE_LITERAL_3(C,R,L);
-    static const XMLCh format[] =           UNICODE_LITERAL_6(f,o,r,m,a,t);
+    static const XMLCh _format[] =          UNICODE_LITERAL_6(f,o,r,m,a,t);
     static const XMLCh Key[] =              UNICODE_LITERAL_3(K,e,y);
     static const XMLCh _key[] =             UNICODE_LITERAL_3(k,e,y);
     static const XMLCh keyInfoMask[] =      UNICODE_LITERAL_11(k,e,y,I,n,f,o,M,a,s,k);
@@ -173,10 +290,14 @@ namespace xmltooling {
     static const XMLCh Name[] =             UNICODE_LITERAL_4(N,a,m,e);
     static const XMLCh password[] =         UNICODE_LITERAL_8(p,a,s,s,w,o,r,d);
     static const XMLCh Path[] =             UNICODE_LITERAL_4(P,a,t,h);
+    static const XMLCh _reloadChanges[] =   UNICODE_LITERAL_13(r,e,l,o,a,d,C,h,a,n,g,e,s);
+    static const XMLCh _reloadInterval[] =  UNICODE_LITERAL_14(r,e,l,o,a,d,I,n,t,e,r,v,a,l);
+    static const XMLCh _URL[] =             UNICODE_LITERAL_3(U,R,L);
     static const XMLCh _use[] =             UNICODE_LITERAL_3(u,s,e);
 };
 
-FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e) : m_credential(NULL)
+FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
+    : m_lock(NULL), m_credential(NULL), m_usage(Credential::UNSPECIFIED_CREDENTIAL)
 {
 #ifdef _DEBUG
     NDC ndc("FilesystemCredentialResolver");
@@ -184,13 +305,13 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
     Category& log=Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER);
 
     // Default to disable X509IssuerSerial due to schema validation issues.
-    unsigned int mask =
+    m_keyinfomask =
         Credential::KEYINFO_KEY_NAME |
         Credential::KEYINFO_KEY_VALUE |
         X509Credential::KEYINFO_X509_CERTIFICATE |
         X509Credential::KEYINFO_X509_SUBJECTNAME;
     if (e && e->hasAttributeNS(NULL,keyInfoMask))
-        mask = XMLString::parseInt(e->getAttributeNS(NULL,keyInfoMask));
+        m_keyinfomask = XMLString::parseInt(e->getAttributeNS(NULL,keyInfoMask));
 
     if (e && (e->hasAttributeNS(NULL,_certificate) || e->hasAttributeNS(NULL,_key))) {
         // Dummy up a simple file resolver config using these attributes.
@@ -221,559 +342,405 @@ FilesystemCredentialResolver::FilesystemCredentialResolver(const DOMElement* e)
         e = dummy;  // reset "root" to the dummy config element
     }
 
-    const DOMElement* root=e;
-    const XMLCh* usage = root->getAttributeNS(NULL,_use);
-
-    XSECCryptoKey* key=NULL;
-    vector<XSECCryptoX509*> xseccerts;
-    XSECCryptoX509CRL* crl=NULL;
+    const XMLCh* prop;
+    const DOMElement* root = e;
 
-    format_t fformat;
-    const XMLCh* format_xml=NULL;
-    BIO* in = NULL;
+    // Save off usage flags.
+    const XMLCh* usage = root->getAttributeNS(NULL,_use);
+    if (usage && *usage) {
+        auto_ptr_char u(usage);
+        if (!strcmp(u.get(), "signing"))
+            m_usage = Credential::SIGNING_CREDENTIAL | Credential::TLS_CREDENTIAL;
+        else if (!strcmp(u.get(), "TLS"))
+            m_usage = Credential::TLS_CREDENTIAL;
+        else if (!strcmp(u.get(), "encryption"))
+            m_usage = Credential::ENCRYPTION_CREDENTIAL;
+    }
 
-    // Move to Key
-    const DOMElement* keynode=XMLHelper::getFirstChildElement(root,Key);
+    // Move to Key.
+    const DOMElement* keynode = XMLHelper::getFirstChildElement(root,Key);
     if (keynode) {
-        // Get raw format attrib value, but defer processing til later since may need to
-        // determine format dynamically, and we need the Path for that.
-        format_xml=keynode->getAttributeNS(NULL,format);
-
-        const XMLCh* password_xml=keynode->getAttributeNS(NULL,password);
-        if (password_xml) {
-            auto_ptr_char kp(password_xml);
-            m_keypass=kp.get();
-        }
-
-        e=XMLHelper::getFirstChildElement(keynode,Path);
-        if (e && e->hasChildNodes()) {
-            const XMLCh* s=e->getFirstChild()->getNodeValue();
-            auto_ptr_char kpath(s);
-            m_keypath = kpath.get();
-            XMLToolingConfig::getConfig().getPathResolver()->resolve(m_keypath, PathResolver::XMLTOOLING_CFG_FILE);
-#ifdef WIN32
-            struct _stat stat_buf;
-            if (_stat(m_keypath.c_str(), &stat_buf) != 0)
-#else
-            struct stat stat_buf;
-            if (stat(m_keypath.c_str(), &stat_buf) != 0)
-#endif
-            {
-                log.error("key file (%s) can't be opened", m_keypath.c_str());
-                throw XMLSecurityException("FilesystemCredentialResolver can't access key file ($1)",params(1,m_keypath.c_str()));
-            }
+        prop = keynode->getAttributeNS(NULL,_format);
+        if (prop && *prop) {
+            auto_ptr_char f(prop);
+            m_key.format = f.get();
+        }
+
+        prop = keynode->getAttributeNS(NULL,password);
+        if (prop && *prop) {
+            auto_ptr_char kp(prop);
+            m_keypass = kp.get();
+        }
+
+        if ((e=XMLHelper::getFirstChildElement(keynode,Path)) && e->hasChildNodes()) {
+            prop = e->getFirstChild()->getNodeValue();
+            auto_ptr_char kpath(prop);
+            m_key.source = kpath.get();
+            XMLToolingConfig::getConfig().getPathResolver()->resolve(m_key.source, PathResolver::XMLTOOLING_CFG_FILE);
+            m_key.local = true;
+            prop = e->getAttributeNS(NULL,_reloadChanges);
+            if (prop && (*prop==chLatin_f) || (*prop==chDigit_0))
+                m_key.reloadChanges = false;
+        }
+        else if ((e=XMLHelper::getFirstChildElement(keynode,_URL)) && e->hasChildNodes()) {
+            prop = e->getFirstChild()->getNodeValue();
+            auto_ptr_char kpath(prop);
+            m_key.source = kpath.get();
+            m_key.local = false;
+            prop = e->getAttributeNS(NULL,backingFilePath);
+            if (!prop || !*prop)
+                throw XMLSecurityException("FilesystemCredentialResolver can't access key, backingFilePath missing from URL element.");
+            auto_ptr_char b(prop);
+            m_key.backing = b.get();
+            XMLToolingConfig::getConfig().getPathResolver()->resolve(m_key.backing, PathResolver::XMLTOOLING_RUN_FILE);
+            prop = e->getAttributeNS(NULL,_reloadInterval);
+            if (prop && *prop)
+                m_key.reloadInterval = XMLString::parseInt(prop);
         }
         else {
-            log.error("Path element missing inside Key element");
-            throw XMLSecurityException("FilesystemCredentialResolver can't access key file, no Path element specified.");
+            log.error("Path/URL element missing inside Key element");
+            throw XMLSecurityException("FilesystemCredentialResolver can't access key, no Path or URL element specified.");
         }
 
-        // Determine the key encoding format dynamically, if not explicitly specified
-        if (format_xml && *format_xml) {
-            fformat = xmlFormatToFormat(format_xml);
-            if (fformat != UNKNOWN) {
-                m_keyformat = fformat;
-            }
-            else {
-                auto_ptr_char unknown(format_xml);
-                log.error("configuration specifies unknown key encoding format (%s)", unknown.get());
-                throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown key encoding format ($1)",params(1,unknown.get()));
+        e = XMLHelper::getFirstChildElement(keynode, Name);
+        while (e) {
+            if (e->hasChildNodes()) {
+                auto_ptr_char n(e->getFirstChild()->getNodeValue());
+                if (n.get() && *n.get())
+                    m_keynames.push_back(n.get());
             }
+            e = XMLHelper::getNextSiblingElement(e, Name);
         }
-        else {
-            in=BIO_new(BIO_s_file_internal());
-            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
-                m_keyformat = getEncodingFormat(in);
-                log.debug("key encoding format for (%s) dynamically resolved as (%s)", m_keypath.c_str(), formatToString(m_keyformat).c_str());
-            }
-            else {
-                log.error("key file (%s) can't be read to determine encoding format", m_keypath.c_str());
-                throw XMLSecurityException("FilesystemCredentialResolver can't read key file ($1) to determine encoding format",params(1,m_keypath.c_str()));
-            }
-            if (in)
-                BIO_free(in);
-            in = NULL;
-        }
-
-        // Load the key.
-        key = loadKey();
     }
 
     // Check for CRL.
-    const DOMElement* crlnode=XMLHelper::getFirstChildElement(root,CRL);
+    const DOMElement* crlnode = XMLHelper::getFirstChildElement(root,CRL);
     if (crlnode) {
-        // Get raw format attrib value, but defer processing til later since may need to
-        // determine format dynamically, and we need the Path for that.
-        format_xml=crlnode->getAttributeNS(NULL,format);
-
-        e=XMLHelper::getFirstChildElement(crlnode,Path);
-        if (e && e->hasChildNodes()) {
-            const XMLCh* s=e->getFirstChild()->getNodeValue();
-            auto_ptr_char kpath(s);
-            m_crlpath=kpath.get();
-            XMLToolingConfig::getConfig().getPathResolver()->resolve(m_crlpath, PathResolver::XMLTOOLING_CFG_FILE);
-#ifdef WIN32
-            struct _stat stat_buf;
-            if (_stat(m_crlpath.c_str(), &stat_buf) != 0)
-#else
-            struct stat stat_buf;
-            if (stat(m_crlpath.c_str(), &stat_buf) != 0)
-#endif
-            {
-                log.error("CRL file (%s) can't be opened", m_crlpath.c_str());
-                throw XMLSecurityException("FilesystemCredentialResolver can't access CRL file ($1)",params(1,m_crlpath.c_str()));
+        const XMLCh* crlformat = crlnode->getAttributeNS(NULL,_format);
+        e = XMLHelper::getFirstChildElement(crlnode,Path);
+        while (e) {
+            if (e->hasChildNodes()) {
+                m_crls.push_back(ManagedCRL());
+                ManagedResource& crl = m_crls.back();
+                if (crlformat && *crlformat) {
+                    auto_ptr_char f(crlformat);
+                    crl.format = f.get();
+                }
+                prop = e->getFirstChild()->getNodeValue();
+                auto_ptr_char crlpath(prop);
+                crl.source = crlpath.get();
+                XMLToolingConfig::getConfig().getPathResolver()->resolve(crl.source, PathResolver::XMLTOOLING_CFG_FILE);
+                crl.local = true;
+                prop = e->getAttributeNS(NULL,_reloadChanges);
+                if (prop && (*prop==chLatin_f) || (*prop==chDigit_0))
+                    crl.reloadChanges = false;
             }
-        }
-        else {
-            log.error("Path element missing inside CRL element");
-            throw XMLSecurityException("FilesystemCredentialResolver can't access CRL file, no Path element specified.");
+            e = XMLHelper::getNextSiblingElement(e,Path);
         }
 
-        // Determine the CRL encoding format dynamically, if not explicitly specified
-        if (format_xml && *format_xml) {
-            fformat = xmlFormatToFormat(format_xml);
-            if (fformat != UNKNOWN) {
-                m_crlformat = fformat;
-            }
-            else {
-                auto_ptr_char unknown(format_xml);
-                log.error("configuration specifies unknown CRL encoding format (%s)", unknown.get());
-                throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown CRL encoding format ($1)",params(1,unknown.get()));
+        e=XMLHelper::getFirstChildElement(crlnode,_URL);
+        while (e) {
+            if (e->hasChildNodes()) {
+                m_crls.push_back(ManagedCRL());
+                ManagedResource& crl = m_crls.back();
+                if (crlformat && *crlformat) {
+                    auto_ptr_char f(crlformat);
+                    crl.format = f.get();
+                }
+                prop = e->getFirstChild()->getNodeValue();
+                auto_ptr_char crlpath(prop);
+                crl.source = crlpath.get();
+                crl.local = false;
+                prop = e->getAttributeNS(NULL,backingFilePath);
+                if (!prop || !*prop)
+                    throw XMLSecurityException("FilesystemCredentialResolver can't access CRL, backingFilePath missing from URL element.");
+                auto_ptr_char b(prop);
+                crl.backing = b.get();
+                XMLToolingConfig::getConfig().getPathResolver()->resolve(crl.backing, PathResolver::XMLTOOLING_RUN_FILE);
+                prop = e->getAttributeNS(NULL,_reloadInterval);
+                if (prop && *prop)
+                    crl.reloadInterval = XMLString::parseInt(prop);
             }
+            e = XMLHelper::getNextSiblingElement(e,_URL);
         }
-        else {
-            in=BIO_new(BIO_s_file_internal());
-            if (in && BIO_read_filename(in,m_crlpath.c_str())>0) {
-                m_crlformat = getEncodingFormat(in);
-                log.debug("CRL encoding format for (%s) dynamically resolved as (%s)", m_crlpath.c_str(), formatToString(m_crlformat).c_str());
+        if (m_crls.empty()) {
+            log.error("Path/URL element missing inside CRL element");
+            throw XMLSecurityException("FilesystemCredentialResolver can't access CRL, no Path or URL element specified.");
+        }
+    }
+
+    // Check for Certificate
+    DOMElement* certnode = XMLHelper::getFirstChildElement(root,Certificate);
+    if (certnode) {
+        prop = certnode->getAttributeNS(NULL,password);
+        if (prop && *prop) {
+            auto_ptr_char certpass(prop);
+            m_certpass = certpass.get();
+        }
+
+        const XMLCh* certformat = certnode->getAttributeNS(NULL,_format);
+
+        e = XMLHelper::getFirstChildElement(certnode);
+        while (e) {
+            if (e->hasChildNodes() && (XMLString::equals(e->getLocalName(), Path) || XMLString::equals(e->getLocalName(), CAPath))) {
+                m_certs.push_back(ManagedCert());
+                ManagedResource& cert = m_certs.back();
+                if (certformat && *certformat) {
+                    auto_ptr_char f(certformat);
+                    cert.format = f.get();
+                }
+                prop = e->getFirstChild()->getNodeValue();
+                auto_ptr_char certpath(prop);
+                cert.source = certpath.get();
+                XMLToolingConfig::getConfig().getPathResolver()->resolve(cert.source, PathResolver::XMLTOOLING_CFG_FILE);
+                cert.local = true;
+                prop = e->getAttributeNS(NULL,_reloadChanges);
+                if (prop && (*prop==chLatin_f) || (*prop==chDigit_0))
+                    cert.reloadChanges = false;
             }
-            else {
-                log.error("CRL file (%s) can't be read to determine encoding format", m_crlpath.c_str());
-                throw XMLSecurityException("FilesystemCredentialResolver can't read CRL file ($1) to determine encoding format",params(1,m_crlpath.c_str()));
+            else if (e->hasChildNodes() && XMLString::equals(e->getLocalName(), _URL)) {
+                m_certs.push_back(ManagedCert());
+                ManagedResource& cert = m_certs.back();
+                if (certformat && *certformat) {
+                    auto_ptr_char f(certformat);
+                    cert.format = f.get();
+                }
+                prop = e->getFirstChild()->getNodeValue();
+                auto_ptr_char certpath(prop);
+                cert.source = certpath.get();
+                cert.local = false;
+                prop = e->getAttributeNS(NULL,backingFilePath);
+                if (!prop || !*prop)
+                    throw XMLSecurityException("FilesystemCredentialResolver can't access certificate, backingFilePath missing from URL element.");
+                auto_ptr_char b(prop);
+                cert.backing = b.get();
+                XMLToolingConfig::getConfig().getPathResolver()->resolve(cert.backing, PathResolver::XMLTOOLING_RUN_FILE);
+                prop = e->getAttributeNS(NULL,_reloadInterval);
+                if (prop && *prop)
+                    cert.reloadInterval = XMLString::parseInt(prop);
             }
-            if (in)
-                BIO_free(in);
-            in = NULL;
+            e = XMLHelper::getNextSiblingElement(e);
+        }
+        if (m_certs.empty()) {
+            log.error("Path/URL element missing inside Certificate element");
+            throw XMLSecurityException("FilesystemCredentialResolver can't access certificate, no Path or URL element specified.");
         }
-
-        // Load the key.
-        crl = loadCRL();
     }
 
-    // Check for Certificate
-    e=XMLHelper::getFirstChildElement(root,Certificate);
-    if (!e) {
-        m_credential = new FilesystemCredential(this,key,xseccerts,crl);
-        m_credential->addKeyNames(keynode);
-        m_credential->setUsage(usage);
-        m_credential->initKeyInfo(mask);
-        return;
+    // Do an initial load of all the objects. If anything blows up here, whatever's
+    // been loaded should be freed during teardown of the embedded objects.
+    time_t now = time(NULL);
+    m_key.filestamp = now;
+    m_key.load(log, m_keypass.c_str());
+    for (vector<ManagedCert>::iterator i = m_certs.begin(); i != m_certs.end(); ++i) {
+        i->load(log, (i==m_certs.begin()) ? m_certpass.c_str() : NULL);
+        i->filestamp = now;
     }
-    auto_ptr_char certpass(e->getAttributeNS(NULL,password));
-
-    const DOMElement* ep=XMLHelper::getFirstChildElement(e,Path);
-    if (!ep || !ep->hasChildNodes()) {
-        log.error("Path element missing inside Certificate element or is empty");
-        delete key;
-        delete crl;
-        throw XMLSecurityException("FilesystemCredentialResolver can't access certificate file, missing or empty Path element.");
+    for (vector<ManagedCRL>::iterator j = m_crls.begin(); j != m_crls.end(); ++j) {
+        j->load(log);
+        j->filestamp = now;
     }
 
-    auto_ptr_char certpath2(ep->getFirstChild()->getNodeValue());
-    string certpath(certpath2.get());
-    XMLToolingConfig::getConfig().getPathResolver()->resolve(certpath, PathResolver::XMLTOOLING_CFG_FILE);
+    // Load it all into a credential object and then create the lock.
+    auto_ptr<Credential> credential(getCredential());
+    m_lock = RWLock::create();
+    m_credential = credential.release();
+}
+
+FilesystemCredentialResolver::~FilesystemCredentialResolver()
+{
+    delete m_credential;
+    delete m_lock;
+}
 
-    format_xml=e->getAttributeNS(NULL,format);
-    if (format_xml && *format_xml) {
-        fformat = xmlFormatToFormat(format_xml);
-        if (fformat == UNKNOWN) {
-            auto_ptr_char unknown(format_xml);
-            log.error("configuration specifies unknown certificate encoding format (%s)", unknown.get());
-            delete key;
-            delete crl;
-            throw XMLSecurityException("FilesystemCredentialResolver configuration contains unknown certificate encoding format ($1)",params(1,unknown.get()));
-        }
+Credential* FilesystemCredentialResolver::getCredential()
+{
+    // First, verify that the key and certificate match.
+    if (m_key.key && !m_certs.empty()) {
+        auto_ptr<XSECCryptoKey> temp(m_certs.front().certs.front()->clonePublicKey());
+        if (!SecurityHelper::matches(*m_key.key, *temp.get()))
+            throw XMLSecurityException("FilesystemCredentialResolver given mismatched key/certificate, check for consistency.");
     }
 
+    // We (unfortunately) need to duplicate all the objects and put them in one set of arrays
+    // in order to create the credential wrapper.
+    FilesystemCredential* credential=NULL;
+    auto_ptr<XSECCryptoKey> xseckey(m_key.key ? m_key.key->clone() : NULL);
+    vector<XSECCryptoX509*> xseccerts;
+    vector<XSECCryptoX509CRL*> xseccrls;
     try {
-        X509* x=NULL;
-        PKCS12* p12=NULL;
-        in=BIO_new(BIO_s_file_internal());
-        if (in && BIO_read_filename(in,certpath.c_str())>0) {
-            if (!format_xml || !*format_xml) {
-                // Determine the cert encoding format dynamically, if not explicitly specified
-                fformat = getEncodingFormat(in);
-                log.debug("certificate encoding format for (%s) dynamically resolved as (%s)", certpath.c_str(), formatToString(fformat).c_str());
-            }
-
-            Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER).info(
-                "loading certificate from file (%s)", certpath.c_str()
-                );
-
-            switch(fformat) {
-                case PEM:
-                    while (x=PEM_read_bio_X509(in,NULL,passwd_callback,const_cast<char*>(certpass.get())))
-                        m_certs.push_back(x);
-                    break;
-
-                case DER:
-                    x=d2i_X509_bio(in,NULL);
-                    if (x)
-                        m_certs.push_back(x);
-                    else {
-                        log_openssl();
-                        BIO_free(in);
-                        throw XMLSecurityException("FilesystemCredentialResolver unable to load DER certificate from file ($1)",params(1,certpath.c_str()));
-                    }
-                    break;
-
-                case _PKCS12:
-                    p12=d2i_PKCS12_bio(in,NULL);
-                    if (p12) {
-                        PKCS12_parse(p12, certpass.get(), NULL, &x, NULL);
-                        PKCS12_free(p12);
-                    }
-                    if (x) {
-                        m_certs.push_back(x);
-                        x=NULL;
-                    } else {
-                        log_openssl();
-                        BIO_free(in);
-                        throw XMLSecurityException("FilesystemCredentialResolver unable to load PKCS12 certificate from file ($1)",params(1,certpath.c_str()));
-                    }
-                    break;
-            } // end switch
-
-        } else {
-            log_openssl();
-            if (in) {
-                BIO_free(in);
-                in=NULL;
-            }
-            throw XMLSecurityException("FilesystemCredentialResolver unable to load certificate(s) from file ($1)",params(1,certpath.c_str()));
+        for (vector<ManagedCert>::iterator i = m_certs.begin(); i != m_certs.end(); ++i) {
+            for (vector<XSECCryptoX509*>::const_iterator y = i->certs.begin(); y != i->certs.end(); ++y)
+                xseccerts.push_back(new OpenSSLCryptoX509(static_cast<OpenSSLCryptoX509*>(*y)->getOpenSSLX509()));
         }
-        if (in) {
-            BIO_free(in);
-            in=NULL;
-        }
-
-        if (m_certs.empty())
-            throw XMLSecurityException("FilesystemCredentialResolver unable to load any certificate(s)");
-
-        // Load any extra CA files.
-        const DOMElement* extra=XMLHelper::getFirstChildElement(e,CAPath);
-        while (extra) {
-            if (!extra->hasChildNodes()) {
-                log.warn("skipping empty CAPath element");
-                extra = XMLHelper::getNextSiblingElement(extra,CAPath);
-                continue;
-            }
-            auto_ptr_char capath2(extra->getFirstChild()->getNodeValue());
-            string capath(capath2.get());
-            XMLToolingConfig::getConfig().getPathResolver()->resolve(capath, PathResolver::XMLTOOLING_CFG_FILE);
-            x=NULL;
-            p12=NULL;
-            in=BIO_new(BIO_s_file_internal());
-            if (in && BIO_read_filename(in,capath.c_str())>0) {
-                if (!format_xml || !*format_xml) {
-                    // Determine the cert encoding format dynamically, if not explicitly specified
-                    fformat = getEncodingFormat(in);
-                    log.debug("CA certificate encoding format for (%s) dynamically resolved as (%s)", capath.c_str(), formatToString(fformat).c_str());
-                }
-
-                Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER).info(
-                    "loading CA certificate from file (%s)", capath.c_str()
-                    );
-
-                switch (fformat) {
-                    case PEM:
-                        while (x=PEM_read_bio_X509(in,NULL,NULL,NULL))
-                            m_certs.push_back(x);
-                        break;
-
-                    case DER:
-                        x=d2i_X509_bio(in,NULL);
-                        if (x)
-                            m_certs.push_back(x);
-                        else {
-                            log_openssl();
-                            BIO_free(in);
-                            throw XMLSecurityException("FilesystemCredentialResolver unable to load DER CA certificate from file ($1)",params(1,capath.c_str()));
-                        }
-                        break;
-
-                    case _PKCS12:
-                        p12 = d2i_PKCS12_bio(in, NULL);
-                        if (p12) {
-                            PKCS12_parse(p12, NULL, NULL, &x, NULL);
-                            PKCS12_free(p12);
-                        }
-                        if (x) {
-                            m_certs.push_back(x);
-                            x=NULL;
-                        }
-                        else {
-                            log_openssl();
-                            BIO_free(in);
-                            throw XMLSecurityException("FilesystemCredentialResolver unable to load PKCS12 CA certificate from file ($1)",params(1,capath.c_str()));
-                        }
-                        break;
-                } //end switch
-
-                BIO_free(in);
-            }
-            else {
-                if (in)
-                    BIO_free(in);
-                log_openssl();
-                log.error("CA certificate file (%s) can't be opened", capath.c_str());
-                throw XMLSecurityException("FilesystemCredentialResolver can't open CA certificate file ($1)",params(1,capath.c_str()));
-            }
-
-            extra = XMLHelper::getNextSiblingElement(extra,CAPath);
+        for (vector<ManagedCRL>::iterator j = m_crls.begin(); j != m_crls.end(); ++j) {
+            for (vector<XSECCryptoX509CRL*>::const_iterator z = j->crls.begin(); z != j->crls.end(); ++z)
+                xseccrls.push_back((*z)->clone());
         }
+        credential = new FilesystemCredential(this, xseckey.get(), xseccerts, xseccrls);
+        xseckey.release();
     }
-    catch (XMLToolingException&) {
-        delete key;
-        delete crl;
-        for_each(m_certs.begin(), m_certs.end(), X509_free);
+    catch (exception&) {
+        for_each(xseccerts.begin(), xseccerts.end(), xmltooling::cleanup<XSECCryptoX509>());
+        for_each(xseccrls.begin(), xseccrls.end(), xmltooling::cleanup<XSECCryptoX509CRL>());
         throw;
     }
 
-    // Reflect certs over to XSEC form and wrap with credential object.
-    for (vector<X509*>::iterator j=m_certs.begin(); j!=m_certs.end(); j++)
-        xseccerts.push_back(new OpenSSLCryptoX509(*j));
-    if (!key && !xseccerts.empty())
-        key = xseccerts.front()->clonePublicKey();
-    m_credential = new FilesystemCredential(this, key, xseccerts, crl);
-    m_credential->addKeyNames(keynode);
-    m_credential->setUsage(usage);
-    m_credential->initKeyInfo(mask);
-}
-
-XSECCryptoKey* FilesystemCredentialResolver::loadKey()
-{
-#ifdef _DEBUG
-    NDC ndc("loadKey");
-#endif
-    Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER).info(
-        "loading private key from file (%s)", m_keypath.c_str()
-        );
-
-    // Get a EVP_PKEY.
-    EVP_PKEY* pkey=NULL;
-    BIO* in=BIO_new(BIO_s_file_internal());
-    if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
-        switch (m_keyformat) {
-            case PEM:
-                pkey=PEM_read_bio_PrivateKey(in, NULL, passwd_callback, const_cast<char*>(m_keypass.c_str()));
-                break;
-
-            case DER:
-                pkey=d2i_PrivateKey_bio(in, NULL);
-                break;
-
-            default: {
-                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
-                if (p12) {
-                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
-                    PKCS12_free(p12);
-                }
-            }
-        }
+    // At this point the copies are owned by the credential.
+    try {
+        credential->initKeyInfo(m_keyinfomask);
     }
-    if (in)
-        BIO_free(in);
-
-    // Now map it to an XSEC wrapper.
-    if (pkey) {
-        XSECCryptoKey* ret=NULL;
-        switch (pkey->type) {
-            case EVP_PKEY_RSA:
-                ret=new OpenSSLCryptoKeyRSA(pkey);
-                break;
-
-            case EVP_PKEY_DSA:
-                ret=new OpenSSLCryptoKeyDSA(pkey);
-                break;
-
-            default:
-                Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER).error("unsupported private key type");
-        }
-        EVP_PKEY_free(pkey);
-        if (ret)
-            return ret;
+    catch (exception&) {
+        delete credential;
+        throw;
     }
 
-    log_openssl();
-    throw XMLSecurityException("FilesystemCredentialResolver unable to load private key from file.");
+    return credential;
 }
 
-XSECCryptoX509CRL* FilesystemCredentialResolver::loadCRL()
+Lockable* FilesystemCredentialResolver::lock()
 {
 #ifdef _DEBUG
-    NDC ndc("loadCRL");
+    NDC ndc("lock");
 #endif
-    Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER).info(
-        "loading CRL from file (%s)", m_crlpath.c_str()
-        );
-
-    X509_CRL* crl=NULL;
-    BIO* in=BIO_new(BIO_s_file_internal());
-    if (in && BIO_read_filename(in,m_crlpath.c_str())>0) {
-        switch (m_crlformat) {
-            case PEM:
-                crl=PEM_read_bio_X509_CRL(in, NULL, NULL, NULL);
-                break;
-
-            case DER:
-                crl=d2i_X509_CRL_bio(in, NULL);
-                break;
-        }
-    }
-    if (in)
-        BIO_free(in);
-
-    // Now map it to an XSEC wrapper.
-    if (crl) {
-        XSECCryptoX509CRL* ret=new OpenSSLCryptoX509CRL(crl);
-        X509_CRL_free(crl);
-        return ret;
-    }
+    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".CredentialResolver."FILESYSTEM_CREDENTIAL_RESOLVER);
 
-    log_openssl();
-    throw XMLSecurityException("FilesystemCredentialResolver unable to load CRL from file.");
-}
+    m_lock->rdlock();
 
-// Used to determine the encoding format of credentials files
-// dynamically. Supports: PEM, DER, PKCS12.
-FilesystemCredentialResolver::format_t FilesystemCredentialResolver::getEncodingFormat(BIO* in) const
-{
-    PKCS12* p12 = NULL;
-    format_t format;
+    // Check each managed resource while holding a read lock for staleness.
+    // If it comes back false, the lock is left as is, and the resource was stable.
+    // If it comes back true, the lock was elevated to a write lock, and the resource
+    // needs to be reloaded, and the credential replaced.
+    // Once a stale check comes back true, further checks leave the lock alone.
 
-    const int READSIZE = 1;
-    char buf[READSIZE];
-    char b1;
-    int mark;
+    bool writelock = false, updated = false;
 
-    try {
-        if ( (mark = BIO_tell(in)) < 0 )
-            throw XMLSecurityException("getEncodingFormat: BIO_tell() can't get the file position");
-        if ( BIO_read(in, buf, READSIZE) <= 0 )
-            throw XMLSecurityException("getEncodingFormat: BIO_read() can't read from the stream");
-        if ( BIO_seek(in, mark) < 0 )
-            throw XMLSecurityException("getEncodingFormat: BIO_seek() can't reset the file position");
+    if (m_key.stale(log, m_lock)) {
+        writelock = true;
+        try {
+            m_key.load(log, m_keypass.c_str());
+            updated = true;
+        }
+        catch (exception& ex) {
+            log.crit("maintaining existing key: %s", ex.what());
+        }
     }
-    catch (...) {
-        log_openssl();
-        throw;
+
+    for (vector<ManagedCert>::iterator i = m_certs.begin(); i != m_certs.end(); ++i) {
+        if (i->stale(log, writelock ? NULL : m_lock)) {
+            writelock = true;
+            try {
+                i->load(log, (i==m_certs.begin()) ? m_certpass.c_str() : NULL);
+                updated = true;
+            }
+            catch (exception& ex) {
+                log.crit("maintaining existing certificate(s): %s", ex.what());
+            }
+        }
+    }
+
+    for (vector<ManagedCRL>::iterator j = m_crls.begin(); j != m_crls.end(); ++j) {
+        if (j->stale(log, writelock ? NULL : m_lock)) {
+            writelock = true;
+            try {
+                j->load(log);
+                updated = true;
+            }
+            catch (exception& ex) {
+                log.crit("maintaining existing CRL(s): %s", ex.what());
+            }
+        }
     }
 
-    b1 = buf[0];
-
-    // This is a slight variation of the Java code by Chad La Joie.
-    //
-    // Check the first byte of the file.  If it's some kind of
-    // DER-encoded structure (including PKCS12), it will begin with ASCII 048.
-    // Otherwise, assume it's PEM.
-    if (b1 !=  48) {
-        format = PEM;
-    } else {
-        // Here we know it's DER-encoded, now try to parse it as a PKCS12
-        // ASN.1 structure.  If it fails, must be another kind of DER-encoded
-        // key/cert structure.  A little inefficient...but it works.
-        if ( (p12=d2i_PKCS12_bio(in,NULL)) == NULL ) {
-            format = DER;
-        } else {
-            format = _PKCS12;
-        }
-        if (p12)
-            PKCS12_free(p12);
-        if ( BIO_seek(in, mark) < 0 ) {
-            log_openssl();
-            throw XMLSecurityException("getEncodingFormat: BIO_seek() can't reset the file position");
+    if (updated) {
+        try {
+            auto_ptr<Credential> credential(getCredential());
+            delete m_credential;
+            m_credential = credential.release();
+        }
+        catch (exception& ex) {
+            log.crit("maintaining existing credentials, error reloading: %s", ex.what());
         }
     }
 
-    return format;
+    if (writelock) {
+        m_lock->unlock();
+        m_lock->rdlock();
+    }
+    return this;
 }
 
-// Convert key/cert format_t types to a human-meaningful string for debug output
-string FilesystemCredentialResolver::formatToString(format_t format) const
+const Credential* FilesystemCredentialResolver::resolve(const CredentialCriteria* criteria) const
 {
-    switch(format) {
-        case PEM:
-            return "PEM";
-        case DER:
-            return "DER";
-        case _PKCS12:
-            return "PKCS12";
-        default:
-            return "UNKNOWN";
+    return (criteria ? (criteria->matches(*m_credential) ? m_credential : NULL) : m_credential);
+}
+
+vector<const Credential*>::size_type FilesystemCredentialResolver::resolve(
+    vector<const Credential*>& results, const CredentialCriteria* criteria
+    ) const
+{
+    if (!criteria || criteria->matches(*m_credential)) {
+        results.push_back(m_credential);
+        return 1;
     }
+    return 0;
 }
 
-// Convert key/cert raw XML format attribute (XMLCh[]) to format_t type
-FilesystemCredentialResolver::format_t FilesystemCredentialResolver::xmlFormatToFormat(const XMLCh* format_xml) const
+// OpenSSL password callback...
+static int passwd_callback(char* buf, int len, int verify, void* passwd)
 {
-    static const XMLCh cPEM[] = UNICODE_LITERAL_3(P,E,M);
-    static const XMLCh cDER[] = UNICODE_LITERAL_3(D,E,R);
-    static const XMLCh cPKCS12[] = { chLatin_P, chLatin_K, chLatin_C, chLatin_S, chDigit_1, chDigit_2, chNull };
-    format_t format;
-
-    if (!XMLString::compareString(format_xml,cPEM))
-        format=PEM;
-    else if (!XMLString::compareString(format_xml,cDER))
-        format=DER;
-    else if (!XMLString::compareString(format_xml,cPKCS12))
-        format=_PKCS12;
-    else
-        format=UNKNOWN;
-
-    return format;
+    if(!verify)
+    {
+        if(passwd && len > strlen(reinterpret_cast<char*>(passwd)))
+        {
+            strcpy(buf,reinterpret_cast<char*>(passwd));
+            return strlen(buf);
+        }
+    }
+    return 0;
 }
 
-void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
+void FilesystemCredential::attach(SSL_CTX* ctx) const
 {
 #ifdef _DEBUG
     NDC ndc("attach");
 #endif
 
-    if (m_keypath.empty())
+    int ret=0;
+    const char* path = m_resolver->m_key.local ? m_resolver->m_key.source.c_str() : m_resolver->m_key.backing.c_str();
+    if (!path || !*path)
         throw XMLSecurityException("No key available, unable to attach private key to SSL context.");
 
-    // Attach key.
-    SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
-    SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_keypass.c_str()));
+    if (!m_resolver->m_keypass.empty()) {
+        SSL_CTX_set_default_passwd_cb(ctx, passwd_callback);
+        SSL_CTX_set_default_passwd_cb_userdata(ctx, const_cast<char*>(m_resolver->m_keypass.c_str()));
+    }
 
-    int ret=0;
-    switch (m_keyformat) {
-        case PEM:
-            ret=SSL_CTX_use_PrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
-            break;
-
-        case DER:
-            ret=SSL_CTX_use_RSAPrivateKey_file(ctx, m_keypath.c_str(), m_keyformat);
-            break;
-
-        default: {
-            BIO* in=BIO_new(BIO_s_file_internal());
-            if (in && BIO_read_filename(in,m_keypath.c_str())>0) {
+    if (m_resolver->m_key.format == "PEM") {
+        ret=SSL_CTX_use_PrivateKey_file(ctx, path, SSL_FILETYPE_PEM);
+    }
+    else if (m_resolver->m_key.format == "DER") {
+        ret=SSL_CTX_use_RSAPrivateKey_file(ctx, path, SSL_FILETYPE_ASN1);
+    }
+    else if (m_resolver->m_key.format == "PKCS12") {
+        BIO* in=BIO_new(BIO_s_file_internal());
+        if (in && BIO_read_filename(in,path)>0) {
+            PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
+            if (p12) {
                 EVP_PKEY* pkey=NULL;
-                PKCS12* p12 = d2i_PKCS12_bio(in, NULL);
-                if (p12) {
-                    PKCS12_parse(p12, const_cast<char*>(m_keypass.c_str()), &pkey, NULL, NULL);
-                    PKCS12_free(p12);
-                    if (pkey) {
-                        ret=SSL_CTX_use_PrivateKey(ctx, pkey);
-                        EVP_PKEY_free(pkey);
-                    }
+                X509* x=NULL;
+                PKCS12_parse(p12, const_cast<char*>(m_resolver->m_keypass.c_str()), &pkey, &x, NULL);
+                PKCS12_free(p12);
+                if (x)
+                    X509_free(x);
+                if (pkey) {
+                    ret=SSL_CTX_use_PrivateKey(ctx, pkey);
+                    EVP_PKEY_free(pkey);
                 }
             }
-            if (in)
-                BIO_free(in);
         }
+        if (in)
+            BIO_free(in);
     }
 
     if (ret!=1) {
@@ -782,16 +749,16 @@ void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
     }
 
     // Attach certs.
-    for (vector<X509*>::const_iterator i=m_certs.begin(); i!=m_certs.end(); i++) {
-        if (i==m_certs.begin()) {
-            if (SSL_CTX_use_certificate(ctx, *i) != 1) {
+    for (vector<XSECCryptoX509*>::const_iterator i=m_xseccerts.begin(); i!=m_xseccerts.end(); i++) {
+        if (i==m_xseccerts.begin()) {
+            if (SSL_CTX_use_certificate(ctx, static_cast<OpenSSLCryptoX509*>(*i)->getOpenSSLX509()) != 1) {
                 log_openssl();
                 throw XMLSecurityException("Unable to attach client certificate to SSL context.");
             }
         }
         else {
             // When we add certs, they don't get ref counted, so we need to duplicate them.
-            X509* dup = X509_dup(*i);
+            X509* dup = X509_dup(static_cast<OpenSSLCryptoX509*>(*i)->getOpenSSLX509());
             if (SSL_CTX_add_extra_chain_cert(ctx, dup) != 1) {
                 X509_free(dup);
                 log_openssl();
@@ -800,21 +767,3 @@ void FilesystemCredentialResolver::attach(SSL_CTX* ctx) const
         }
     }
 }
-
-void FilesystemCredential::addKeyNames(const DOMElement* e)
-{
-    e = e ? XMLHelper::getFirstChildElement(e, Name) : NULL;
-    while (e) {
-        if (e->hasChildNodes()) {
-            auto_ptr_char n(e->getFirstChild()->getNodeValue());
-            if (n.get() && *n.get())
-                m_keyNames.insert(n.get());
-        }
-        e = XMLHelper::getNextSiblingElement(e, Name);
-    }
-}
-
-void FilesystemCredential::attach(SSL_CTX* ctx) const
-{
-    return m_resolver->attach(ctx);
-}
index 6b71a9a..4dba33f 100644 (file)
@@ -44,6 +44,7 @@
 using namespace xmlsignature;
 using namespace xmltooling::logging;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 namespace xmltooling {
@@ -108,7 +109,7 @@ namespace xmltooling {
     private:
         bool resolveCerts(const KeyInfo* keyInfo);
         bool resolveKey(const KeyInfo* keyInfo);
-        bool resolveCRL(const KeyInfo* keyInfo);
+        bool resolveCRLs(const KeyInfo* keyInfo);
 
         KeyInfoCredentialContext* m_credctx;
     };
@@ -182,7 +183,7 @@ void InlineCredential::resolve(const KeyInfo* keyInfo, int types)
     }
 
     if (types & X509Credential::RESOLVE_CRLS)
-        resolveCRL(keyInfo);
+        resolveCRLs(keyInfo);
 
     const XMLCh* n;
     char* kn;
@@ -319,7 +320,7 @@ bool InlineCredential::resolveCerts(const KeyInfo* keyInfo)
     return !m_xseccerts.empty();
 }
 
-bool InlineCredential::resolveCRL(const KeyInfo* keyInfo)
+bool InlineCredential::resolveCRLs(const KeyInfo* keyInfo)
 {
     Category& log = Category::getInstance(XMLTOOLING_LOGCAT".KeyInfoResolver."INLINE_KEYINFO_RESOLVER);
 
@@ -337,8 +338,7 @@ bool InlineCredential::resolveCRL(const KeyInfo* keyInfo)
                     log.debug("resolving ds:X509CRL");
                     auto_ptr<XSECCryptoX509CRL> crl(XMLToolingConfig::getConfig().X509CRL());
                     crl->loadX509CRLBase64Bin(x.get(), strlen(x.get()));
-                    m_crl = crl.release();
-                    return true;
+                    m_crls.push_back(crl.release());
                 }
             }
             catch(XSECException& e) {
@@ -351,7 +351,8 @@ bool InlineCredential::resolveCRL(const KeyInfo* keyInfo)
         }
     }
 
-    return false;
+    log.debug("resolved %d CRL(s)", m_crls.size());
+    return !m_crls.empty();
 }
 
 void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types)
@@ -392,23 +393,33 @@ void InlineCredential::resolve(DSIGKeyInfoList* keyInfo, int types)
     }
 
     if (types & X509Credential::RESOLVE_CRLS) {
+        DOMNode* x509Node;
+        DOMElement* crlElement;
         for (DSIGKeyInfoList::size_type i=0; i<sz; ++i) {
             if (keyInfo->item(i)->getKeyInfoType()==DSIGKeyInfo::KEYINFO_X509) {
-                auto_ptr_char buf(static_cast<DSIGKeyInfoX509*>(keyInfo->item(i))->getX509CRL());
-                if (buf.get()) {
-                    try {
-                        auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());
-                        crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));
-                        m_crl = crlobj.release();
-                        break;
-                    }
-                    catch(XSECException& e) {
-                        auto_ptr_char temp(e.getMsg());
-                        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", temp.get());
-                    }
-                    catch(XSECCryptoException& e) {
-                        Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", e.getMsg());
+                // The current xmlsec API is limited to one CRL per KeyInfo.
+                // For now, I'm going to process the DOM directly.
+                x509Node = keyInfo->item(i)->getKeyInfoDOMNode();
+                crlElement = x509Node ? XMLHelper::getFirstChildElement(x509Node, xmlconstants::XMLSIG_NS, X509CRL::LOCAL_NAME) : NULL;
+                while (crlElement) {
+                    if (crlElement->hasChildNodes()) {
+                        auto_ptr_char buf(crlElement->getFirstChild()->getNodeValue());
+                        if (buf.get()) {
+                            try {
+                                auto_ptr<XSECCryptoX509CRL> crlobj(XMLToolingConfig::getConfig().X509CRL());
+                                crlobj->loadX509CRLBase64Bin(buf.get(), strlen(buf.get()));
+                                m_crls.push_back(crlobj.release());
+                            }
+                            catch(XSECException& e) {
+                                auto_ptr_char temp(e.getMsg());
+                                Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", temp.get());
+                            }
+                            catch(XSECCryptoException& e) {
+                                Category::getInstance(XMLTOOLING_LOGCAT".KeyResolver."INLINE_KEYINFO_RESOLVER).error("caught XML-Security exception loading CRL: %s", e.getMsg());
+                            }
+                        }
                     }
+                    crlElement = XMLHelper::getNextSiblingElement(crlElement, xmlconstants::XMLSIG_NS, X509CRL::LOCAL_NAME);
                 }
             }
         }
index 6b182f8..8e28538 100644 (file)
@@ -30,7 +30,7 @@ using namespace xmltooling;
 using namespace std;
 
 namespace xmltooling {
-    XMLTOOL_DLLLOCAL PluginManager<KeyInfoResolver,string,const DOMElement*>::Factory InlineKeyInfoResolverFactory;
+    XMLTOOL_DLLLOCAL PluginManager<KeyInfoResolver,string,const xercesc::DOMElement*>::Factory InlineKeyInfoResolverFactory;
 };
 
 void XMLTOOL_API xmltooling::registerKeyInfoResolvers()
diff --git a/xmltooling/security/impl/SecurityHelper.cpp b/xmltooling/security/impl/SecurityHelper.cpp
new file mode 100644 (file)
index 0000000..ebcc37c
--- /dev/null
@@ -0,0 +1,633 @@
+/*
+ *  Copyright 2001-2009 Internet2
+ *
+ * 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.
+ */
+
+/**
+ * SecurityHelper.cpp
+ *
+ * A helper class for working with keys, certificates, etc.
+ */
+
+#include "internal.h"
+#include "logging.h"
+#include "security/OpenSSLCryptoX509CRL.h"
+#include "security/SecurityHelper.h"
+#include "security/X509Credential.h"
+#include "util/NDC.h"
+
+#include <fstream>
+#include <openssl/pem.h>
+#include <openssl/pkcs12.h>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoX509.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyRSA.hpp>
+#include <xsec/enc/OpenSSL/OpenSSLCryptoKeyDSA.hpp>
+
+using namespace xmltooling::logging;
+using namespace xmltooling;
+using namespace std;
+
+// OpenSSL password callback...
+static int passwd_callback(char* buf, int len, int verify, void* passwd)
+{
+    if(!verify)
+    {
+        if(passwd && len > strlen(reinterpret_cast<char*>(passwd)))
+        {
+            strcpy(buf,reinterpret_cast<char*>(passwd));
+            return strlen(buf);
+        }
+    }
+    return 0;
+}
+
+const char* SecurityHelper::guessEncodingFormat(const char* pathname)
+{
+    const char* format=NULL;
+    BIO* in=BIO_new(BIO_s_file_internal());
+    if (in && BIO_read_filename(in, pathname)>0) {
+        const int READSIZE = 1;
+        char buf[READSIZE];
+        int mark;
+
+        // Examine the first byte.
+        try {
+            if ((mark = BIO_tell(in)) < 0)
+                throw XMLSecurityException("Error loading file: BIO_tell() can't get the file position.");
+            if (BIO_read(in, buf, READSIZE) <= 0)
+                throw XMLSecurityException("Error loading file: BIO_read() can't read from the stream.");
+            if (BIO_seek(in, mark) < 0)
+                throw XMLSecurityException("Error loading file: BIO_seek() can't reset the file position.");
+        }
+        catch (exception&) {
+            log_openssl();
+            BIO_free(in);
+            throw;
+        }
+
+        // Check the first byte of the file.  If it's some kind of DER-encoded structure
+        // (including PKCS12), it will begin with ASCII 048. Otherwise, assume it's PEM.
+        if (buf[0] != 48) {
+            format = "PEM";
+        }
+        else {
+            // Here we know it's DER-encoded, now try to parse it as a PKCS12 ASN.1 structure.
+            // If it fails, must be another kind of DER-encoded structure.
+            PKCS12* p12;
+            if ((p12=d2i_PKCS12_bio(in, NULL)) == NULL) {
+                format = "DER";
+            }
+            else {
+                format = "PKCS12";
+                PKCS12_free(p12);
+            }
+        }
+    }
+    if (in)
+        BIO_free(in);
+    if (format)
+        return format;
+    throw XMLSecurityException("Unable to determine encoding for file ($1).", params(1,pathname));
+}
+
+XSECCryptoKey* SecurityHelper::loadKeyFromFile(const char* pathname, const char* format, const char* password)
+{
+#ifdef _DEBUG
+    NDC ndc("loadKeyFromFile");
+#endif
+    Category& log = Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper");
+    log.info("loading private key from file (%s)", pathname);
+
+    // Native objects.
+    PKCS12* p12=NULL;
+    EVP_PKEY* pkey=NULL;
+
+    BIO* in=BIO_new(BIO_s_file_internal());
+    if (in && BIO_read_filename(in, pathname)>0) {
+        // If the format isn't set, try and guess it.
+        if (!format || !*format) {
+            const int READSIZE = 1;
+            char buf[READSIZE];
+            int mark;
+
+            // Examine the first byte.
+            try {
+                if ((mark = BIO_tell(in)) < 0)
+                    throw XMLSecurityException("Error loading key: BIO_tell() can't get the file position.");
+                if (BIO_read(in, buf, READSIZE) <= 0)
+                    throw XMLSecurityException("Error loading key: BIO_read() can't read from the stream.");
+                if (BIO_seek(in, mark) < 0)
+                    throw XMLSecurityException("Error loading key: BIO_seek() can't reset the file position.");
+            }
+            catch (exception&) {
+                log_openssl();
+                BIO_free(in);
+                throw;
+            }
+
+            // Check the first byte of the file.  If it's some kind of DER-encoded structure
+            // (including PKCS12), it will begin with ASCII 048. Otherwise, assume it's PEM.
+            if (buf[0] != 48) {
+                format = "PEM";
+            }
+            else {
+                // Here we know it's DER-encoded, now try to parse it as a PKCS12 ASN.1 structure.
+                // If it fails, must be another kind of DER-encoded structure.
+                if ((p12=d2i_PKCS12_bio(in, NULL)) == NULL) {
+                    format = "DER";
+                    if (BIO_seek(in, mark) < 0) {
+                        log_openssl();
+                        BIO_free(in);
+                        throw XMLSecurityException("Error loading key: BIO_seek() can't reset the file position.");
+                    }
+                }
+                else {
+                    format = "PKCS12";
+                }
+            }
+            log.debug("key encoding format for (%s) dynamically resolved as (%s)", pathname, format);
+        }
+
+        // The format should be known, so parse accordingly.
+        if (!strcmp(format, "PEM")) {
+            pkey = PEM_read_bio_PrivateKey(in, NULL, passwd_callback, const_cast<char*>(password));
+        }
+        else if (!strcmp(format, "DER")) {
+            pkey=d2i_PrivateKey_bio(in, NULL);
+        }
+        else if (!strcmp(format, "PKCS12")) {
+            if (!p12)
+                p12 = d2i_PKCS12_bio(in, NULL);
+            if (p12) {
+                X509* x=NULL;
+                PKCS12_parse(p12, const_cast<char*>(password), &pkey, &x, NULL);
+                PKCS12_free(p12);
+                X509_free(x);
+            }
+        }
+        else {
+            log.error("unknown key encoding format (%s)", format);
+        }
+    }
+    if (in)
+        BIO_free(in);
+
+    // Now map it to an XSEC wrapper.
+    if (pkey) {
+        XSECCryptoKey* ret=NULL;
+        switch (pkey->type) {
+            case EVP_PKEY_RSA:
+                ret=new OpenSSLCryptoKeyRSA(pkey);
+                break;
+
+            case EVP_PKEY_DSA:
+                ret=new OpenSSLCryptoKeyDSA(pkey);
+                break;
+
+            default:
+                log.error("unsupported private key type");
+        }
+        EVP_PKEY_free(pkey);
+        if (ret)
+            return ret;
+    }
+
+    log_openssl();
+    throw XMLSecurityException("Unable to load private key from file ($1).", params(1, pathname));
+}
+
+vector<XSECCryptoX509*>::size_type SecurityHelper::loadCertificatesFromFile(
+    vector<XSECCryptoX509*>& certs, const char* pathname, const char* format, const char* password
+    )
+{
+#ifdef _DEBUG
+    NDC ndc("loadCertificatesFromFile");
+#endif
+    Category& log = Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper");
+    log.info("loading certificate(s) from file (%s)", pathname);
+
+    vector<XSECCryptoX509*>::size_type count = certs.size();
+
+    // Native objects.
+    X509* x=NULL;
+    PKCS12* p12=NULL;
+
+    BIO* in=BIO_new(BIO_s_file_internal());
+    if (in && BIO_read_filename(in, pathname)>0) {
+        // If the format isn't set, try and guess it.
+        if (!format || !*format) {
+            const int READSIZE = 1;
+            char buf[READSIZE];
+            int mark;
+
+            // Examine the first byte.
+            try {
+                if ((mark = BIO_tell(in)) < 0)
+                    throw XMLSecurityException("Error loading certificate: BIO_tell() can't get the file position.");
+                if (BIO_read(in, buf, READSIZE) <= 0)
+                    throw XMLSecurityException("Error loading certificate: BIO_read() can't read from the stream.");
+                if (BIO_seek(in, mark) < 0)
+                    throw XMLSecurityException("Error loading certificate: BIO_seek() can't reset the file position.");
+            }
+            catch (exception&) {
+                log_openssl();
+                BIO_free(in);
+                throw;
+            }
+
+            // Check the first byte of the file.  If it's some kind of DER-encoded structure
+            // (including PKCS12), it will begin with ASCII 048. Otherwise, assume it's PEM.
+            if (buf[0] != 48) {
+                format = "PEM";
+            }
+            else {
+                // Here we know it's DER-encoded, now try to parse it as a PKCS12 ASN.1 structure.
+                // If it fails, must be another kind of DER-encoded structure.
+                if ((p12=d2i_PKCS12_bio(in, NULL)) == NULL) {
+                    format = "DER";
+                    if (BIO_seek(in, mark) < 0) {
+                        log_openssl();
+                        BIO_free(in);
+                        throw XMLSecurityException("Error loading certificate: BIO_seek() can't reset the file position.");
+                    }
+                }
+                else {
+                    format = "PKCS12";
+                }
+            }
+        }
+
+        // The format should be known, so parse accordingly.
+        if (!strcmp(format, "PEM")) {
+            while (x=PEM_read_bio_X509(in, NULL, NULL, NULL)) {
+                certs.push_back(new OpenSSLCryptoX509(x));
+                X509_free(x);
+            }
+        }
+        else if (!strcmp(format, "DER")) {
+            x=d2i_X509_bio(in, NULL);
+            if (x) {
+                certs.push_back(new OpenSSLCryptoX509(x));
+                X509_free(x);
+            }
+        }
+        else if (!strcmp(format, "PKCS12")) {
+            if (!p12)
+                p12 = d2i_PKCS12_bio(in, NULL);
+            if (p12) {
+                EVP_PKEY* pkey=NULL;
+                STACK_OF(X509)* CAstack = sk_X509_new_null();
+                PKCS12_parse(p12, const_cast<char*>(password), &pkey, &x, &CAstack);
+                PKCS12_free(p12);
+                EVP_PKEY_free(pkey);
+                if (x) {
+                    certs.push_back(new OpenSSLCryptoX509(x));
+                    X509_free(x);
+                }
+                x = sk_X509_pop(CAstack);
+                while (x) {
+                    certs.push_back(new OpenSSLCryptoX509(x));
+                    X509_free(x);
+                    x = sk_X509_pop(CAstack);
+                }
+                sk_X509_free(CAstack);
+            }
+        }
+    }
+    if (in)
+        BIO_free(in);
+
+    if (certs.size() == count) {
+        log_openssl();
+        throw XMLSecurityException("Unable to load certificate(s) from file ($1).", params(1, pathname));
+    }
+
+    return certs.size();
+}
+
+vector<XSECCryptoX509CRL*>::size_type SecurityHelper::loadCRLsFromFile(
+    vector<XSECCryptoX509CRL*>& crls, const char* pathname, const char* format
+    )
+{
+#ifdef _DEBUG
+    NDC ndc("loadCRLsFromFile");
+#endif
+    Category& log = Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper");
+    log.info("loading CRL(s) from file (%s)", pathname);
+
+    vector<XSECCryptoX509CRL*>::size_type count = crls.size();
+
+    BIO* in=BIO_new(BIO_s_file_internal());
+    if (in && BIO_read_filename(in, pathname)>0) {
+        // If the format isn't set, try and guess it.
+        if (!format || !*format) {
+            const int READSIZE = 1;
+            char buf[READSIZE];
+            int mark;
+
+            // Examine the first byte.
+            try {
+                if ((mark = BIO_tell(in)) < 0)
+                    throw XMLSecurityException("Error loading CRL: BIO_tell() can't get the file position.");
+                if (BIO_read(in, buf, READSIZE) <= 0)
+                    throw XMLSecurityException("Error loading CRL: BIO_read() can't read from the stream.");
+                if (BIO_seek(in, mark) < 0)
+                    throw XMLSecurityException("Error loading CRL: BIO_seek() can't reset the file position.");
+            }
+            catch (exception&) {
+                log_openssl();
+                BIO_free(in);
+                throw;
+            }
+
+            // Check the first byte of the file.  If it's some kind of DER-encoded structure
+            // it will begin with ASCII 048. Otherwise, assume it's PEM.
+            if (buf[0] != 48) {
+                format = "PEM";
+            }
+            else {
+                format = "DER";
+            }
+            log.debug("CRL encoding format for (%s) dynamically resolved as (%s)", pathname, format);
+        }
+
+        X509_CRL* crl=NULL;
+        if (!strcmp(format, "PEM")) {
+            while (crl=PEM_read_bio_X509_CRL(in, NULL, NULL, NULL)) {
+                crls.push_back(new OpenSSLCryptoX509CRL(crl));
+                X509_CRL_free(crl);
+            }
+        }
+        else if (!strcmp(format, "DER")) {
+            crl=d2i_X509_CRL_bio(in, NULL);
+            if (crl) {
+                crls.push_back(new OpenSSLCryptoX509CRL(crl));
+                X509_CRL_free(crl);
+            }
+        }
+        else {
+            log.error("unknown CRL encoding format (%s)", format);
+        }
+    }
+    if (in)
+        BIO_free(in);
+
+    if (crls.size() == count) {
+        log_openssl();
+        throw XMLSecurityException("Unable to load CRL(s) from file ($1).", params(1, pathname));
+    }
+
+    return crls.size();
+}
+
+XSECCryptoKey* SecurityHelper::loadKeyFromURL(SOAPTransport& transport, const char* backing, const char* format, const char* password)
+{
+    // Fetch the data.
+    transport.send();
+    istream& msg = transport.receive();
+
+    // Dump to output file.
+    ofstream out(backing, fstream::trunc|fstream::binary);
+    out << msg.rdbuf();
+    out.close();
+
+    return loadKeyFromFile(backing, format, password);
+}
+
+vector<XSECCryptoX509*>::size_type SecurityHelper::loadCertificatesFromURL(
+    vector<XSECCryptoX509*>& certs, SOAPTransport& transport, const char* backing, const char* format, const char* password
+    )
+{
+    transport.send();
+    istream& msg = transport.receive();
+
+    // Dump to output file.
+    ofstream out(backing, fstream::trunc|fstream::binary);
+    out << msg.rdbuf();
+    out.close();
+
+    return loadCertificatesFromFile(certs, backing, format, password);
+}
+
+vector<XSECCryptoX509CRL*>::size_type SecurityHelper::loadCRLsFromURL(
+    vector<XSECCryptoX509CRL*>& crls, SOAPTransport& transport, const char* backing, const char* format
+    )
+{
+    // Fetch the data.
+    transport.send();
+    istream& msg = transport.receive();
+
+    // Dump to output file.
+    ofstream out(backing, fstream::trunc|fstream::binary);
+    out << msg.rdbuf();
+    out.close();
+
+    return loadCRLsFromFile(crls, backing, format);
+}
+
+bool SecurityHelper::matches(const XSECCryptoKey& key1, const XSECCryptoKey& key2)
+{
+    if (key1.getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL ||
+        key2.getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+        Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("comparison of non-OpenSSL keys not supported");
+        return false;
+    }
+
+    // If one key is public or both, just compare the public key half.
+    if (key1.getKeyType()==XSECCryptoKey::KEY_RSA_PUBLIC || key1.getKeyType()==XSECCryptoKey::KEY_RSA_PAIR) {
+        if (key2.getKeyType()!=XSECCryptoKey::KEY_RSA_PUBLIC && key2.getKeyType()!=XSECCryptoKey::KEY_RSA_PAIR)
+            return false;
+        const RSA* rsa1 = static_cast<const OpenSSLCryptoKeyRSA&>(key1).getOpenSSLRSA();
+        const RSA* rsa2 = static_cast<const OpenSSLCryptoKeyRSA&>(key2).getOpenSSLRSA();
+        return (rsa1 && rsa2 && BN_cmp(rsa1->n,rsa2->n) == 0 && BN_cmp(rsa1->e,rsa2->e) == 0);
+    }
+
+    // For a private key, compare the private half.
+    if (key1.getKeyType()==XSECCryptoKey::KEY_RSA_PRIVATE) {
+        if (key2.getKeyType()!=XSECCryptoKey::KEY_RSA_PRIVATE && key2.getKeyType()!=XSECCryptoKey::KEY_RSA_PAIR)
+            return false;
+        const RSA* rsa1 = static_cast<const OpenSSLCryptoKeyRSA&>(key1).getOpenSSLRSA();
+        const RSA* rsa2 = static_cast<const OpenSSLCryptoKeyRSA&>(key2).getOpenSSLRSA();
+        return (rsa1 && rsa2 && BN_cmp(rsa1->n,rsa2->n) == 0 && BN_cmp(rsa1->d,rsa2->d) == 0);
+    }
+
+    // If one key is public or both, just compare the public key half.
+    if (key1.getKeyType()==XSECCryptoKey::KEY_DSA_PUBLIC || key1.getKeyType()==XSECCryptoKey::KEY_DSA_PAIR) {
+        if (key2.getKeyType()!=XSECCryptoKey::KEY_DSA_PUBLIC && key2.getKeyType()!=XSECCryptoKey::KEY_DSA_PAIR)
+            return false;
+        const DSA* dsa1 = static_cast<const OpenSSLCryptoKeyDSA&>(key1).getOpenSSLDSA();
+        const DSA* dsa2 = static_cast<const OpenSSLCryptoKeyDSA&>(key2).getOpenSSLDSA();
+        return (dsa1 && dsa2 && BN_cmp(dsa1->pub_key,dsa2->pub_key) == 0);
+    }
+
+    // For a private key, compare the private half.
+    if (key1.getKeyType()==XSECCryptoKey::KEY_DSA_PRIVATE) {
+        if (key2.getKeyType()!=XSECCryptoKey::KEY_DSA_PRIVATE && key2.getKeyType()!=XSECCryptoKey::KEY_DSA_PAIR)
+            return false;
+        const DSA* dsa1 = static_cast<const OpenSSLCryptoKeyDSA&>(key1).getOpenSSLDSA();
+        const DSA* dsa2 = static_cast<const OpenSSLCryptoKeyDSA&>(key2).getOpenSSLDSA();
+        return (dsa1 && dsa2 && BN_cmp(dsa1->priv_key,dsa2->priv_key) == 0);
+    }
+
+    Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("unsupported key type for comparison");
+    return false;
+}
+
+string SecurityHelper::getDEREncoding(const XSECCryptoKey& key, bool hash, bool nowrap)
+{
+    string ret;
+
+    if (key.getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+        Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("encoding of non-OpenSSL keys not supported");
+        return ret;
+    }
+
+    if (key.getKeyType() == XSECCryptoKey::KEY_RSA_PUBLIC || key.getKeyType() == XSECCryptoKey::KEY_RSA_PAIR) {
+        const RSA* rsa = static_cast<const OpenSSLCryptoKeyRSA&>(key).getOpenSSLRSA();
+        if (!rsa) {
+            Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("key was not populated");
+            return ret;
+        }
+        BIO* chain = BIO_new(BIO_s_mem());
+        BIO* b = BIO_new(BIO_f_base64());
+        if (nowrap)
+            BIO_set_flags(b, BIO_FLAGS_BASE64_NO_NL);
+        chain = BIO_push(b, chain);
+        if (hash) {
+            b = BIO_new(BIO_f_md());
+            BIO_set_md(b, EVP_sha1());
+            chain = BIO_push(b, chain);
+        }
+        i2d_RSA_PUBKEY_bio(chain, const_cast<RSA*>(rsa));
+        BIO_flush(chain);
+        if (hash) {
+            char digest[20];
+            int len = BIO_gets(chain, digest, sizeof(digest));
+            if (len != sizeof(digest)) {
+                BIO_free_all(chain);
+                return ret;
+            }
+            b = BIO_pop(chain);
+            BIO_free(chain);
+            chain = b;
+            BIO_reset(chain);
+            BIO_write(chain, digest, len);
+            BIO_flush(chain);
+        }
+        BUF_MEM* bptr=NULL;
+        BIO_get_mem_ptr(chain, &bptr);
+        if (bptr && bptr->length > 0)
+            ret.append(bptr->data, bptr->length);
+        BIO_free_all(chain);
+    }
+    else if (key.getKeyType() == XSECCryptoKey::KEY_DSA_PUBLIC || key.getKeyType() == XSECCryptoKey::KEY_DSA_PAIR) {
+        const DSA* dsa = static_cast<const OpenSSLCryptoKeyDSA&>(key).getOpenSSLDSA();
+        if (!dsa) {
+            Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("key was not populated");
+            return ret;
+        }
+        BIO* chain = BIO_new(BIO_s_mem());
+        BIO* b = BIO_new(BIO_f_base64());
+        if (nowrap)
+            BIO_set_flags(b, BIO_FLAGS_BASE64_NO_NL);
+        chain = BIO_push(b, chain);
+        if (hash) {
+            b = BIO_new(BIO_f_md());
+            BIO_set_md(b, EVP_sha1());
+            chain = BIO_push(b, chain);
+        }
+        i2d_DSA_PUBKEY_bio(chain, const_cast<DSA*>(dsa));
+        BIO_flush(chain);
+        if (hash) {
+            char digest[20];
+            int len = BIO_gets(chain, digest, sizeof(digest));
+            if (len != sizeof(digest)) {
+                BIO_free_all(chain);
+                return ret;
+            }
+            b = BIO_pop(chain);
+            BIO_free(chain);
+            chain = b;
+            BIO_reset(chain);
+            BIO_write(chain, digest, len);
+            BIO_flush(chain);
+        }
+        BUF_MEM* bptr=NULL;
+        BIO_get_mem_ptr(chain, &bptr);
+        if (bptr && bptr->length > 0)
+            ret.append(bptr->data, bptr->length);
+        BIO_free_all(chain);
+    }
+    else {
+        Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("encoding of non-RSA/DSA public keys not supported");
+    }
+    return ret;
+}
+
+string SecurityHelper::getDEREncoding(const XSECCryptoX509& cert, bool hash, bool nowrap)
+{
+    string ret;
+
+    if (cert.getProviderName()!=DSIGConstants::s_unicodeStrPROVOpenSSL) {
+        Category::getInstance(XMLTOOLING_LOGCAT".SecurityHelper").warn("encoding of non-OpenSSL keys not supported");
+        return ret;
+    }
+
+    const X509* x = static_cast<const OpenSSLCryptoX509&>(cert).getOpenSSLX509();
+    EVP_PKEY* key = X509_get_pubkey(const_cast<X509*>(x));
+
+    BIO* chain = BIO_new(BIO_s_mem());
+    BIO* b = BIO_new(BIO_f_base64());
+    if (nowrap)
+        BIO_set_flags(b, BIO_FLAGS_BASE64_NO_NL);
+    chain = BIO_push(b, chain);
+    if (hash) {
+        b = BIO_new(BIO_f_md());
+        BIO_set_md(b, EVP_sha1());
+        chain = BIO_push(b, chain);
+    }
+    i2d_PUBKEY_bio(chain, key);
+    EVP_PKEY_free(key);
+    BIO_flush(chain);
+    if (hash) {
+        char digest[20];
+        int len = BIO_gets(chain, digest, sizeof(digest));
+        if (len != sizeof(digest)) {
+            BIO_free_all(chain);
+            return ret;
+        }
+        b = BIO_pop(chain);
+        BIO_free(chain);
+        chain = b;
+        BIO_reset(chain);
+        BIO_write(chain, digest, len);
+        BIO_flush(chain);
+    }
+    BUF_MEM* bptr=NULL;
+    BIO_get_mem_ptr(chain, &bptr);
+    if (bptr && bptr->length > 0)
+        ret.append(bptr->data, bptr->length);
+    BIO_free_all(chain);
+    return ret;
+}
+
+string SecurityHelper::getDEREncoding(const Credential& cred, bool hash, bool nowrap)
+{
+    const X509Credential* x509 = dynamic_cast<const X509Credential*>(&cred);
+    if (x509 && !x509->getEntityCertificateChain().empty())
+        return getDEREncoding(*(x509->getEntityCertificateChain().front()), hash, nowrap);
+    else if (cred.getPublicKey())
+        return getDEREncoding(*(cred.getPublicKey()), hash, nowrap);
+    return "";
+}
index 8df6c68..f2432bd 100644 (file)
@@ -38,23 +38,20 @@ using namespace std;
 
 namespace xmltooling {
 
-    static const XMLCh _CredentialResolver[] =  UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);\r
-    static const XMLCh type[] =                 UNICODE_LITERAL_4(t,y,p,e);\r
-    static const XMLCh certificate[] =          UNICODE_LITERAL_11(c,e,r,t,i,f,i,c,a,t,e);\r
-    static const XMLCh Certificate[] =          UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);\r
-    static const XMLCh Path[] =                 UNICODE_LITERAL_4(P,a,t,h);\r
+    static const XMLCh _CredentialResolver[] =  UNICODE_LITERAL_18(C,r,e,d,e,n,t,i,a,l,R,e,s,o,l,v,e,r);
+    static const XMLCh type[] =                 UNICODE_LITERAL_4(t,y,p,e);
+    static const XMLCh certificate[] =          UNICODE_LITERAL_11(c,e,r,t,i,f,i,c,a,t,e);
+    static const XMLCh Certificate[] =          UNICODE_LITERAL_11(C,e,r,t,i,f,i,c,a,t,e);
+    static const XMLCh Path[] =                 UNICODE_LITERAL_4(P,a,t,h);
     static const XMLCh verifyDepth[] =          UNICODE_LITERAL_11(v,e,r,i,f,y,D,e,p,t,h);
-\r
+
     class XMLTOOL_DLLLOCAL StaticPKIXTrustEngine : public AbstractPKIXTrustEngine
     {
     public:
         StaticPKIXTrustEngine(const DOMElement* e=NULL);
 
         virtual ~StaticPKIXTrustEngine() {
-            if (m_credResolver) {
-                m_credResolver->unlock();
-                delete m_credResolver;
-            }
+            delete m_credResolver;
         }
         
         AbstractPKIXTrustEngine::PKIXValidationInfoIterator* getPKIXValidationInfoIterator(
@@ -66,10 +63,8 @@ namespace xmltooling {
         }
 
     private:
-        CredentialResolver* m_credResolver;
         int m_depth;
-        vector<XSECCryptoX509*> m_certs;
-        vector<XSECCryptoX509CRL*> m_crls;
+        CredentialResolver* m_credResolver;
         friend class XMLTOOL_DLLLOCAL StaticPKIXIterator;
     };
     
@@ -82,9 +77,26 @@ namespace xmltooling {
     {
     public:
         StaticPKIXIterator(const StaticPKIXTrustEngine& engine) : m_engine(engine), m_done(false) {
+            // Merge together all X509Credentials we can resolve.
+            m_engine.m_credResolver->lock();
+            try {
+                vector<const Credential*> creds;
+                m_engine.m_credResolver->resolve(creds);
+                for (vector<const Credential*>::const_iterator i = creds.begin(); i != creds.end(); ++i) {
+                    const X509Credential* xcred = dynamic_cast<const X509Credential*>(*i);
+                    if (xcred) {
+                        m_certs.insert(m_certs.end(), xcred->getEntityCertificateChain().begin(), xcred->getEntityCertificateChain().end());
+                        m_crls.insert(m_crls.end(), xcred->getCRLs().begin(), xcred->getCRLs().end());
+                    }
+                }
+            }
+            catch (exception& ex) {
+                logging::Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine.StaticPKIX").error(ex.what());
+            }
         }
 
         virtual ~StaticPKIXIterator() {
+            m_engine.m_credResolver->unlock();
         }
 
         bool next() {
@@ -99,58 +111,39 @@ namespace xmltooling {
         }
         
         const vector<XSECCryptoX509*>& getTrustAnchors() const {
-            return m_engine.m_certs;
+            return m_certs;
         }
 
         const vector<XSECCryptoX509CRL*>& getCRLs() const {
-            return m_engine.m_crls;
+            return m_crls;
         }
     
     private:
         const StaticPKIXTrustEngine& m_engine;
+        vector<XSECCryptoX509*> m_certs;
+        vector<XSECCryptoX509CRL*> m_crls;
         bool m_done;
     };
 };
 
-StaticPKIXTrustEngine::StaticPKIXTrustEngine(const DOMElement* e) : AbstractPKIXTrustEngine(e)
+StaticPKIXTrustEngine::StaticPKIXTrustEngine(const DOMElement* e) : AbstractPKIXTrustEngine(e), m_depth(1), m_credResolver(NULL)
 {
     const XMLCh* depth = e ? e->getAttributeNS(NULL, verifyDepth) : NULL;
     if (depth && *depth)
         m_depth = XMLString::parseInt(depth);
-    else
-        m_depth = 1;
-
-    if (e && e->hasAttributeNS(NULL,certificate)) {\r
-        // Simple File resolver config rooted here.\r
-        m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(FILESYSTEM_CREDENTIAL_RESOLVER,e);\r
-    }\r
-    else {\r
-        e = e ? XMLHelper::getFirstChildElement(e, _CredentialResolver) : NULL;\r
-        auto_ptr_char t(e ? e->getAttributeNS(NULL,type) : NULL);\r
-        if (t.get()) {\r
-            m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(t.get(),e);\r
-        }\r
-        else\r
-            throw XMLSecurityException("Missing <CredentialResolver> element, or no type attribute found");\r
-    }\r
-\r
-    m_credResolver->lock();\r
-
-    // Merge together all X509Credentials we can resolve.
-    try {
-        vector<const Credential*> creds;
-        m_credResolver->resolve(creds);
-        for (vector<const Credential*>::const_iterator i = creds.begin(); i != creds.end(); ++i) {
-            const X509Credential* xcred = dynamic_cast<const X509Credential*>(*i);
-            if (xcred) {
-                m_certs.insert(m_certs.end(), xcred->getEntityCertificateChain().begin(), xcred->getEntityCertificateChain().end());
-                if (xcred->getCRL())
-                    m_crls.push_back(xcred->getCRL());
-            }
-        }
+
+    if (e && e->hasAttributeNS(NULL,certificate)) {
+        // Simple File resolver config rooted here.
+        m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(FILESYSTEM_CREDENTIAL_RESOLVER,e);
     }
-    catch (exception& ex) {
-        logging::Category::getInstance(XMLTOOLING_LOGCAT".TrustEngine.StaticPKIX").error(ex.what());
+    else {
+        e = e ? XMLHelper::getFirstChildElement(e, _CredentialResolver) : NULL;
+        auto_ptr_char t(e ? e->getAttributeNS(NULL,type) : NULL);
+        if (t.get()) {
+            m_credResolver = XMLToolingConfig::getConfig().CredentialResolverManager.newPlugin(t.get(),e);
+        }
+        else
+            throw XMLSecurityException("Missing <CredentialResolver> element, or no type attribute found");
     }
 }
 
index 0052b13..1c67741 100644 (file)
@@ -30,6 +30,8 @@
 using namespace xmltooling;
 using namespace std;
 
+using xercesc::DOMElement;
+
 namespace xmltooling {
     XMLTOOL_DLLLOCAL PluginManager<TrustEngine,string,const DOMElement*>::Factory ExplicitKeyTrustEngineFactory;
     XMLTOOL_DLLLOCAL PluginManager<TrustEngine,string,const DOMElement*>::Factory StaticPKIXTrustEngineFactory;
index 1f59137..9505365 100644 (file)
@@ -33,6 +33,7 @@
 
 using namespace xmlsignature;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 using xmlconstants::XMLSIG_NS;
 
@@ -52,7 +53,7 @@ namespace xmlsignature {
     public:
         virtual ~DSAKeyValueImpl() {}
 
-        DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        DSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -137,7 +138,7 @@ namespace xmlsignature {
     public:
         virtual ~RSAKeyValueImpl() {}
 
-        RSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        RSAKeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -182,7 +183,7 @@ namespace xmlsignature {
     public:
         virtual ~KeyValueImpl() {}
 
-        KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        KeyValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -244,7 +245,7 @@ namespace xmlsignature {
             XMLString::release(&m_Algorithm);
         }
 
-        TransformImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        TransformImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Algorithm(NULL) {
         }
             
@@ -301,7 +302,7 @@ namespace xmlsignature {
     public:
         virtual ~TransformsImpl() {}
 
-        TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        TransformsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -337,7 +338,7 @@ namespace xmlsignature {
             XMLString::release(&m_Type);
         }
 
-        RetrievalMethodImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        RetrievalMethodImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -390,7 +391,7 @@ namespace xmlsignature {
     public:
         virtual ~X509IssuerSerialImpl() {}
 
-        X509IssuerSerialImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        X509IssuerSerialImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -435,7 +436,7 @@ namespace xmlsignature {
     public:
         virtual ~X509DataImpl() {}
 
-        X509DataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        X509DataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -514,7 +515,7 @@ namespace xmlsignature {
     public:
         virtual ~SPKIDataImpl() {}
 
-        SPKIDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        SPKIDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -578,7 +579,7 @@ namespace xmlsignature {
     public:
         virtual ~PGPDataImpl() {}
 
-        PGPDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        PGPDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -637,7 +638,7 @@ namespace xmlsignature {
             XMLString::release(&m_Id);
         }
 
-        KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {
         }
             
index da8eb1a..f3072c6 100644 (file)
@@ -47,6 +47,7 @@
 using namespace xmlsignature;
 using namespace xmltooling::logging;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 using xmlconstants::XMLSIG_NS;
 using xmlconstants::XMLSIG_PREFIX;
@@ -432,7 +433,7 @@ Signature*
 XMLObject*
 #endif
 SignatureBuilder::buildObject(
-    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType
+    const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType
     ) const
 {
     if (!XMLString::equals(nsURI,XMLSIG_NS) || !XMLString::equals(localName,Signature::LOCAL_NAME))
index ff2de77..641040d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2008 Internet2
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -75,7 +75,8 @@ namespace soap11 {
     END_XMLOBJECT;
 
     BEGIN_XMLOBJECT(XMLTOOL_API,Body,xmltooling::ElementProxy,SOAP 1.1 Body element);
-        DECL_STRING_ATTRIB(EncodingStyle,ENCODINGSTYLE);
+        /** encodingStyle attribute name */
+        static const XMLCh ENCODINGSTYLE_ATTRIB_NAME[];
         /** Body (type) local name */
         static const XMLCh TYPE_NAME[];
     END_XMLOBJECT;
index ec6ed9c..b2e7ef3 100644 (file)
@@ -182,6 +182,17 @@ namespace xmltooling {
         virtual void send(std::istream& in)=0;
 
         /**
+         * Sends an optional stream of data over the transport. The function may return without
+         * having received any data, depending on the nature of the transport.
+         *
+         * <p>If the parameter is omitted, a request may be issued with no body if the transport
+         * supports that feature.
+         *
+         * @param in    input stream to send
+         */
+        virtual void send(std::istream* in=NULL);
+
+        /**
          * Returns reference to response stream.  The resulting stream must be
          * checked directly to determine whether data is available.
          *
index 0aca880..0bd3715 100644 (file)
@@ -166,7 +166,11 @@ namespace xmltooling {
 #endif
         }
 
-        void send(istream& in);
+        void send(istream& in) {
+            send(&in);
+        }
+
+        void send(istream* in=NULL);
 
         istream& receive() {
             return m_stream;
@@ -304,10 +308,10 @@ CURL* CURLPool::get(const SOAPTransport::Address& addr)
     curl_easy_setopt(handle,CURLOPT_NOPROGRESS,1);
     curl_easy_setopt(handle,CURLOPT_NOSIGNAL,1);
     curl_easy_setopt(handle,CURLOPT_FAILONERROR,1);
-    curl_easy_setopt(handle,CURLOPT_SSLVERSION,CURL_SSLVERSION_SSLv3);
     curl_easy_setopt(handle,CURLOPT_SSL_CIPHER_LIST,"ALL:!aNULL:!LOW:!EXPORT:!SSLv2");
     // Verification of the peer is via TrustEngine only.
     curl_easy_setopt(handle,CURLOPT_SSL_VERIFYPEER,0);
+    curl_easy_setopt(handle,CURLOPT_CAINFO,NULL);
     curl_easy_setopt(handle,CURLOPT_HEADERFUNCTION,&curl_header_hook);
     curl_easy_setopt(handle,CURLOPT_WRITEFUNCTION,&curl_write_hook);
     curl_easy_setopt(handle,CURLOPT_DEBUGFUNCTION,&curl_debug_hook);
@@ -404,7 +408,7 @@ string CURLSOAPTransport::getContentType() const
     return content_type ? content_type : "";
 }
 
-void CURLSOAPTransport::send(istream& in)
+void CURLSOAPTransport::send(istream* in)
 {
 #ifdef _DEBUG
     xmltooling::NDC ndc("send");
@@ -428,13 +432,13 @@ void CURLSOAPTransport::send(istream& in)
         curl_easy_setopt(m_handle,CURLOPT_POST,1);
         m_headers=curl_slist_append(m_headers,"Transfer-Encoding: chunked");
         curl_easy_setopt(m_handle,CURLOPT_READFUNCTION,&curl_read_hook);
-        curl_easy_setopt(m_handle,CURLOPT_READDATA,&in);
+        curl_easy_setopt(m_handle,CURLOPT_READDATA,in);
     }
     else if (in) {
         char buf[1024];
-        while (in) {
-            in.read(buf,1024);
-            msg.append(buf,in.gcount());
+        while (*in) {
+            in->read(buf,1024);
+            msg.append(buf,in->gcount());
         }
         curl_easy_setopt(m_handle,CURLOPT_POST,1);
         curl_easy_setopt(m_handle,CURLOPT_READFUNCTION,NULL);
@@ -478,7 +482,7 @@ void CURLSOAPTransport::send(istream& in)
     log.debug("sending SOAP message to %s", m_endpoint.c_str());
     if (curl_easy_perform(m_handle) != CURLE_OK) {
         throw IOException(
-            string("CURLSOAPTransport failed while contacting SOAP responder: ") +
+            string("CURLSOAPTransport failed while contacting SOAP endpoint (") + m_endpoint + "): " +
                 (curl_errorbuf[0] ? curl_errorbuf : "no further information available"));
     }
 }
@@ -513,10 +517,10 @@ size_t xmltooling::curl_header_hook(void* ptr, size_t size, size_t nmemb, void*
 // callback to send data to server
 size_t xmltooling::curl_read_hook(void* ptr, size_t size, size_t nmemb, void* stream)
 {
-    // *stream is actually an istream object
-    istream& buf=*(reinterpret_cast<istream*>(stream));
-    buf.read(reinterpret_cast<char*>(ptr),size*nmemb);
-    return buf.gcount();
+    // stream is actually an istream pointer
+    istream* buf=reinterpret_cast<istream*>(stream);
+    buf->read(reinterpret_cast<char*>(ptr),size*nmemb);
+    return buf->gcount();
 }
 
 // callback to buffer data from server
@@ -589,6 +593,15 @@ CURLcode xmltooling::xml_ssl_ctx_callback(CURL* curl, SSL_CTX* ssl_ctx, void* us
 {
     CURLSOAPTransport* conf = reinterpret_cast<CURLSOAPTransport*>(userptr);
 
+    // Manually disable SSLv2 so we're not dependent on libcurl to do it.
+    // Also disable the ticket option where implemented, since this breaks a variety
+    // of servers. Newer libcurl also does this for us.
+#ifdef SSL_OP_NO_TICKET
+    SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET);
+#else
+    SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2);
+#endif
+
 #ifndef XMLTOOLING_NO_XMLSEC
     if (conf->m_cred)
         conf->m_cred->attach(ssl_ctx);
index e89742b..9082d41 100644 (file)
 using namespace soap11;
 using namespace xmltooling::logging;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
+void SOAPTransport::send(istream* in)
+{
+    if (!in)
+        throw IOException("SOAP transport does not support an empty request body.");
+    return send(*in);
+}
+
 SOAPClient::~SOAPClient()
 {
     delete m_transport;
@@ -49,7 +57,7 @@ void SOAPClient::reset()
 void SOAPClient::send(const Envelope& env, const SOAPTransport::Address& addr)
 {
     // Prepare a transport object.
-    const char* pch = strchr(addr.m_endpoint,':');
+    const char* pch = addr.m_endpoint ? strchr(addr.m_endpoint,':') : NULL;
     if (!pch)
         throw IOException("SOAP endpoint was not a URL.");
     string scheme(addr.m_endpoint, pch-addr.m_endpoint);
@@ -122,7 +130,7 @@ Envelope* SOAPClient::receive()
 
 bool SOAPClient::handleFault(const Fault& fault)
 {
-    const QName* code = (fault.getFaultcode() ? fault.getFaultcode()->getCode() : NULL);
+    const xmltooling::QName* code = (fault.getFaultcode() ? fault.getFaultcode()->getCode() : NULL);
     auto_ptr_char str((fault.getFaultstring() ? fault.getFaultstring()->getString() : NULL));
     Category::getInstance(XMLTOOLING_LOGCAT".SOAPClient").error(
         "SOAP client detected a Fault: (%s) (%s)",
index e6fc4d6..c635f30 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2008 Internet2
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@
 /**
  * SOAPImpl.cpp
  * 
- * Implementation classes for SOAP schema
+ * Implementation classes for SOAP 1.1 schema
  */
 
 #include "internal.h"
@@ -34,6 +34,7 @@
 
 using namespace soap11;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 using xmlconstants::SOAP11ENV_NS;
 using xmlconstants::SOAP11ENV_PREFIX;
@@ -54,13 +55,13 @@ namespace {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
-        QName* m_qname;
+        xmltooling::QName* m_qname;
     public:
         virtual ~FaultcodeImpl() {
             delete m_qname;
         }
 
-        FaultcodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        FaultcodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(NULL) {
         }
             
@@ -69,11 +70,11 @@ namespace {
             setCode(src.getCode());
         }
         
-        const QName* getCode() const {
+        const xmltooling::QName* getCode() const {
             return m_qname;
         }
         
-        void setCode(const QName* qname) {
+        void setCode(const xmltooling::QName* qname) {
             m_qname=prepareForAssignment(m_qname,qname);
             if (m_qname) {
                 auto_ptr_XMLCh temp(m_qname->toString().c_str());
@@ -96,7 +97,7 @@ namespace {
     public:
         virtual ~DetailImpl() {}
 
-        DetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        DetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -158,7 +159,7 @@ namespace {
     public:
         virtual ~FaultImpl() {}
 
-        FaultImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        FaultImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -199,17 +200,12 @@ namespace {
         public AbstractXMLObjectMarshaller,
         public AbstractXMLObjectUnmarshaller
     {
-        void init() {
-            m_EncodingStyle=NULL;
-        }
     public:
         virtual ~BodyImpl() {
-            XMLString::release(&m_EncodingStyle);
         }
 
-        BodyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        BodyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            init();
         }
             
         BodyImpl(const BodyImpl& src)
@@ -217,31 +213,16 @@ namespace {
                     AbstractAttributeExtensibleXMLObject(src),
                     AbstractComplexElement(src),
                     AbstractDOMCachingXMLObject(src) {
-            init();
-            setEncodingStyle(src.getEncodingStyle());
             VectorOf(XMLObject) v=getUnknownXMLObjects();
             for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
                 v.push_back((*i)->clone());
         }
         
         IMPL_XMLOBJECT_CLONE(Body);
-        IMPL_STRING_ATTRIB(EncodingStyle);
         IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject, m_children.end());
 
-        using AbstractAttributeExtensibleXMLObject::setAttribute;
-        void setAttribute(QName& qualifiedName, const XMLCh* value, bool ID=false) {
-            if (qualifiedName.hasNamespaceURI() && XMLString::equals(qualifiedName.getNamespaceURI(),SOAP11ENV_NS)) {
-                if (XMLString::equals(qualifiedName.getLocalPart(),ENCODINGSTYLE_ATTRIB_NAME)) {
-                    setEncodingStyle(value);
-                    return;
-                }
-            }
-            AbstractAttributeExtensibleXMLObject::setAttribute(qualifiedName, value, ID);
-        }
-
     protected:
         void marshallAttributes(DOMElement* domElement) const {
-            MARSHALL_STRING_ATTRIB(EncodingStyle,ENCODINGSTYLE,SOAP11ENV_NS);
             marshallExtensionAttributes(domElement);
         }
 
@@ -265,7 +246,7 @@ namespace {
         virtual ~HeaderImpl() {
         }
 
-        HeaderImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        HeaderImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
         }
             
@@ -315,7 +296,7 @@ namespace {
     public:
         virtual ~EnvelopeImpl() {}
 
-        EnvelopeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType)
+        EnvelopeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
             : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
             init();
         }
@@ -385,12 +366,12 @@ const XMLCh Header::TYPE_NAME[] =                       UNICODE_LITERAL_6(H,e,a,
 const XMLCh Header::ACTOR_ATTRIB_NAME[] =               UNICODE_LITERAL_5(a,c,t,o,r);
 const XMLCh Header::MUSTUNDERSTAND_ATTRIB_NAME[] =      UNICODE_LITERAL_14(m,u,s,t,U,n,d,e,r,s,t,a,n,d);
 
-static const XMLCh _CLIENT[] =                          UNICODE_LITERAL_6(C,l,i,e,n,t);\r
-static const XMLCh _SERVER[] =                          UNICODE_LITERAL_6(S,e,r,v,e,r);\r
-static const XMLCh _MUSTUNDERSTAND[] =                  UNICODE_LITERAL_14(M,u,s,t,U,n,d,e,r,s,t,a,n,d);\r
-static const XMLCh _VERSIONMISMATCH[] =                 UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);\r
\r
-QName Faultcode::CLIENT(SOAP11ENV_NS,_CLIENT,SOAP11ENV_PREFIX);\r
-QName Faultcode::SERVER(SOAP11ENV_NS,_SERVER,SOAP11ENV_PREFIX);\r
-QName Faultcode::MUSTUNDERSTAND(SOAP11ENV_NS,_MUSTUNDERSTAND,SOAP11ENV_PREFIX);\r
-QName Faultcode::VERSIONMISMATCH(SOAP11ENV_NS,_VERSIONMISMATCH,SOAP11ENV_PREFIX);\r
+static const XMLCh _CLIENT[] =                          UNICODE_LITERAL_6(C,l,i,e,n,t);
+static const XMLCh _SERVER[] =                          UNICODE_LITERAL_6(S,e,r,v,e,r);
+static const XMLCh _MUSTUNDERSTAND[] =                  UNICODE_LITERAL_14(M,u,s,t,U,n,d,e,r,s,t,a,n,d);
+static const XMLCh _VERSIONMISMATCH[] =                 UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
+xmltooling::QName Faultcode::CLIENT(SOAP11ENV_NS,_CLIENT,SOAP11ENV_PREFIX);
+xmltooling::QName Faultcode::SERVER(SOAP11ENV_NS,_SERVER,SOAP11ENV_PREFIX);
+xmltooling::QName Faultcode::MUSTUNDERSTAND(SOAP11ENV_NS,_MUSTUNDERSTAND,SOAP11ENV_PREFIX);
+xmltooling::QName Faultcode::VERSIONMISMATCH(SOAP11ENV_NS,_VERSIONMISMATCH,SOAP11ENV_PREFIX);
index b8deeb3..1e50c9c 100644 (file)
 #include <xercesc/util/XMLUTF8Transcoder.hpp>
 #include <xercesc/util/XMLUniDefs.hpp>
 
+using namespace xercesc;
+
 static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };
 
 char* xmltooling::toUTF8(const XMLCh* src, bool use_malloc)
 {
-    unsigned int eaten,factor=1,bufsize;
-    unsigned int srclen=XMLString::stringLen(src);
+    xsecsize_t eaten,factor=1,bufsize;
+    xsecsize_t srclen=XMLString::stringLen(src);
     XMLUTF8Transcoder t(UTF8, 4096);    // block size isn't used any more anyway
     do {
         bufsize = factor*srclen + 10;
@@ -63,8 +65,8 @@ char* xmltooling::toUTF8(const XMLCh* src, bool use_malloc)
 
 XMLCh* xmltooling::fromUTF8(const char* src, bool use_malloc)
 {
-    unsigned int eaten;
-    unsigned int srclen=strlen(src);
+    xsecsize_t eaten;
+    xsecsize_t srclen=strlen(src);
     XMLUTF8Transcoder t(UTF8, 4096);    // block size isn't used any more anyway
     XMLCh* buf = use_malloc ? reinterpret_cast<XMLCh*>(malloc((srclen+1)*sizeof(XMLCh))) : new XMLCh[srclen + 1];
     unsigned char* sizes=new unsigned char[srclen];
@@ -86,3 +88,8 @@ std::ostream& xmltooling::operator<<(std::ostream& ostr, const XMLCh* s)
     }
     return ostr;
 }
+
+std::ostream& xmltooling::operator<<(std::ostream& ostr, const xstring& s)
+{
+    return ostr << s.c_str();
+}
index 6cc8763..1076abc 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
 
 /**
  * @file xmltooling/unicode.h
- * 
+ *
  * Helper classes and types for manipulating Unicode
  */
+
 #ifndef __xmltooling_unicode_h__
 #define __xmltooling_unicode_h__
 
 #include <xmltooling/base.h>
 
+#ifndef HAVE_GOOD_STL
+# include <xmltooling/char_traits.h>
+#endif
+
 #include <string>
 #include <iostream>
 #include <xercesc/util/XMLString.hpp>
 
 namespace xmltooling {
-    
-    #ifdef HAVE_GOOD_STL
+
+#ifdef HAVE_GOOD_STL
         /**
          * An STL string type that supports 16-bit Unicode.
-         * Most compilers support this, but various versions of gcc3 do not.
          */
         typedef std::basic_string<XMLCh> xstring;
-    #endif
+#else
+        /**
+         * An STL string type that supports 16-bit Unicode.
+         */
+        typedef std::basic_string< XMLCh,char_traits<XMLCh> > xstring;
+#endif
 
     /**
      * Transcodes a 16-bit Unicode string into UTF-8.
-     * 
+     *
      * @param src           the 16-bit string to transcode
      * @param use_malloc    true iff the result should be allocated with malloc, false to use new
-     * @return      a UTF-8 string allocated by the Xerces memory manager 
+     * @return      a UTF-8 string allocated by the Xerces memory manager
      */
     extern XMLTOOL_API char* toUTF8(const XMLCh* src, bool use_malloc=false);
 
     /**
      * Transcodes a UTF-8 string into 16-bit Unicode.
-     * 
+     *
      * @param src           the UTF-8 string to transcode
      * @param use_malloc    true iff the result should be allocated with malloc, false to use new
-     * @return      a 16-bit Unicode string allocated by the Xerces memory manager 
+     * @return      a 16-bit Unicode string allocated by the Xerces memory manager
      */
     extern XMLTOOL_API XMLCh* fromUTF8(const char* src, bool use_malloc=false);
 
     /**
      * Writes a Unicode string to an ASCII stream by transcoding to UTF8.
-     * 
+     *
      * @param ostr  stream to write to
      * @param s     string to write
      * @return      reference to output stream
@@ -67,20 +75,35 @@ namespace xmltooling {
     extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const XMLCh* s);
 
     /**
+     * Writes a Unicode string to an ASCII stream by transcoding to UTF8.
+     *
+     * @param ostr  stream to write to
+     * @param s     string to write
+     * @return      reference to output stream
+     */
+    extern XMLTOOL_API std::ostream& operator<<(std::ostream& ostr, const xstring& s);
+
+    /**
      * A minimal auto_ptr-like class that can copy or transcode a buffer into
      * the local code page and free the result automatically.
-     * 
+     *
      * Needed because a standard auto_ptr would use delete on the resulting
-     * pointer. 
+     * pointer.
      */
     class XMLTOOL_API auto_ptr_char
     {
         MAKE_NONCOPYABLE(auto_ptr_char);
     public:
         /**
+         * Default constructor.
+         */
+        auto_ptr_char() : m_buf(NULL) {
+        }
+
+        /**
          * Constructor transcodes a 16-bit Unicode string into the local code page (NOT UTF-8) and wraps the result.
          * @param src   the 16-bit string to transcode and wrap
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true)
          */
         auto_ptr_char(const XMLCh* src, bool trim=true) : m_buf(xercesc::XMLString::transcode(src)) {
             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
@@ -89,7 +112,7 @@ namespace xmltooling {
         /**
          * Constructor copies a local code page (NOT UTF-8) string and wraps the result.
          * @param src   the local string to copy and wrap
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true)
          */
         auto_ptr_char(const char* src, bool trim=true) : m_buf(xercesc::XMLString::replicate(src)) {
             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
@@ -118,25 +141,31 @@ namespace xmltooling {
             char* temp=m_buf; m_buf=NULL; return temp;
         }
 
-    private:    
+    private:
         char* m_buf;
     };
 
     /**
      * A minimal auto_ptr-like class that can copy or transcode a buffer into
      * 16-bit Unicode and free the result automatically.
-     * 
+     *
      * Needed because a standard auto_ptr would use delete on the resulting
-     * pointer. 
+     * pointer.
      */
     class XMLTOOL_API auto_ptr_XMLCh
     {
         MAKE_NONCOPYABLE(auto_ptr_XMLCh);
     public:
         /**
+         * Default constructor.
+         */
+        auto_ptr_XMLCh() : m_buf(NULL) {
+        }
+
+        /**
          * Constructor transcodes a local code page (NOT UTF-8) string into 16-bit Unicode and wraps the result.
          * @param src   the local string to transcode and wrap
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true)
          */
         auto_ptr_XMLCh(const char* src, bool trim=true) : m_buf(xercesc::XMLString::transcode(src)) {
             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
@@ -145,7 +174,7 @@ namespace xmltooling {
         /**
          * Constructor copies a 16-bit Unicode string and wraps the result.
          * @param src   the Unicode string to copy and wrap
-         * @param trim  trims leading/trailing whitespace from the result (defaults to true) 
+         * @param trim  trims leading/trailing whitespace from the result (defaults to true)
          */
         auto_ptr_XMLCh(const XMLCh* src, bool trim=true) : m_buf(xercesc::XMLString::replicate(src)) {
             if (trim && m_buf) xercesc::XMLString::trim(m_buf);
@@ -165,7 +194,7 @@ namespace xmltooling {
         const XMLCh* get() const {
             return m_buf;
         }
-        
+
         /**
          * Returns the wrapped buffer and transfers ownership of it to the caller.
          * @return a null-terminated Unicode string
diff --git a/xmltooling/util/CurlNetAccessor.cpp b/xmltooling/util/CurlNetAccessor.cpp
deleted file mode 100644 (file)
index e09ffe5..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/*
- * $Id$
- */
-
-#include "internal.h"
-
-#include <xercesc/util/XMLUniDefs.hpp>
-#include <xercesc/util/XMLUni.hpp>
-#include <xercesc/util/XMLString.hpp>
-#include <xercesc/util/XMLExceptMsgs.hpp>
-#include <xmltooling/util/CurlURLInputStream.hpp>
-#include <xmltooling/util/CurlNetAccessor.hpp>
-
-using namespace xmltooling;
-
-const XMLCh xmltooling::CurlNetAccessor::fgMyName[] =
-{
-    chLatin_C, chLatin_u, chLatin_r, chLatin_l, chLatin_N, chLatin_e,
-    chLatin_t, chLatin_A, chLatin_c, chLatin_c, chLatin_e, chLatin_s,
-    chLatin_s, chLatin_o, chLatin_r, chNull
-};
-
-
-CurlNetAccessor::CurlNetAccessor()
-{
-}
-
-
-CurlNetAccessor::~CurlNetAccessor()
-{
-}
-
-BinInputStream*
-CurlNetAccessor::makeNew(const XMLURL&  urlSource, const XMLNetHTTPInfo* httpInfo/*=0*/)
-{
-       // Just create a CurlURLInputStream
-       // We defer any checking of the url type for curl in CurlURLInputStream
-       CurlURLInputStream* retStrm =
-               new (urlSource.getMemoryManager()) CurlURLInputStream(urlSource, httpInfo);
-       return retStrm;            
-}
diff --git a/xmltooling/util/CurlNetAccessor.hpp b/xmltooling/util/CurlNetAccessor.hpp
deleted file mode 100644 (file)
index a1ff700..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/*
- * $Id$
- */
-
-#if !defined(XERCESC_INCLUDE_GUARD_CURLNETACCESSOR_HPP) && !defined(XMLTOOLING_LITE)
-#define XERCESC_INCLUDE_GUARD_CURLNETACCESSOR_HPP
-
-#include <xmltooling/base.h>
-
-#include <xercesc/util/XercesDefs.hpp>
-#include <xercesc/util/XMLURL.hpp>
-#include <xercesc/util/BinInputStream.hpp>
-#include <xercesc/util/XMLNetAccessor.hpp>
-
-namespace xmltooling {
-
-//
-// This class is the wrapper for the socket based code which
-// provides the ability to fetch a resource specified using
-// a HTTP or FTP URL.
-//
-
-class XMLTOOL_API CurlNetAccessor : public XMLNetAccessor
-{
-public :
-    CurlNetAccessor();
-    ~CurlNetAccessor();
-    
-    virtual BinInputStream* makeNew(const XMLURL&  urlSource, const XMLNetHTTPInfo* httpInfo=0);
-    virtual const XMLCh* getId() const;
-
-private :
-    static const XMLCh fgMyName[];
-
-    CurlNetAccessor(const CurlNetAccessor&);
-    CurlNetAccessor& operator=(const CurlNetAccessor&);
-
-}; // CurlNetAccessor
-
-
-inline const XMLCh* CurlNetAccessor::getId() const
-{
-    return fgMyName;
-}
-
-
-};
-
-#endif // CURLNETACCESSOR_HPP
-
-
index 532d318..35fe364 100644 (file)
  * limitations under the License.
  */
 
-/*
- * $Id$
+/**
+ * xmltooling/util/CurlURLInputStream.cpp
+ *
+ * Asynchronous use of curl to fetch data from a URL.
  */
 
 #include "internal.h"
 
-#include <curl/curl.h>
+#include <xmltooling/util/CurlURLInputStream.h>
+#include <xmltooling/util/XMLHelper.h>
 
+#include <openssl/ssl.h>
 #include <xercesc/util/XercesDefs.hpp>
 #include <xercesc/util/XMLNetAccessor.hpp>
 #include <xercesc/util/XMLString.hpp>
 #include <xercesc/util/TranscodingException.hpp>
 #include <xercesc/util/PlatformUtils.hpp>
 
-#include <xmltooling/util/CurlURLInputStream.hpp>
-
 using namespace xmltooling;
+using namespace xercesc;
+
+namespace {
+    static const XMLCh  _CURL[] =           UNICODE_LITERAL_4(C,U,R,L);
+    static const XMLCh _option[] =          UNICODE_LITERAL_6(o,p,t,i,o,n);
+    static const XMLCh _provider[] =        UNICODE_LITERAL_8(p,r,o,v,i,d,e,r);
+    static const XMLCh TransportOption[] =  UNICODE_LITERAL_15(T,r,a,n,s,p,o,r,t,O,p,t,i,o,n);
+    static const XMLCh uri[] =              UNICODE_LITERAL_3(u,r,i);
+    static const XMLCh url[] =              UNICODE_LITERAL_3(u,r,l);
+    static const XMLCh verifyHost[] =       UNICODE_LITERAL_10(v,e,r,i,f,y,H,o,s,t);
+
+    // callback to invoke a caller-defined SSL callback
+    CURLcode ssl_ctx_callback(CURL* curl, SSL_CTX* ssl_ctx, void* userptr)
+    {
+        // Manually disable SSLv2 so we're not dependent on libcurl to do it.
+        // Also disable the ticket option where implemented, since this breaks a variety
+        // of servers. Newer libcurl also does this for us.
+#ifdef SSL_OP_NO_TICKET
+        SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2|SSL_OP_NO_TICKET);
+#else
+        SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2);
+#endif
 
+        return CURLE_OK;
+    }
+}
 
-CurlURLInputStream::CurlURLInputStream(const XMLURL& urlSource, const XMLNetHTTPInfo* httpInfo/*=0*/)
-      : fMemoryManager(urlSource.getMemoryManager())
-      , fURLSource(urlSource)
-      , fURL(0)
-      , fInputStream(NULL)
-      , m_log(logging::Category::getInstance(XMLTOOLING_LOGCAT".libcurl.NetAccessor"))
+CurlURLInputStream::CurlURLInputStream(const char* url)
+    : fLog(logging::Category::getInstance(XMLTOOLING_LOGCAT".libcurl.InputStream"))
+    , fURL(url)
+    , fMulti(0)
+    , fEasy(0)
+    , fTotalBytesRead(0)
+    , fWritePtr(0)
+    , fBytesRead(0)
+    , fBytesToRead(0)
+    , fDataAvailable(false)
+    , fBufferHeadPtr(fBuffer)
+    , fBufferTailPtr(fBuffer)
+    , fContentType(0)
 {
-       // Get the text of the URL we're going to use
-       fURL.reset(XMLString::transcode(fURLSource.getURLText(), fMemoryManager), fMemoryManager);
+    init();
 }
 
+CurlURLInputStream::CurlURLInputStream(const XMLCh* url)
+    : fLog(logging::Category::getInstance(XMLTOOLING_LOGCAT".libcurl.InputStream"))
+    , fMulti(0)
+    , fEasy(0)
+    , fTotalBytesRead(0)
+    , fWritePtr(0)
+    , fBytesRead(0)
+    , fBytesToRead(0)
+    , fDataAvailable(false)
+    , fBufferHeadPtr(fBuffer)
+    , fBufferTailPtr(fBuffer)
+    , fContentType(0)
+{
+    auto_ptr_char temp(url);
+    fURL = temp.get();
+    init();
+}
+
+CurlURLInputStream::CurlURLInputStream(const DOMElement* e)
+    : fLog(logging::Category::getInstance(XMLTOOLING_LOGCAT".libcurl.InputStream"))
+    , fMulti(0)
+    , fEasy(0)
+    , fTotalBytesRead(0)
+    , fWritePtr(0)
+    , fBytesRead(0)
+    , fBytesToRead(0)
+    , fDataAvailable(false)
+    , fBufferHeadPtr(fBuffer)
+    , fBufferTailPtr(fBuffer)
+    , fContentType(0)
+{
+    const XMLCh* attr = e->getAttributeNS(NULL, url);
+    if (!attr || !*attr) {
+        attr = e->getAttributeNS(NULL, uri);
+        if (!attr || !*attr)
+            throw IOException("No URL supplied via DOM to CurlURLInputStream constructor.");
+    }
+
+    auto_ptr_char temp(attr);
+    fURL = temp.get();
+    init(e);
+}
 
 CurlURLInputStream::~CurlURLInputStream()
 {
-    delete fInputStream;
+    if (fEasy) {
+        // Remove the easy handle from the multi stack
+        curl_multi_remove_handle(fMulti, fEasy);
+
+        // Cleanup the easy handle
+        curl_easy_cleanup(fEasy);
+    }
+
+    if (fMulti) {
+        // Cleanup the multi handle
+        curl_multi_cleanup(fMulti);
+    }
+
+    XMLString::release(&fContentType);
+}
+
+void CurlURLInputStream::init(const DOMElement* e)
+{
+    // Allocate the curl multi handle
+    fMulti = curl_multi_init();
+
+    // Allocate the curl easy handle
+    fEasy = curl_easy_init();
+
+    if (!fMulti || !fEasy)
+        throw IOException("Failed to allocate libcurl handles.");
+
+    curl_easy_setopt(fEasy, CURLOPT_URL, fURL.c_str());
+
+    // Set up a way to recieve the data
+    curl_easy_setopt(fEasy, CURLOPT_WRITEDATA, this);                       // Pass this pointer to write function
+    curl_easy_setopt(fEasy, CURLOPT_WRITEFUNCTION, staticWriteCallback);    // Our static write function
+
+    // Do redirects
+    curl_easy_setopt(fEasy, CURLOPT_FOLLOWLOCATION, 1);
+    curl_easy_setopt(fEasy, CURLOPT_MAXREDIRS, 6);
+
+    // Default settings.
+    curl_easy_setopt(fEasy, CURLOPT_CONNECTTIMEOUT,30);
+    curl_easy_setopt(fEasy, CURLOPT_TIMEOUT,60);
+    curl_easy_setopt(fEasy, CURLOPT_HTTPAUTH,0);
+    curl_easy_setopt(fEasy, CURLOPT_USERPWD,NULL);
+    curl_easy_setopt(fEasy, CURLOPT_SSL_VERIFYHOST, 2);
+    curl_easy_setopt(fEasy, CURLOPT_SSL_VERIFYPEER, 0);
+    curl_easy_setopt(fEasy, CURLOPT_SSL_CIPHER_LIST, "ALL:!aNULL:!LOW:!EXPORT:!SSLv2");
+    curl_easy_setopt(fEasy, CURLOPT_NOPROGRESS, 1);
+    curl_easy_setopt(fEasy, CURLOPT_NOSIGNAL, 1);
+    curl_easy_setopt(fEasy, CURLOPT_FAILONERROR, 1);
+
+    // Install SSL callback.
+    curl_easy_setopt(fEasy, CURLOPT_SSL_CTX_FUNCTION, ssl_ctx_callback);
+
+    fError[0] = 0;
+    curl_easy_setopt(fEasy, CURLOPT_ERRORBUFFER, fError);
+
+    if (e) {
+        const XMLCh* flag = e->getAttributeNS(NULL, verifyHost);
+        if (flag && (*flag == chLatin_f || *flag == chDigit_0))
+            curl_easy_setopt(fEasy, CURLOPT_SSL_VERIFYHOST, 0);
+
+        // Process TransportOption elements.
+        bool success;
+        DOMElement* child = XMLHelper::getLastChildElement(e, TransportOption);
+        while (child) {
+            if (child->hasChildNodes() && XMLString::equals(child->getAttributeNS(NULL,_provider), _CURL)) {
+                auto_ptr_char option(child->getAttributeNS(NULL,_option));
+                auto_ptr_char value(child->getFirstChild()->getNodeValue());
+                if (option.get() && *option.get() && value.get() && *value.get()) {
+                    // For libcurl, the option is an enum and the value type depends on the option.
+                    CURLoption opt = static_cast<CURLoption>(strtol(option.get(), NULL, 10));
+                    if (opt < CURLOPTTYPE_OBJECTPOINT)
+                        success = (curl_easy_setopt(fEasy, opt, strtol(value.get(), NULL, 10)) == CURLE_OK);
+#ifdef CURLOPTTYPE_OFF_T
+                    else if (opt < CURLOPTTYPE_OFF_T)
+                        success = (curl_easy_setopt(fEasy, opt, value.get()) == CURLE_OK);
+                    else if (sizeof(curl_off_t) == sizeof(long))
+                        success = (curl_easy_setopt(fEasy, opt, strtol(value.get(), NULL, 10)) == CURLE_OK);
+                    else
+                        success = false;
+#else
+                    else
+                        success = (curl_easy_setopt(fEasy, opt, value.get()) == CURLE_OK);
+#endif
+                    if (!success)
+                        fLog.error("failed to set transport option (%s)", option.get());
+                }
+            }
+            child = XMLHelper::getPreviousSiblingElement(child, TransportOption);
+        }
+    }
+
+    // Add easy handle to the multi stack
+    curl_multi_add_handle(fMulti, fEasy);
+
+    fLog.debug("libcurl trying to fetch %s", fURL.c_str());
+
+    // Start reading, to get the content type
+    while(fBufferHeadPtr == fBuffer) {
+        int runningHandles = 0;
+        try {
+            readMore(&runningHandles);
+        }
+        catch (XMLException& ex) {
+            curl_multi_remove_handle(fMulti, fEasy);
+            curl_easy_cleanup(fEasy);
+            fEasy = NULL;
+            curl_multi_cleanup(fMulti);
+            fMulti = NULL;
+            auto_ptr_char msg(ex.getMessage());
+            throw IOException(msg.get());
+        }
+        if(runningHandles == 0) break;
+    }
+
+    // Find the content type
+    char* contentType8 = NULL;
+    curl_easy_getinfo(fEasy, CURLINFO_CONTENT_TYPE, &contentType8);
+    if(contentType8)
+        fContentType = XMLString::transcode(contentType8);
 }
 
 
-size_t CurlURLInputStream::staticWriteCallback(void* ptr, size_t size, size_t nmemb, void* stream)
+size_t CurlURLInputStream::staticWriteCallback(char* buffer, size_t size, size_t nitems, void* outstream)
 {
-    size_t len = size*nmemb;
-    reinterpret_cast<std::stringstream*>(stream)->write(reinterpret_cast<const char*>(ptr),len);
-    return len;
+    return ((CurlURLInputStream*)outstream)->writeCallback(buffer, size, nitems);
 }
 
+size_t CurlURLInputStream::writeCallback(char* buffer, size_t size, size_t nitems)
+{
+    size_t cnt = size * nitems;
+    size_t totalConsumed = 0;
+
+    // Consume as many bytes as possible immediately into the buffer
+    size_t consume = (cnt > fBytesToRead) ? fBytesToRead : cnt;
+    memcpy(fWritePtr, buffer, consume);
+    fWritePtr       += consume;
+    fBytesRead      += consume;
+    fTotalBytesRead += consume;
+    fBytesToRead    -= consume;
 
-unsigned int CurlURLInputStream::readBytes(XMLByte* const toFill, const unsigned int maxToRead)
+    //fLog.debug("write callback consuming %d bytes", consume);
+
+    // If bytes remain, rebuffer as many as possible into our holding buffer
+    buffer          += consume;
+    totalConsumed   += consume;
+    cnt             -= consume;
+    if (cnt > 0)
+    {
+        size_t bufAvail = sizeof(fBuffer) - (fBufferHeadPtr - fBuffer);
+        consume = (cnt > bufAvail) ? bufAvail : cnt;
+        memcpy(fBufferHeadPtr, buffer, consume);
+        fBufferHeadPtr  += consume;
+        buffer          += consume;
+        totalConsumed   += consume;
+        //fLog.debug("write callback rebuffering %d bytes", consume);
+    }
+
+    // Return the total amount we've consumed. If we don't consume all the bytes
+    // then an error will be generated. Since our buffer size is equal to the
+    // maximum size that curl will write, this should never happen unless there
+    // is a logic error somewhere here.
+    return totalConsumed;
+}
+
+bool CurlURLInputStream::readMore(int* runningHandles)
 {
-    if (!fInputStream) {
-        // Allocate the curl easy handle.
-        CURL* fEasy = curl_easy_init();
-        if (!fEasy)
-            ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_InternalError, "unable to allocate libcurl handle", fMemoryManager);
-
-        m_log.debug("libcurl trying to fetch %s", fURL.get());
-
-        // Set URL option
-        curl_easy_setopt(fEasy, CURLOPT_URL, fURL.get());
-        curl_easy_setopt(fEasy, CURLOPT_WRITEDATA, &fUnderlyingStream);
-        curl_easy_setopt(fEasy, CURLOPT_WRITEFUNCTION, staticWriteCallback);
-        curl_easy_setopt(fEasy, CURLOPT_CONNECTTIMEOUT, 30);
-        curl_easy_setopt(fEasy, CURLOPT_TIMEOUT, 60);
-        curl_easy_setopt(fEasy, CURLOPT_SSL_VERIFYHOST, 0);
-        curl_easy_setopt(fEasy, CURLOPT_SSL_VERIFYPEER, 0);
-        curl_easy_setopt(fEasy, CURLOPT_NOPROGRESS, 1);
-        curl_easy_setopt(fEasy, CURLOPT_NOSIGNAL, 1);
-        curl_easy_setopt(fEasy, CURLOPT_FAILONERROR, 1);
-
-        char curl_errorbuf[CURL_ERROR_SIZE];
-        curl_errorbuf[0]=0;
-        curl_easy_setopt(fEasy,CURLOPT_ERRORBUFFER,curl_errorbuf);
-
-        // Fetch the data.
-        if (curl_easy_perform(fEasy) != CURLE_OK) {
-            curl_easy_cleanup(fEasy);
-            ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_InternalError, curl_errorbuf, fMemoryManager);
-        }
+    // Ask the curl to do some work
+    CURLMcode curlResult = curl_multi_perform(fMulti, runningHandles);
 
-        curl_easy_cleanup(fEasy);
+    // Process messages from curl
+    int msgsInQueue = 0;
+    for (CURLMsg* msg = NULL; (msg = curl_multi_info_read(fMulti, &msgsInQueue)) != NULL; )
+    {
+        //fLog.debug("msg %d, %d from curl", msg->msg, msg->data.result);
+
+        if (msg->msg != CURLMSG_DONE)
+            return true;
 
-        /*
         switch (msg->data.result)
         {
         case CURLE_OK:
@@ -106,31 +312,96 @@ unsigned int CurlURLInputStream::readBytes(XMLByte* const toFill, const unsigned
             break;
 
         case CURLE_UNSUPPORTED_PROTOCOL:
-            ThrowXMLwithMemMgr(MalformedURLException, XMLExcepts::URL_UnsupportedProto, fMemoryManager);
+            ThrowXML(MalformedURLException, XMLExcepts::URL_UnsupportedProto);
             break;
 
         case CURLE_COULDNT_RESOLVE_HOST:
         case CURLE_COULDNT_RESOLVE_PROXY:
-            ThrowXMLwithMemMgr1(NetAccessorException,  XMLExcepts::NetAcc_TargetResolution, fURLSource.getHost(), fMemoryManager);
+            ThrowXML1(NetAccessorException,  XMLExcepts::NetAcc_TargetResolution, fURL.c_str());
             break;
 
         case CURLE_COULDNT_CONNECT:
-            ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_ConnSocket, fURLSource.getURLText(), fMemoryManager);
+            ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_ConnSocket, fURL.c_str());
+            break;
 
         case CURLE_RECV_ERROR:
-            ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, fURLSource.getURLText(), fMemoryManager);
+            ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_ReadSocket, fURL.c_str());
             break;
 
         default:
-            m_log.error("curl NetAccessor encountered error from libcurl (%d)", msg->data.result);
-            ThrowXMLwithMemMgr1(NetAccessorException, XMLExcepts::NetAcc_InternalError, fURLSource.getURLText(), fMemoryManager);
+            fLog.error("error while fetching %s: (%d) %s", fURL.c_str(), msg->data.result, fError);
+            ThrowXML1(NetAccessorException, XMLExcepts::NetAcc_InternalError, fURL.c_str());
             break;
         }
-        */
+    }
 
-        fInputStream = new (fMemoryManager) StreamInputSource::StreamBinInputStream(fUnderlyingStream);
+    // If nothing is running any longer, bail out
+    if(*runningHandles == 0)
+        return false;
+
+    // If there is no further data to read, and we haven't
+    // read any yet on this invocation, call select to wait for data
+    if (curlResult != CURLM_CALL_MULTI_PERFORM && fBytesRead == 0)
+    {
+        fd_set readSet;
+        fd_set writeSet;
+        fd_set exceptSet;
+        int fdcnt=0;
+
+        FD_ZERO(&readSet);
+        FD_ZERO(&writeSet);
+        FD_ZERO(&exceptSet);
+
+        // Ask curl for the file descriptors to wait on
+        curl_multi_fdset(fMulti, &readSet, &writeSet, &exceptSet, &fdcnt);
+
+        // Wait on the file descriptors
+        timeval tv;
+        tv.tv_sec  = 2;
+        tv.tv_usec = 0;
+        select(fdcnt+1, &readSet, &writeSet, &exceptSet, &tv);
+    }
+
+    return curlResult == CURLM_CALL_MULTI_PERFORM;
+}
+
+xsecsize_t CurlURLInputStream::readBytes(XMLByte* const toFill, const xsecsize_t maxToRead)
+{
+    fBytesRead = 0;
+    fBytesToRead = maxToRead;
+    fWritePtr = toFill;
+
+    for (bool tryAgain = true; fBytesToRead > 0 && (tryAgain || fBytesRead == 0); )
+    {
+        // First, any buffered data we have available
+        size_t bufCnt = fBufferHeadPtr - fBufferTailPtr;
+        bufCnt = (bufCnt > fBytesToRead) ? fBytesToRead : bufCnt;
+        if (bufCnt > 0)
+        {
+            memcpy(fWritePtr, fBufferTailPtr, bufCnt);
+            fWritePtr       += bufCnt;
+            fBytesRead      += bufCnt;
+            fTotalBytesRead += bufCnt;
+            fBytesToRead    -= bufCnt;
+
+            fBufferTailPtr  += bufCnt;
+            if (fBufferTailPtr == fBufferHeadPtr)
+                fBufferHeadPtr = fBufferTailPtr = fBuffer;
+
+            //fLog.debug("consuming %d buffered bytes", bufCnt);
+
+            tryAgain = true;
+            continue;
+        }
+
+        // Ask the curl to do some work
+        int runningHandles = 0;
+        tryAgain = readMore(&runningHandles);
+
+        // If nothing is running any longer, bail out
+        if (runningHandles == 0)
+            break;
     }
 
-    // Defer to the stream wrapper.
-    return fInputStream->readBytes(toFill, maxToRead);
+    return fBytesRead;
 }
diff --git a/xmltooling/util/CurlURLInputStream.h b/xmltooling/util/CurlURLInputStream.h
new file mode 100644 (file)
index 0000000..e397331
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+
+/**
+ * @file xmltooling/util/CurlURLInputStream.h
+ *
+ * Asynchronous use of curl to fetch data from a URL.
+ */
+
+#if !defined(__xmltooling_curlinstr_h__) && !defined(XMLTOOLING_LITE)
+#define __xmltooling_curlinstr_h__
+
+#include <xmltooling/logging.h>
+
+#include <curl/curl.h>
+#include <xercesc/util/BinInputStream.hpp>
+
+namespace xmltooling {
+
+    /**
+     * Adapted from Xerces-C as a more advanced input stream implementation
+     * for subsequent use in parsing remote documents.
+     */
+    class XMLTOOL_API CurlURLInputStream : public xercesc::BinInputStream
+    {
+    public :
+        /**
+         * Constructor.
+         *
+         * @param url   the URL of the resource to fetch
+         */
+        CurlURLInputStream(const char* url);
+
+        /**
+         * Constructor.
+         *
+         * @param url   the URL of the resource to fetch
+         */
+        CurlURLInputStream(const XMLCh* url);
+
+        /**
+         * Constructor taking a DOM element supporting the following content:
+         * 
+         * <dl>
+         *  <dt>uri | url</dt>
+         *  <dd>identifies the remote resource</dd>
+         *  <dt>verifyHost</dt>
+         *  <dd>true iff name of host should be matched against TLS/SSL certificate</dd>
+         *  <dt>TransportOption elements, like so:</dt>
+         *  <dd>&lt;TransportOption provider="CURL" option="150"&gt;0&lt;/TransportOption&gt;</dd>
+         * </dl>
+         * 
+         * @param e     DOM to supply configuration
+         */
+        CurlURLInputStream(const xercesc::DOMElement* e);
+
+        ~CurlURLInputStream();
+
+#ifdef XMLTOOLING_XERCESC_64BITSAFE
+        XMLFilePos
+#else
+        unsigned int
+#endif
+        curPos() const {
+            return fTotalBytesRead;
+        }
+
+#ifdef XMLTOOLING_XERCESC_INPUTSTREAM_HAS_CONTENTTYPE
+        const XMLCh* getContentType() const {
+            return fContentType;
+        }
+#endif
+
+        xsecsize_t readBytes(XMLByte* const toFill, const xsecsize_t maxToRead);
+
+    private :
+        CurlURLInputStream(const CurlURLInputStream&);
+        CurlURLInputStream& operator=(const CurlURLInputStream&);
+
+        // libcurl callbacks for data read/write
+        static size_t staticWriteCallback(char *buffer, size_t size, size_t nitems, void *outstream);
+        size_t writeCallback(char *buffer, size_t size, size_t nitems);
+
+        void init(const xercesc::DOMElement* e=NULL);
+        bool readMore(int *runningHandles);
+
+        logging::Category&  fLog;\r
+        std::string         fURL;\r
+
+        CURLM*              fMulti;
+        CURL*               fEasy;
+
+        unsigned long       fTotalBytesRead;
+        XMLByte*            fWritePtr;
+        xsecsize_t          fBytesRead;
+        xsecsize_t          fBytesToRead;
+        bool                fDataAvailable;
+
+        // Overflow buffer for when curl writes more data to us
+        // than we've asked for.
+        XMLByte             fBuffer[CURL_MAX_WRITE_SIZE];
+        XMLByte*            fBufferHeadPtr;
+        XMLByte*            fBufferTailPtr;
+
+        XMLCh*              fContentType;
+
+        char                fError[CURL_ERROR_SIZE];
+    };
+};
+
+#endif // __xmltooling_curlinstr_h__
diff --git a/xmltooling/util/CurlURLInputStream.hpp b/xmltooling/util/CurlURLInputStream.hpp
deleted file mode 100644 (file)
index cd6106a..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.
- */
-
-/*
- * $Id$
- */
-
-#if !defined(XERCESC_INCLUDE_GUARD_CURLURLINPUTSTREAM_HPP) && !defined(XMLTOOLING_LITE)
-#define XERCESC_INCLUDE_GUARD_CURLURLINPUTSTREAM_HPP
-
-#include <xmltooling/logging.h>
-#include <xmltooling/util/ParserPool.h>
-
-#include <sstream>
-
-#include <xercesc/util/XMLURL.hpp>
-#include <xercesc/util/XMLExceptMsgs.hpp>
-#include <xercesc/util/Janitor.hpp>
-#include <xercesc/util/BinInputStream.hpp>
-#include <xercesc/util/XMLNetAccessor.hpp>
-
-namespace xmltooling {
-
-//
-// This class implements the BinInputStream interface specified by the XML
-// parser.
-//
-
-class XMLTOOL_API CurlURLInputStream : public BinInputStream
-{
-public :
-    CurlURLInputStream(const XMLURL&  urlSource, const XMLNetHTTPInfo* httpInfo=0);
-    ~CurlURLInputStream();
-
-    unsigned int curPos() const;
-    unsigned int readBytes(XMLByte* const toFill, const unsigned int maxToRead);
-
-private :
-    // -----------------------------------------------------------------------
-    //  Unimplemented constructors and operators
-    // -----------------------------------------------------------------------
-    CurlURLInputStream(const CurlURLInputStream&);
-    CurlURLInputStream& operator=(const CurlURLInputStream&);
-
-    static size_t staticWriteCallback(void* ptr, size_t size, size_t nmemb, void* stream);
-
-    std::stringstream   fUnderlyingStream;
-    MemoryManager*      fMemoryManager;
-    XMLURL                             fURLSource;
-    ArrayJanitor<char> fURL;
-    StreamInputSource::StreamBinInputStream* fInputStream;
-    logging::Category&  m_log;
-
-}; // CurlURLInputStream
-
-
-inline unsigned int CurlURLInputStream::curPos() const
-{
-    return fInputStream ? fInputStream->curPos() : 0;
-}
-
-};
-
-#endif // CURLURLINPUTSTREAM_HPP
index 8e07608..ffe55cf 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright 2001-2007 Internet2
- * 
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * DateTime.cpp
- * 
- * Manipulation of XML date/time data. 
+ *
+ * Manipulation of XML date/time data.
  */
 
 /*
 #endif
 
 #include <ctime>
+#include <sstream>
 #include <assert.h>
 #include <xercesc/util/Janitor.hpp>
 
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 //
@@ -245,7 +247,7 @@ void DateTime::addDuration(DateTime*             fNewDate
     temp = DATETIMES[index][Second] + fDuration->fValue[Second];
     carry = fQuotient (temp, 60);
     fNewDate->fValue[Second] =  mod(temp, 60, carry);
-               
+
     //add minutes
     temp = DATETIMES[index][Minute] + fDuration->fValue[Minute] + carry;
     carry = fQuotient(temp, 60);
@@ -255,7 +257,7 @@ void DateTime::addDuration(DateTime*             fNewDate
     temp = DATETIMES[index][Hour] + fDuration->fValue[Hour] + carry;
     carry = fQuotient(temp, 24);
     fNewDate->fValue[Hour] = mod(temp, 24, carry);
-               
+
     fNewDate->fValue[Day] =
         DATETIMES[index][Day] + fDuration->fValue[Day] + carry;
 
@@ -316,7 +318,7 @@ int DateTime::compareResult(int resultA
     }
 
     return resultA;
-       
+
 }
 
 // ---------------------------------------------------------------------------
@@ -346,7 +348,7 @@ int DateTime::compare(const DateTime* const pDate1
         return getRetVal(c1, c2);
     }
 
-    return XMLDateTime::INDETERMINATE; 
+    return XMLDateTime::INDETERMINATE;
 }
 
 int DateTime::compareResult(const DateTime* const pDate1
@@ -436,7 +438,7 @@ DateTime::DateTime(const XMLCh* const aString)
     setBuffer(aString);
 }
 
-DateTime::DateTime(time_t epoch)
+DateTime::DateTime(time_t epoch, bool duration)
 : fStart(0)
 , fEnd(0)
 , fBufferMaxLen(0)
@@ -444,16 +446,34 @@ DateTime::DateTime(time_t epoch)
 , fMiliSecond(0)
 , fHasTime(false)
 {
+    if (duration) {
+        ostringstream s;
+        if (epoch < 0) {
+            s << "-";
+            epoch = -epoch;
+        }
+        time_t days = epoch / 86400;
+        epoch %= 86400;
+        time_t hours = epoch / 3600;
+        epoch %= 3600;
+        time_t minutes = epoch / 60;
+        epoch %= 60;
+        s << "P" << days << "DT" << hours << "H" << minutes << "M" << epoch << "S";
+        auto_ptr_XMLCh timeptr(s.str().c_str());
+        setBuffer(timeptr.get());
+    }
+    else {
 #ifndef HAVE_GMTIME_R
-    struct tm* ptime=gmtime(&epoch);
+        struct tm* ptime=gmtime(&epoch);
 #else
-    struct tm res;
-    struct tm* ptime=gmtime_r(&epoch,&res);
+        struct tm res;
+        struct tm* ptime=gmtime_r(&epoch,&res);
 #endif
-    char timebuf[32];
-    strftime(timebuf,32,"%Y-%m-%dT%H:%M:%SZ",ptime);
-    auto_ptr_XMLCh timeptr(timebuf);
-    setBuffer(timeptr.get());
+        char timebuf[32];
+        strftime(timebuf,32,"%Y-%m-%dT%H:%M:%SZ",ptime);
+        auto_ptr_XMLCh timeptr(timebuf);
+        setBuffer(timeptr.get());
+    }
 }
 
 // -----------------------------------------------------------------------
@@ -497,25 +517,35 @@ const XMLCh*  DateTime::getFormattedString() const
 
 int DateTime::getSign() const
 {
-    return 0;
+    return fValue[utc];
 }
 
-time_t DateTime::getEpoch() const
+time_t DateTime::getEpoch(bool duration) const
 {
-    struct tm t;
-    t.tm_sec=getSecond();
-    t.tm_min=getMinute();
-    t.tm_hour=getHour();
-    t.tm_mday=getDay();
-    t.tm_mon=getMonth()-1;
-    t.tm_year=getYear()-1900;
-    t.tm_isdst=0;
+    if (duration) {
+        time_t epoch = getSecond() + (60 * getMinute()) + (3600 * getHour()) + (86400 * getDay());
+        if (getMonth())
+            epoch += (((365 * 4) + 1)/48 * 86400);
+        if (getYear())
+            epoch += 365.25 * 86400;
+        return getSign()!=UTC_NEG ? epoch : -epoch;
+    }
+    else {
+        struct tm t;
+        t.tm_sec=getSecond();
+        t.tm_min=getMinute();
+        t.tm_hour=getHour();
+        t.tm_mday=getDay();
+        t.tm_mon=getMonth()-1;
+        t.tm_year=getYear()-1900;
+        t.tm_isdst=0;
 #if defined(HAVE_TIMEGM)
-    return timegm(&t);
+        return timegm(&t);
 #else
-    // Windows, and hopefully most others...?
-    return mktime(&t) - timezone;
+        // Windows, and hopefully most others...?
+        return mktime(&t) - timezone;
 #endif
+    }
 }
 
 // ---------------------------------------------------------------------------
@@ -625,14 +655,14 @@ void DateTime::parseMonth()
     fValue[Day]      = DAY_DEFAULT;
     fValue[Month]    = parseInt(2, 4);
 
-    // REVISIT: allow both --MM and --MM-- now. 
-    // need to remove the following lines to disallow --MM-- 
-    // when the errata is officially in the rec. 
+    // REVISIT: allow both --MM and --MM-- now.
+    // need to remove the following lines to disallow --MM--
+    // when the errata is officially in the rec.
     fStart = 4;
-    if ( fEnd >= fStart+2 && fBuffer[fStart] == DATE_SEPARATOR && fBuffer[fStart+1] == DATE_SEPARATOR ) 
-    { 
-        fStart += 2; 
-    } 
+    if ( fEnd >= fStart+2 && fBuffer[fStart] == DATE_SEPARATOR && fBuffer[fStart+1] == DATE_SEPARATOR )
+    {
+        fStart += 2;
+    }
 
     //
     // parse TimeZone if any
@@ -702,7 +732,7 @@ void DateTime::parseMonthDay()
 
     //initialize
     fValue[CentYear] = YEAR_DEFAULT;
-    fValue[Month]    = parseInt(2, 4); 
+    fValue[Month]    = parseInt(2, 4);
     fValue[Day]      = parseInt(5, 7);
 
     if ( MONTHDAY_SIZE < fEnd )
@@ -855,9 +885,9 @@ void DateTime::parseDuration()
 
             /***
              * Schema Errata: E2-23
-             * at least one digit must follow the decimal point if it appears. 
-             * That is, the value of the seconds component must conform 
-             * to the following pattern: [0-9]+(.[0-9]+)? 
+             * at least one digit must follow the decimal point if it appears.
+             * That is, the value of the seconds component must conform
+             * to the following pattern: [0-9]+(.[0-9]+)?
              */
             if ( mlsec != NOT_FOUND )
             {
@@ -1072,9 +1102,9 @@ void DateTime::getTimeZone(const int sign)
         if ((sign + 1) != fEnd )
         {
             throw XMLParserException("Error in parsing time zone.");
-        }              
+        }
 
-        return;        
+        return;
     }
 
     //
@@ -1089,9 +1119,9 @@ void DateTime::getTimeZone(const int sign)
         throw XMLParserException("Error in parsing time zone.");
     }
 
-    fTimeZone[hh] = parseInt(sign+1, sign+3);          
+    fTimeZone[hh] = parseInt(sign+1, sign+3);
     fTimeZone[mm] = parseInt(sign+4, fEnd);
-                       
+
     return;
 }
 
@@ -1214,7 +1244,7 @@ void DateTime::validateDateTime() const
     {
         throw XMLParserException("Minute must have values 0-59");
     }
-       
+
     return;
 }
 
@@ -1332,15 +1362,15 @@ int DateTime::parseIntYear(const int end) const
  * E2-41
  *
  *  3.2.7.2 Canonical representation
- * 
- *  Except for trailing fractional zero digits in the seconds representation, 
- *  '24:00:00' time representations, and timezone (for timezoned values), 
- *  the mapping from literals to values is one-to-one. Where there is more 
- *  than one possible representation, the canonical representation is as follows: 
- *  redundant trailing zero digits in fractional-second literals are prohibited. 
+ *
+ *  Except for trailing fractional zero digits in the seconds representation,
+ *  '24:00:00' time representations, and timezone (for timezoned values),
+ *  the mapping from literals to values is one-to-one. Where there is more
+ *  than one possible representation, the canonical representation is as follows:
+ *  redundant trailing zero digits in fractional-second literals are prohibited.
  *  An hour representation of '24' is prohibited. Timezoned values are canonically
- *  represented by appending 'Z' to the nontimezoned representation. (All 
- *  timezoned dateTime values are UTC.) 
+ *  represented by appending 'Z' to the nontimezoned representation. (All
+ *  timezoned dateTime values are UTC.)
  *
  *  .'24:00:00' -> '00:00:00'
  *  .milisecond: trailing zeros removed
@@ -1402,8 +1432,8 @@ XMLCh* DateTime::getDateTimeCanonicalRepresentation() const
 /***
  * 3.2.8 time
  *
- *  . either the time zone must be omitted or, 
- *    if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z".   
+ *  . either the time zone must be omitted or,
+ *    if present, the time zone must be Coordinated Universal Time (UTC) indicated by a "Z".
  *
  *  . Additionally, the canonical representation for midnight is 00:00:00.
  *
@@ -1450,7 +1480,7 @@ void DateTime::fillString(XMLCh*& ptr, valueIndex ind, int expLen) const
     XMLCh strBuffer[16];
     assert(expLen < 16);
     XMLString::binToText(fValue[ind], strBuffer, expLen, 10);
-    int   actualLen = XMLString::stringLen(strBuffer);
+    int   actualLen = (int) XMLString::stringLen(strBuffer);
     int   i;
     //append leading zeros
     for (i = 0; i < expLen - actualLen; i++)
@@ -1470,7 +1500,7 @@ int DateTime::fillYearString(XMLCh*& ptr, valueIndex ind) const
     XMLCh strBuffer[16];
     // let's hope we get no years of 15 digits...
     XMLString::binToText(fValue[ind], strBuffer, 15, 10);
-    int   actualLen = XMLString::stringLen(strBuffer);
+    int   actualLen = (int) XMLString::stringLen(strBuffer);
     // don't forget that years can be negative...
     int negativeYear = 0;
     if(strBuffer[0] == chDash)
index dead345..b3fa78f 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright 2001-2007 Internet2
- * 
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * @file xmltooling/util/DateTime.h
- * 
- * Manipulation of XML date/time data. 
+ *
+ * Manipulation of XML date/time data.
  */
 
 #ifndef __xmltool_datetime_h__
@@ -40,7 +40,7 @@ namespace xmltooling
 {
     /**
      * Class for manipulating XML date/time information.
-     * 
+     *
      * This is mostly copied from Xerces-C, but they haven't produced a usable date/time
      * class, so we had to incorporate a version of it for now. It can't be inherited
      * since the fields needed are private.
@@ -51,20 +51,20 @@ namespace xmltooling
         /// @cond OFF
         DateTime();
         DateTime(const XMLCh* const);
-        DateTime(time_t epoch);
+        DateTime(time_t epoch, bool duration=false);
         DateTime(const DateTime&);
         DateTime& operator=(const DateTime&);
         ~DateTime();
-    
+
         inline void setBuffer(const XMLCh* const);
-    
+
         const XMLCh* getRawData() const;
         const XMLCh* getFormattedString() const;
         int getSign() const;
-    
+
         XMLCh* getDateTimeCanonicalRepresentation() const;
         XMLCh* getTimeCanonicalRepresentation() const;
-    
+
         void parseDateTime();
         void parseDate();
         void parseTime();
@@ -74,19 +74,19 @@ namespace xmltooling
         void parseMonthDay();
         void parseYearMonth();
         void parseDuration();
-    
+
         static int compare(const DateTime* const, const DateTime* const);
         static int compare(const DateTime* const, const DateTime* const, bool);
-        static int compareOrder(const DateTime* const, const DateTime* const);                                    
-    
+        static int compareOrder(const DateTime* const, const DateTime* const);
+
         int getYear() const {return fValue[CentYear];}
         int getMonth() const {return fValue[Month];}
         int getDay() const {return fValue[Day];}
         int getHour() const {return fValue[Hour];}
         int getMinute() const {return fValue[Minute];}
         int getSecond() const {return fValue[Second];}
-        time_t getEpoch() const;
-    
+        time_t getEpoch(bool duration=false) const;
+
         /// @endcond
     private:
         enum valueIndex {
@@ -100,52 +100,52 @@ namespace xmltooling
             utc        ,
             TOTAL_SIZE
         };
-    
+
         enum utcType {
             UTC_UNKNOWN = 0,
             UTC_STD        ,          // set in parse() or normalize()
             UTC_POS        ,          // set in parse()
             UTC_NEG                   // set in parse()
         };
-    
+
         enum timezoneIndex {
             hh = 0,
             mm ,
             TIMEZONE_ARRAYSIZE
         };
-    
+
         static int compareResult(int, int, bool);
         static void addDuration(DateTime* pDuration, const DateTime* const pBaseDate, int index);
         static int compareResult(const DateTime* const, const DateTime* const, bool, int);
         static inline int getRetVal(int, int);
-    
+
         inline void reset();
         //inline void assertBuffer() const;
         inline void copy(const DateTime&);
-        
+
         inline void initParser();
         inline bool isNormalized() const;
-    
+
         void getDate();
         void getTime();
         void getYearMonth();
         void getTimeZone(const int);
         void parseTimeZone();
-    
+
         int findUTCSign(const int start);
         int indexOf(const int start, const int end, const XMLCh ch) const;
         int parseInt(const int start, const int end) const;
         int parseIntYear(const int end) const;
         double parseMiliSecond(const int start, const int end) const;
-    
+
         void validateDateTime() const;
         void normalize();
         void fillString(XMLCh*& ptr, valueIndex ind, int expLen) const;
         int  fillYearString(XMLCh*& ptr, valueIndex ind) const;
         void searchMiliSeconds(XMLCh*& miliStartPtr, XMLCh*& miliEndPtr) const;
-    
+
        bool operator==(const DateTime& toCompare) const;
-    
+
         static const int DATETIMES[][TOTAL_SIZE];
         int fValue[TOTAL_SIZE];
         int fTimeZone[TIMEZONE_ARRAYSIZE];
@@ -153,7 +153,7 @@ namespace xmltooling
         int fEnd;
         int fBufferMaxLen;
         XMLCh* fBuffer;
-    
+
         double fMiliSecond;
         bool fHasTime;
     };
@@ -161,7 +161,7 @@ namespace xmltooling
     inline void DateTime::setBuffer(const XMLCh* const aString)
     {
         reset();
-        fEnd = xercesc::XMLString::stringLen(aString);
+        fEnd = (int) xercesc::XMLString::stringLen(aString);
         if (fEnd > 0) {
             if (fEnd > fBufferMaxLen) {
                 delete[] fBuffer;
@@ -171,33 +171,33 @@ namespace xmltooling
             memcpy(fBuffer, aString, (fEnd+1) * sizeof(XMLCh));
         }
     }
-    
+
     inline void DateTime::reset()
     {
         for ( int i=0; i < xercesc::XMLDateTime::TOTAL_SIZE; i++ )
             fValue[i] = 0;
-    
+
         fMiliSecond   = 0;
         fHasTime      = false;
         fTimeZone[hh] = fTimeZone[mm] = 0;
         fStart = fEnd = 0;
-    
+
         if (fBuffer)
             *fBuffer = 0;
     }
-    
+
     inline void DateTime::copy(const DateTime& rhs)
     {
         for ( int i = 0; i < xercesc::XMLDateTime::TOTAL_SIZE; i++ )
             fValue[i] = rhs.fValue[i];
-    
+
         fMiliSecond   = rhs.fMiliSecond;
         fHasTime      = rhs.fHasTime;
         fTimeZone[hh] = rhs.fTimeZone[hh];
         fTimeZone[mm] = rhs.fTimeZone[mm];
         fStart = rhs.fStart;
         fEnd   = rhs.fEnd;
-    
+
         if (fEnd > 0) {
             if (fEnd > fBufferMaxLen) {
                 delete[] fBuffer;
@@ -207,24 +207,24 @@ namespace xmltooling
             memcpy(fBuffer, rhs.fBuffer, (fEnd+1) * sizeof(XMLCh));
         }
     }
-    
+
     inline void DateTime::initParser()
     {
         fStart = 0;   // to ensure scan from the very first beginning
                       // in case the pointer is updated accidentally by someone else.
     }
-    
+
     inline bool DateTime::isNormalized() const
     {
         return (fValue[xercesc::XMLDateTime::utc] == xercesc::XMLDateTime::UTC_STD ? true : false);
     }
-    
+
     inline int DateTime::getRetVal(int c1, int c2)
     {
         if ((c1 == xercesc::XMLDateTime::LESS_THAN && c2 == xercesc::XMLDateTime::GREATER_THAN) ||
             (c1 == xercesc::XMLDateTime::GREATER_THAN && c2 == xercesc::XMLDateTime::LESS_THAN))
             return xercesc::XMLDateTime::INDETERMINATE;
-    
+
         return (c1 != xercesc::XMLDateTime::INDETERMINATE) ? c1 : c2;
     }
 
index 17133b3..25e4324 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2008 Internet2
+ *
  * 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
 
 /**
  * ParserPool.cpp
- * 
- * XML parsing
+ *
+ * A thread-safe pool of parsers that share characteristics.
  */
 
 #include "internal.h"
 #include "exceptions.h"
 #include "logging.h"
+#include "util/CurlURLInputStream.h"
 #include "util/NDC.h"
 #include "util/ParserPool.h"
 #include "util/XMLHelper.h"
 
 using namespace xmltooling::logging;
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
+
+namespace {
+    class MyErrorHandler : public DOMErrorHandler {
+    public:
+        unsigned int errors;
+
+        MyErrorHandler() : errors(0) {}
+
+        bool handleError(const DOMError& e)
+        {
+#ifdef _DEBUG
+            xmltooling::NDC ndc("handleError");
+#endif
+            Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
+
+            DOMLocator* locator=e.getLocation();
+            auto_ptr_char temp(e.getMessage());
+
+            switch (e.getSeverity()) {
+                case DOMError::DOM_SEVERITY_WARNING:
+                    log.warnStream() << "warning on line " << locator->getLineNumber()
+                        << ", column " << locator->getColumnNumber()
+                        << ", message: " << temp.get() << logging::eol;
+                    return true;
+
+                case DOMError::DOM_SEVERITY_ERROR:
+                    ++errors;
+                    log.errorStream() << "error on line " << locator->getLineNumber()
+                        << ", column " << locator->getColumnNumber()
+                        << ", message: " << temp.get() << logging::eol;
+                    return true;
+
+                case DOMError::DOM_SEVERITY_FATAL_ERROR:
+                    ++errors;
+                    log.errorStream() << "fatal error on line " << locator->getLineNumber()
+                        << ", column " << locator->getColumnNumber()
+                        << ", message: " << temp.get() << logging::eol;
+                    return true;
+            }
+
+            ++errors;
+            log.errorStream() << "undefined error type on line " << locator->getLineNumber()
+                << ", column " << locator->getColumnNumber()
+                << ", message: " << temp.get() << logging::eol;
+            return false;
+        }
+    };
+}
+
+
 ParserPool::ParserPool(bool namespaceAware, bool schemaAware)
     : m_namespaceAware(namespaceAware), m_schemaAware(schemaAware), m_lock(Mutex::create()), m_security(new SecurityManager()) {}
 
@@ -60,26 +112,78 @@ DOMDocument* ParserPool::newDocument()
     return DOMImplementationRegistry::getDOMImplementation(NULL)->createDocument();
 }
 
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+
+DOMDocument* ParserPool::parse(DOMLSInput& domsrc)
+{
+    DOMLSParser* parser=checkoutBuilder();
+    XercesJanitor<DOMLSParser> janitor(parser);
+    try {
+        MyErrorHandler deh;
+        parser->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, dynamic_cast<DOMErrorHandler*>(&deh));
+        DOMDocument* doc=parser->parse(&domsrc);
+        if (deh.errors) {
+            if (doc)
+                doc->release();
+            throw XMLParserException("XML error(s) during parsing, check log for specifics");
+        }
+        parser->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, (void*)NULL);
+        parser->getDomConfig()->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);
+        checkinBuilder(janitor.release());
+        return doc;
+    }
+    catch (XMLException& ex) {
+        parser->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, (void*)NULL);
+        parser->getDomConfig()->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);
+        checkinBuilder(janitor.release());
+        auto_ptr_char temp(ex.getMessage());
+        throw XMLParserException(string("Xerces error during parsing: ") + (temp.get() ? temp.get() : "no message"));
+    }
+    catch (XMLToolingException&) {
+        parser->getDomConfig()->setParameter(XMLUni::fgDOMErrorHandler, (void*)NULL);
+        parser->getDomConfig()->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);
+        checkinBuilder(janitor.release());
+        throw;
+    }
+}
+
+#else
+
 DOMDocument* ParserPool::parse(DOMInputSource& domsrc)
 {
     DOMBuilder* parser=checkoutBuilder();
     XercesJanitor<DOMBuilder> janitor(parser);
     try {
+        MyErrorHandler deh;
+        parser->setErrorHandler(&deh);
         DOMDocument* doc=parser->parse(domsrc);
-        parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);
+        if (deh.errors) {
+            if (doc)
+                doc->release();
+            throw XMLParserException("XML error(s) during parsing, check log for specifics");
+        }
+        parser->setErrorHandler(NULL);
+        parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument, true);
         checkinBuilder(janitor.release());
         return doc;
     }
-    catch (XMLException&) {
+    catch (XMLException& ex) {
+        parser->setErrorHandler(NULL);
+        parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument, true);
         checkinBuilder(janitor.release());
-        throw;
+        auto_ptr_char temp(ex.getMessage());
+        throw XMLParserException(string("Xerces error during parsing: ") + (temp.get() ? temp.get() : "no message"));
     }
     catch (XMLToolingException&) {
+        parser->setErrorHandler(NULL);
+        parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument, true);
         checkinBuilder(janitor.release());
         throw;
     }
 }
 
+#endif
+
 DOMDocument* ParserPool::parse(istream& is)
 {
     StreamInputSource src(is);
@@ -100,7 +204,7 @@ public:
 bool ParserPool::loadSchema(const XMLCh* nsURI, const XMLCh* pathname)
 {
     // Just check the pathname and then directly register the pair into the map.
-    
+
     auto_ptr_char p(pathname);
 #ifdef WIN32
     struct _stat stat_buf;
@@ -120,16 +224,9 @@ bool ParserPool::loadSchema(const XMLCh* nsURI, const XMLCh* pathname)
     }
 
     Lock lock(m_lock);
-#ifdef HAVE_GOOD_STL
     m_schemaLocMap[nsURI]=pathname;
     m_schemaLocations.erase();
     for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));
-#else
-    auto_ptr_char n(nsURI);
-    m_schemaLocMap[n.get()]=p.get();
-    m_schemaLocations.erase();
-    for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));
-#endif
 
     return true;
 }
@@ -169,7 +266,7 @@ bool ParserPool::loadCatalog(const XMLCh* pathname)
     try {
         DOMDocument* doc=XMLToolingConfig::getConfig().getParser().parse(domsrc);
         XercesJanitor<DOMDocument> janitor(doc);
-        
+
         // Check root element.
         const DOMElement* root=doc->getDocumentElement();
         if (!XMLHelper::isNodeNamed(root,CATALOG_NS,catalog)) {
@@ -177,7 +274,7 @@ bool ParserPool::loadCatalog(const XMLCh* pathname)
             log.error("unknown root element, failed to load XML catalog from %s", temp.get());
             return false;
         }
-        
+
         // Fetch all the <system> elements.
         DOMNodeList* mappings=root->getElementsByTagNameNS(CATALOG_NS,system);
         Lock lock(m_lock);
@@ -185,20 +282,10 @@ bool ParserPool::loadCatalog(const XMLCh* pathname)
             root=static_cast<DOMElement*>(mappings->item(i));
             const XMLCh* from=root->getAttributeNS(NULL,systemId);
             const XMLCh* to=root->getAttributeNS(NULL,uri);
-#ifdef HAVE_GOOD_STL
             m_schemaLocMap[from]=to;
-#else
-            auto_ptr_char f(from);
-            auto_ptr_char t(to);
-            m_schemaLocMap[f.get()]=t.get();
-#endif
         }
         m_schemaLocations.erase();
-#ifdef HAVE_GOOD_STL
         for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<xstring>(m_schemaLocations,chSpace));
-#else
-        for_each(m_schemaLocMap.begin(),m_schemaLocMap.end(),doubleit<string>(m_schemaLocations,' '));
-#endif
     }
     catch (exception& e) {
         log.error("catalog loader caught exception: %s", e.what());
@@ -208,7 +295,19 @@ bool ParserPool::loadCatalog(const XMLCh* pathname)
     return true;
 }
 
-DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI)
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+DOMLSInput* ParserPool::resolveResource(
+            const XMLCh *const resourceType,
+            const XMLCh *const namespaceUri,
+            const XMLCh *const publicId,
+            const XMLCh *const systemId,
+            const XMLCh *const baseURI
+            )
+#else
+DOMInputSource* ParserPool::resolveEntity(
+    const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI
+    )
+#endif
 {
 #if _DEBUG
     xmltooling::NDC ndc("resolveEntity");
@@ -223,7 +322,6 @@ DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XML
         log.debug("asked to resolve %s with baseURI %s",sysId.get(),base.get() ? base.get() : "(null)");
     }
 
-#ifdef HAVE_GOOD_STL
     // Find well-known schemas in the specified location.
     map<xstring,xstring>::const_iterator i=m_schemaLocMap.find(systemId);
     if (i!=m_schemaLocMap.end())
@@ -238,93 +336,83 @@ DOMInputSource* ParserPool::resolveEntity(const XMLCh* const publicId, const XML
     // We'll allow anything without embedded slashes.
     if (XMLString::indexOf(systemId, chForwardSlash)==-1)
         return new Wrapper4InputSource(new LocalFileInputSource(baseURI,systemId));
-#else
-    // Find well-known schemas in the specified location.
-    auto_ptr_char temp(systemId);
-    map<string,string>::const_iterator i=m_schemaLocMap.find(temp.get());
-    if (i!=m_schemaLocMap.end()) {
-        auto_ptr_XMLCh temp2(i->second.c_str());
-        return new Wrapper4InputSource(new LocalFileInputSource(baseURI,temp2.get()));
-    }
-
-    // Check for entity as a value in the map.
-    for (i=m_schemaLocMap.begin(); i!=m_schemaLocMap.end(); ++i) {
-        auto_ptr_XMLCh temp2(i->second.c_str());
-        if (XMLString::endsWith(temp2.get(), systemId))
-            return new Wrapper4InputSource(new LocalFileInputSource(baseURI,temp2.get()));
-    }
-
-    // We'll allow anything without embedded slashes.
-    if (XMLString::indexOf(systemId, chForwardSlash)==-1)
-        return new Wrapper4InputSource(new LocalFileInputSource(baseURI,systemId));
-#endif    
 
     // Shortcircuit the request.
-#ifdef HAVE_GOOD_STL
     auto_ptr_char temp(systemId);
-#endif
     log.debug("unauthorized entity request (%s), blocking it", temp.get());
     static const XMLByte nullbuf[] = {0};
     return new Wrapper4InputSource(new MemBufInputSource(nullbuf,0,systemId));
 }
 
-bool ParserPool::handleError(const DOMError& e)
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+
+DOMLSParser* ParserPool::createBuilder()
 {
-#ifdef _DEBUG
-    xmltooling::NDC ndc("handleError");
-#endif
-    Category& log=Category::getInstance(XMLTOOLING_LOGCAT".ParserPool");
-    DOMLocator* locator=e.getLocation();
-    auto_ptr_char temp(e.getMessage());
+    static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
+    DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
+    DOMLSParser* parser=static_cast<DOMImplementationLS*>(impl)->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS,NULL);
+    parser->getDomConfig()->setParameter(XMLUni::fgDOMNamespaces, m_namespaceAware);
+    if (m_schemaAware) {
+        parser->getDomConfig()->setParameter(XMLUni::fgDOMNamespaces, true);
+        parser->getDomConfig()->setParameter(XMLUni::fgXercesSchema, true);
+        parser->getDomConfig()->setParameter(XMLUni::fgDOMValidate, true);
+        parser->getDomConfig()->setParameter(XMLUni::fgXercesCacheGrammarFromParse, true);
 
-    switch (e.getSeverity()) {
-        case DOMError::DOM_SEVERITY_WARNING:
-            log.warnStream() << "warning on line " << locator->getLineNumber()
-                << ", column " << locator->getColumnNumber()
-                << ", message: " << temp.get() << logging::eol;
-            return true;
+        // We build a "fake" schema location hint that binds each namespace to itself.
+        // This ensures the entity resolver will be given the namespace as a systemId it can check.
+        parser->getDomConfig()->setParameter(XMLUni::fgXercesSchemaExternalSchemaLocation, const_cast<XMLCh*>(m_schemaLocations.c_str()));
+    }
+    parser->getDomConfig()->setParameter(XMLUni::fgXercesUserAdoptsDOMDocument, true);
+    parser->getDomConfig()->setParameter(XMLUni::fgXercesDisableDefaultEntityResolution, true);
+    parser->getDomConfig()->setParameter(XMLUni::fgDOMResourceResolver, dynamic_cast<DOMLSResourceResolver*>(this));
+    parser->getDomConfig()->setParameter(XMLUni::fgXercesSecurityManager, m_security);
+    return parser;
+}
 
-        case DOMError::DOM_SEVERITY_ERROR:
-            log.errorStream() << "error on line " << locator->getLineNumber()
-                << ", column " << locator->getColumnNumber()
-                << ", message: " << temp.get() << logging::eol;
-            throw XMLParserException(string("error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+DOMLSParser* ParserPool::checkoutBuilder()
+{
+    Lock lock(m_lock);
+    if (m_pool.empty()) {
+        DOMLSParser* builder=createBuilder();
+        return builder;
+    }
+    DOMLSParser* p=m_pool.top();
+    m_pool.pop();
+    if (m_schemaAware)
+        p->getDomConfig()->setParameter(XMLUni::fgXercesSchemaExternalSchemaLocation, const_cast<XMLCh*>(m_schemaLocations.c_str()));
+    return p;
+}
 
-        case DOMError::DOM_SEVERITY_FATAL_ERROR:
-            log.errorStream() << "fatal error on line " << locator->getLineNumber()
-                << ", column " << locator->getColumnNumber()
-                << ", message: " << temp.get() << logging::eol;
-            throw XMLParserException(string("fatal error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
+void ParserPool::checkinBuilder(DOMLSParser* builder)
+{
+    if (builder) {
+        Lock lock(m_lock);
+        m_pool.push(builder);
     }
-    throw XMLParserException(string("unclassified error during XML parsing: ") + (temp.get() ? temp.get() : "no message"));
 }
 
+#else
+
 DOMBuilder* ParserPool::createBuilder()
 {
     static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
     DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
     DOMBuilder* parser=static_cast<DOMImplementationLS*>(impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS,0);
-    if (m_namespaceAware)
-        parser->setFeature(XMLUni::fgDOMNamespaces,true);
+    parser->setFeature(XMLUni::fgDOMNamespaces, m_namespaceAware);
     if (m_schemaAware) {
-        parser->setFeature(XMLUni::fgXercesSchema,true);
-        parser->setFeature(XMLUni::fgDOMValidation,true);
-        parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse,true);
-        parser->setFeature(XMLUni::fgXercesValidationErrorAsFatal,true);
-        
+        parser->setFeature(XMLUni::fgDOMNamespaces, true);
+        parser->setFeature(XMLUni::fgXercesSchema, true);
+        parser->setFeature(XMLUni::fgDOMValidation, true);
+        parser->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true);
+
         // We build a "fake" schema location hint that binds each namespace to itself.
-        // This ensures the entity resolver will be given the namespace as a systemId it can check. 
-#ifdef HAVE_GOOD_STL
+        // This ensures the entity resolver will be given the namespace as a systemId it can check.
         parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));
-#else
-        auto_ptr_XMLCh temp(m_schemaLocations.c_str());
-        parser->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp.get()));
-#endif
     }
     parser->setProperty(XMLUni::fgXercesSecurityManager, m_security);
-    parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument,true);
+    parser->setFeature(XMLUni::fgXercesUserAdoptsDOMDocument, true);
+    parser->setFeature(XMLUni::fgXercesDisableDefaultEntityResolution, true);
     parser->setEntityResolver(this);
-    parser->setErrorHandler(this);
     return parser;
 }
 
@@ -337,14 +425,8 @@ DOMBuilder* ParserPool::checkoutBuilder()
     }
     DOMBuilder* p=m_pool.top();
     m_pool.pop();
-    if (m_schemaAware) {
-#ifdef HAVE_GOOD_STL
+    if (m_schemaAware)
         p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(m_schemaLocations.c_str()));
-#else
-        auto_ptr_XMLCh temp2(m_schemaLocations.c_str());
-        p->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation,const_cast<XMLCh*>(temp2.get()));
-#endif
-    }
     return p;
 }
 
@@ -356,10 +438,12 @@ void ParserPool::checkinBuilder(DOMBuilder* builder)
     }
 }
 
-unsigned int StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const toFill, const unsigned int maxToRead)
+#endif
+
+xsecsize_t StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const toFill, const xsecsize_t maxToRead)
 {
     XMLByte* target=toFill;
-    unsigned int bytes_read=0,request=maxToRead;
+    xsecsize_t bytes_read=0,request=maxToRead;
 
     // Fulfill the rest by reading from the stream.
     if (request && !m_is.eof() && !m_is.fail()) {
@@ -378,3 +462,49 @@ unsigned int StreamInputSource::StreamBinInputStream::readBytes(XMLByte* const t
     }
     return bytes_read;
 }
+
+#ifdef XMLTOOLING_LITE
+
+URLInputSource::URLInputSource(const XMLCh* url, const char* systemId) : InputSource(systemId), m_url(url)
+{
+}
+
+URLInputSource::URLInputSource(const DOMElement* e, const char* systemId) : InputSource(systemId)
+{
+    static const XMLCh uri[] = UNICODE_LITERAL_3(u,r,i);
+    static const XMLCh url[] = UNICODE_LITERAL_3(u,r,l);
+
+    const XMLCh* attr = e->getAttributeNS(NULL, url);
+    if (!attr || !*attr) {
+        attr = e->getAttributeNS(NULL, uri);
+        if (!attr || !*attr)
+            throw IOException("No URL supplied via DOM to URLInputSource constructor.");
+    }
+
+    m_url.setURL(attr);
+}
+
+BinInputStream* URLInputSource::makeStream() const
+{
+    // Ask the URL to create us an appropriate input stream
+    return m_url.makeNewStream();
+}
+
+#else
+
+URLInputSource::URLInputSource(const XMLCh* url, const char* systemId)
+    : InputSource(systemId), m_url(url), m_root(NULL)
+{
+}
+
+URLInputSource::URLInputSource(const DOMElement* e, const char* systemId)
+    : InputSource(systemId), m_root(e)
+{
+}
+
+BinInputStream* URLInputSource::makeStream() const
+{
+    return m_root ? new CurlURLInputStream(m_root) : new CurlURLInputStream(m_url.get());
+}
+
+#endif
index 3dcdde6..e901a02 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2008 Internet2
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * @file xmltooling/util/ParserPool.h
- * 
- * A thread-safe pool of DOMBuilders that share characteristics.
+ *
+ * A thread-safe pool of parsers that share characteristics.
  */
 
 #ifndef __xmltooling_pool_h__
 #include <xercesc/sax/InputSource.hpp>
 #include <xercesc/util/BinInputStream.hpp>
 #include <xercesc/util/SecurityManager.hpp>
+#include <xercesc/util/XMLURL.hpp>
+
+#ifndef XMLTOOLING_NO_XMLSEC
+# include <xsec/framework/XSECDefs.hpp>
+#endif
 
 #if defined (_MSC_VER)
     #pragma warning( push )
@@ -44,13 +49,18 @@ namespace xmltooling {
     /**
      * A thread-safe pool of DOMBuilders that share characteristics.
      */
-    class XMLTOOL_API ParserPool : public xercesc::DOMEntityResolver, xercesc::DOMErrorHandler
+    class XMLTOOL_API ParserPool :
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+        public xercesc::DOMLSResourceResolver
+#else
+        public xercesc::DOMEntityResolver
+#endif
     {
         MAKE_NONCOPYABLE(ParserPool);
     public:
         /**
          * Constructs a new pool
-         * 
+         *
          * @param namespaceAware    indicates whether parsers should be namespace-aware or not
          * @param schemaAware       indicates whether parsers should be schema-validating or not
          */
@@ -59,24 +69,30 @@ namespace xmltooling {
 
         /**
          * Creates a new document using a parser from this pool.
-         * 
+         *
          * @return new XML document
-         * 
+         *
          */
         xercesc::DOMDocument* newDocument();
 
         /**
          * Parses a document using a pooled parser with the proper settings
-         * 
-         * @param domsrc A DOM source containing the content to be parsed
+         *
+         * @param domsrc An input source containing the content to be parsed
          * @return The DOM document resulting from the parse
          * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML
          */
-        xercesc::DOMDocument* parse(xercesc::DOMInputSource& domsrc);
+        xercesc::DOMDocument* parse(
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+            xercesc::DOMLSInput& domsrc
+#else
+            xercesc::DOMInputSource& domsrc
+#endif
+            );
 
         /**
          * Parses a document using a pooled parser with the proper settings
-         * 
+         *
          * @param is An input stream containing the content to be parsed
          * @return The DOM document resulting from the parse
          * @throws XMLParserException thrown if there was a problem reading, parsing, or validating the XML
@@ -85,21 +101,21 @@ namespace xmltooling {
 
         /**
          * Load an OASIS catalog file to map schema namespace URIs to filenames.
-         * 
+         *
          * This does not provide real catalog support; only the &lt;uri&gt; element
          * is supported to map from a namespace URI to a relative path or file:// URI.
-         * 
+         *
          * @param pathname  path to a catalog file
          * @return true iff the catalog was successfully processed
          */
         bool loadCatalog(const XMLCh* pathname);
-        
+
         /**
          * Load a schema explicitly from a local file.
-         * 
+         *
          * Note that "successful processing" does not imply that the schema is valid,
          * only that a reference to it was successfully registered with the pool.
-         * 
+         *
          * @param nsURI     XML namespace to load
          * @param pathname  path to schema file
          * @return true iff the schema was successfully processed
@@ -109,27 +125,40 @@ namespace xmltooling {
         /**
          * Supplies all external entities (primarily schemas) to the parser
          */
-        xercesc::DOMInputSource* resolveEntity(const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI);
-
-        /**
-         * Handles parsing errors
-         */
-        bool handleError(const xercesc::DOMError& e);
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+        xercesc::DOMLSInput* resolveResource(
+            const XMLCh *const resourceType,
+            const XMLCh *const namespaceUri,
+            const XMLCh *const publicId,
+            const XMLCh *const systemId,
+            const XMLCh *const baseURI
+            );
+#else
+        xercesc::DOMInputSource* resolveEntity(
+            const XMLCh* const publicId, const XMLCh* const systemId, const XMLCh* const baseURI
+            );
+#endif
 
     private:
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+        xercesc::DOMLSParser* createBuilder();
+        xercesc::DOMLSParser* checkoutBuilder();
+        void checkinBuilder(xercesc::DOMLSParser* builder);
+#else
         xercesc::DOMBuilder* createBuilder();
         xercesc::DOMBuilder* checkoutBuilder();
         void checkinBuilder(xercesc::DOMBuilder* builder);
+#endif
 
-#ifdef HAVE_GOOD_STL
         xstring m_schemaLocations;
         std::map<xstring,xstring> m_schemaLocMap;
-#else
-        std::string m_schemaLocations;
-        std::map<std::string,std::string> m_schemaLocMap;
-#endif
+
         bool m_namespaceAware,m_schemaAware;
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+        std::stack<xercesc::DOMLSParser*> m_pool;
+#else
         std::stack<xercesc::DOMBuilder*> m_pool;
+#endif
         Mutex* m_lock;
         xercesc::SecurityManager* m_security;
     };
@@ -143,7 +172,7 @@ namespace xmltooling {
     public:
         /**
          * Constructs an input source around an input stream reference.
-         * 
+         *
          * @param is        reference to an input stream
          * @param systemId  optional system identifier to attach to the stream
          */
@@ -160,22 +189,75 @@ namespace xmltooling {
         public:
             /**
              * Constructs a Xerces input stream around a C++ input stream reference.
-             * 
-             * @param is        reference to an input stream
+             *
+             * @param is            reference to an input stream
              */
             StreamBinInputStream(std::istream& is) : m_is(is), m_pos(0) {}
             /// @cond off
-            virtual unsigned int curPos() const { return m_pos; }
-            virtual unsigned int readBytes(XMLByte* const toFill, const unsigned int maxToRead);
+#ifdef XMLTOOLING_XERCESC_64BITSAFE
+            XMLFilePos
+#else
+            unsigned int
+#endif
+                curPos() const { return m_pos; }
+            xsecsize_t readBytes(XMLByte* const toFill, const xsecsize_t maxToRead);
+#ifdef XMLTOOLING_XERCESC_64BITSAFE
+            const XMLCh* getContentType() const { return NULL; }
+#endif
             /// @endcond
         private:
             std::istream& m_is;
-            unsigned int m_pos;
+            xsecsize_t m_pos;
         };
 
     private:
         std::istream& m_is;
     };
+
+    /**
+     * A URL-based parser source that supports a more advanced input stream.
+     */
+    class XMLTOOL_API URLInputSource : public xercesc::InputSource
+    {
+    MAKE_NONCOPYABLE(URLInputSource);
+    public:
+        /**
+         * Constructor.
+         *
+         * @param url       source of input
+         * @param systemId  optional system identifier to attach to the source
+         */
+        URLInputSource(const XMLCh* url, const char* systemId=NULL);
+
+        /**
+         * Constructor taking a DOM element supporting the following content:
+         *
+         * <dl>
+         *  <dt>uri | url</dt>
+         *  <dd>identifies the remote resource</dd>
+         *  <dt>verifyHost</dt>
+         *  <dd>true iff name of host should be matched against TLS/SSL certificate</dd>
+         *  <dt>TransportOption elements, like so:</dt>
+         *  <dd>&lt;TransportOption provider="CURL" option="150"&gt;0&lt;/TransportOption&gt;</dd>
+         * </dl>
+         *
+         * @param e         DOM to supply configuration
+         * @param systemId  optional system identifier to attach to the source
+         */
+        URLInputSource(const xercesc::DOMElement* e, const char* systemId=NULL);
+
+        /// @cond off
+        virtual xercesc::BinInputStream* makeStream() const;
+        /// @endcond
+
+    private:
+#ifdef XMLTOOLING_LITE
+        xercesc::XMLURL m_url;
+#else
+        xmltooling::auto_ptr_char m_url;
+        const xercesc::DOMElement* m_root;
+#endif
+    };
 };
 
 #if defined (_MSC_VER)
index f4d4975..e25000f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2009 Internet2
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 using namespace xmltooling;
 using namespace std;
 
+PathResolver::PathResolver() : m_defaultPackage(PACKAGE_NAME), m_defaultPrefix("/usr")
+{
+    setLibDir("/usr/lib");
+    setLogDir("/var/log");
+    setXMLDir("/usr/share/xml");
+    setRunDir("/var/run");
+    setCfgDir("/etc");
+}
+
 const string& PathResolver::resolve(string& s, file_type_t filetype, const char* pkgname, const char* prefix) const
 {
     if (!isAbsolute(s.c_str())) {
         switch (filetype) {
             case XMLTOOLING_LIB_FILE:
-                s = string(prefix ? prefix : m_defaultPrefix) +
-#if (SIZEOF_LONG == 8)
-                    "/lib64/"
-#else
-                    "/lib/"
-#endif
-                    + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                s = m_lib + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                if (!isAbsolute(m_lib.c_str()))
+                    s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
                 break;
 
             case XMLTOOLING_LOG_FILE:
-                if (prefix || m_defaultPrefix != "/usr")
-                    s = string(prefix ? prefix : m_defaultPrefix) + "/var/log/" + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
-                else
-                    s = string("/var/log/") + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                s = m_log + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                if (!isAbsolute(m_log.c_str())) {
+                    if (prefix || m_defaultPrefix != "/usr")
+                        s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
+                    else
+                        s = string("/") + s;
+                }
                 break;
 
             case XMLTOOLING_XML_FILE:
-                s = string(prefix ? prefix : m_defaultPrefix) + "/share/xml/" + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                s = m_xml + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                if (!isAbsolute(m_xml.c_str()))
+                    s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
                 break;
 
             case XMLTOOLING_RUN_FILE:
-                if (prefix || m_defaultPrefix != "/usr")
-                    s = string(prefix ? prefix : m_defaultPrefix) + "/var/run/" + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
-                else
-                    s = string("/var/run/") + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                s = m_run + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                if (!isAbsolute(m_run.c_str())) {
+                    if (prefix || m_defaultPrefix != "/usr")
+                        s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
+                    else
+                        s = string("/") + s;
+                }
                 break;
 
             case XMLTOOLING_CFG_FILE:
-                if (prefix || m_defaultPrefix != "/usr")
-                    s = string(prefix ? prefix : m_defaultPrefix) + "/etc/" + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
-                else
-                    s = string("/etc/") + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                s = m_cfg + '/' + (pkgname ? pkgname : m_defaultPackage) + '/' + s;
+                if (!isAbsolute(m_cfg.c_str())) {
+                    if (prefix || m_defaultPrefix != "/usr")
+                        s = string(prefix ? prefix : m_defaultPrefix) + '/' + s;
+                    else
+                        s = string("/") + s;
+                }
                 break;
 
             default:
index 23f6d94..4f12ee8 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,7 +16,7 @@
 
 /**
  * @file xmltooling/util/PathResolver.h
- * 
+ *
  * Resolves local filenames into absolute pathnames.
  */
 
@@ -28,7 +28,6 @@
 #include <string>
 
 namespace xmltooling {
-
     /**
      * Resolves local filenames into absolute pathnames.
      */
@@ -36,10 +35,9 @@ namespace xmltooling {
     {
         MAKE_NONCOPYABLE(PathResolver);
     public:
-        PathResolver() : m_defaultPackage("xmltooling"), m_defaultPrefix("/usr") {}
-
+        PathResolver();
         virtual ~PathResolver() {}
-        
+
         /** Types of file resources to resolve. */
         enum file_type_t {
             XMLTOOLING_LIB_FILE,
@@ -48,33 +46,83 @@ namespace xmltooling {
             XMLTOOLING_RUN_FILE,
             XMLTOOLING_CFG_FILE
         };
-        
+
         /**
          * Set the default package to use when resolving files.
          *
-         * @param pkgname name of default package to use 
+         * @param pkgname name of default package to use
          */
         virtual void setDefaultPackageName(const char* pkgname) {
             m_defaultPackage = pkgname;
         }
 
         /**
-         * Set the default istallation prefix to use when resolving files.
+         * Set the default installation prefix to use when resolving files.
          *
-         * @param prefix name of default prefix to use 
+         * @param prefix name of default prefix to use
          */
         virtual void setDefaultPrefix(const char* prefix) {
             m_defaultPrefix = prefix;
         }
-        
+
+        /**
+         * Set the lib directory to use when resolving files.
+         * <p>If relative, the default prefix will be prepended.
+         *
+         * @param dir    the library directory to use
+         */
+        virtual void setLibDir(const char* dir) {
+            m_lib = dir;
+        }
+
+        /**
+         * Set the log directory to use when resolving files.
+         * <p>If relative, the default prefix will be prepended.
+         *
+         * @param dir    the log directory to use
+         */
+        virtual void setLogDir(const char* dir) {
+            m_log = dir;
+        }
+
+        /**
+         * Set the XML directory to use when resolving files.
+         * <p>If relative, the default prefix will be prepended.
+         *
+         * @param dir    the XML directory to use
+         */
+        virtual void setXMLDir(const char* dir) {
+            m_xml = dir;
+        }
+
+        /**
+         * Set the run directory to use when resolving files.
+         * <p>If relative, the default prefix will be prepended.
+         *
+         * @param dir    the run directory to use
+         */
+        virtual void setRunDir(const char* dir) {
+            m_run = dir;
+        }
+
+        /**
+         * Set the config directory to use when resolving files.
+         * <p>If relative, the default prefix will be prepended.
+         *
+         * @param dir    the config directory to use
+         */
+        virtual void setCfgDir(const char* dir) {
+            m_cfg = dir;
+        }
+
         /**
          * Changes the input filename into an absolute pathname to the same file.
-         * 
+         *
          * @param s         filename to resolve
          * @param filetype  type of file being resolved
          * @param pkgname   application package name to use in resolving the file (or NULL for the default)
          * @param prefix    installation prefix to use in resolving the file (or NULL for the default)
-         * 
+         *
          * @return a const reference to the input string
          */
         virtual const std::string& resolve(std::string& s, file_type_t filetype, const char* pkgname=NULL, const char* prefix=NULL) const;
@@ -91,7 +139,7 @@ namespace xmltooling {
             return *(s+1) == ':';
         }
 
-        std::string m_defaultPackage,m_defaultPrefix;
+        std::string m_defaultPackage,m_defaultPrefix,m_lib,m_log,m_xml,m_run,m_cfg;
     };
 };
 
index 172b813..a28ff5b 100644 (file)
@@ -1,6 +1,6 @@
 /*\r
- *  Copyright 2001-2007 Internet2\r
- * \r
+ *  Copyright 2001-2009 Internet2\r
+ *\r
  * Licensed under the Apache License, Version 2.0 (the "License");\r
  * you may not use this file except in compliance with the License.\r
  * You may obtain a copy of the License at\r
@@ -16,7 +16,7 @@
 \r
 /**\r
  * @file ReloadableXMLFile.cpp\r
- * \r
+ *\r
  * Base class for file-based XML configuration.\r
  */\r
 \r
 \r
 #include <xercesc/framework/LocalFileInputSource.hpp>\r
 #include <xercesc/framework/Wrapper4InputSource.hpp>\r
-#include <xercesc/framework/URLInputSource.hpp>\r
 #include <xercesc/util/XMLUniDefs.hpp>\r
 \r
 using namespace xmltooling::logging;\r
 using namespace xmltooling;\r
+using namespace xercesc;\r
 using namespace std;\r
 \r
 static const XMLCh uri[] =              UNICODE_LITERAL_3(u,r,i);\r
@@ -79,14 +79,14 @@ ReloadableXMLFile::ReloadableXMLFile(const DOMElement* e, Category& log)
     }\r
     else\r
         m_local=false;\r
-    \r
+\r
     if (source && *source) {\r
         const XMLCh* flag=e->getAttributeNS(NULL,validate);\r
         m_validate=(XMLString::equals(flag,xmlconstants::XML_TRUE) || XMLString::equals(flag,xmlconstants::XML_ONE));\r
 \r
         auto_ptr_char temp(source);\r
         m_source=temp.get();\r
-        \r
+\r
         if (!m_local && !strstr(m_source.c_str(),"://")) {\r
             log.warn("deprecated usage of uri/url attribute for a local resource, use path instead");\r
             m_local=true;\r
@@ -156,8 +156,8 @@ pair<bool,DOMElement*> ReloadableXMLFile::load(bool backup)
                 m_log.debug("loading configuration from external resource...");\r
 \r
             DOMDocument* doc=NULL;\r
-            auto_ptr_XMLCh widenit(backup ? m_backing.c_str() : m_source.c_str());\r
             if (m_local || backup) {\r
+                auto_ptr_XMLCh widenit(backup ? m_backing.c_str() : m_source.c_str());\r
                 LocalFileInputSource src(widenit.get());\r
                 Wrapper4InputSource dsrc(&src,false);\r
                 if (m_validate)\r
@@ -166,7 +166,7 @@ pair<bool,DOMElement*> ReloadableXMLFile::load(bool backup)
                     doc=XMLToolingConfig::getConfig().getParser().parse(dsrc);\r
             }\r
             else {\r
-                URLInputSource src(widenit.get());\r
+                URLInputSource src(m_root);\r
                 Wrapper4InputSource dsrc(&src,false);\r
                 if (m_validate)\r
                     doc=XMLToolingConfig::getConfig().getValidatingParser().parse(dsrc);\r
@@ -180,7 +180,7 @@ pair<bool,DOMElement*> ReloadableXMLFile::load(bool backup)
                 m_log.debug("backing up remote resource to (%s)", m_backing.c_str());\r
                 try {\r
                     ofstream backer(m_backing.c_str());\r
-                    backer << *(doc->getDocumentElement());\r
+                    backer << *doc;\r
                 }\r
                 catch (exception& ex) {\r
                     m_log.crit("exception while backing up resource: %s", ex.what());\r
@@ -211,7 +211,7 @@ Lockable* ReloadableXMLFile::lock()
 {\r
     if (!m_lock)\r
         return this;\r
-        \r
+\r
     m_lock->rdlock();\r
 \r
     // Check if we need to refresh.\r
@@ -227,7 +227,7 @@ Lockable* ReloadableXMLFile::lock()
 #endif\r
         if (m_filestamp>=stat_buf.st_mtime)\r
             return this;\r
-        \r
+\r
         // Elevate lock and recheck.\r
         m_log.debug("timestamp of local resource changed, elevating to a write lock");\r
         m_lock->unlock();\r
@@ -267,7 +267,7 @@ Lockable* ReloadableXMLFile::lock()
         m_filestamp = now;\r
         m_log.info("reloading remote resource...");\r
     }\r
-    \r
+\r
     // Do this once...\r
     try {\r
         // At this point we're holding the write lock, so make sure we pop it.\r
@@ -278,7 +278,7 @@ Lockable* ReloadableXMLFile::lock()
     } catch (exception& ex) {\r
         m_log.crit("maintaining existing configuration, error reloading resource (%s): %s", m_source.c_str(), ex.what());\r
     }\r
-    \r
+\r
     // If we made it here, the swap may or may not have worked, but we need to relock.\r
     m_log.debug("attempt to update resource complete, relocking");\r
     m_lock->rdlock();\r
index cb4c5c3..d8dda9e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2009 Internet2
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -53,6 +53,10 @@ namespace xmltooling {
          *  <dd>use a validating parser</dd>
          *  <dt>reloadChanges</dt>
          *  <dd>enables monitoring of local file for changes</dd>
+         *  <dt>reloadInterval</dt>
+         *  <dd>enables periodic refresh of remote file</dd>
+         *  <dt>backingFilePath</dt>
+         *  <dd>location for backup of remote resource</dd>
          * </dl>
          * 
          * @param e     DOM to supply configuration
index b5b5782..7b6717a 100644 (file)
@@ -27,7 +27,7 @@ using namespace xmltooling;
 using namespace std;
 
 namespace xmltooling {
-    XMLTOOL_DLLLOCAL PluginManager<StorageService,string,const DOMElement*>::Factory MemoryStorageServiceFactory; 
+    XMLTOOL_DLLLOCAL PluginManager<StorageService,string,const xercesc::DOMElement*>::Factory MemoryStorageServiceFactory; 
 };
 
 void XMLTOOL_API xmltooling::registerStorageServices()
index c9f44b8..1e86975 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * TemplateEngine.cpp
- * 
- * Simple template replacement engine. 
+ *
+ * Simple template replacement engine.
  */
 
 #include "internal.h"
 using namespace xmltooling;
 using namespace std;
 
+namespace {
+    static const pair<const string,string> emptyPair;
+}
+
 void TemplateEngine::setTagPrefix(const char* tagPrefix)
 {
     keytag = string("<") + tagPrefix + " ";
@@ -33,8 +37,12 @@ void TemplateEngine::setTagPrefix(const char* tagPrefix)
     ifnottag = string("<") + tagPrefix + "ifnot ";
     ifendtag = string("</") + tagPrefix + "if>";
     ifnotendtag = string("</") + tagPrefix + "ifnot>";
+    fortag = string("<") + tagPrefix + "for ";
+    forendtag = string("</") + tagPrefix + "for>";
 }
 
+string TemplateEngine::unsafe_chars = "#%&():[]\\`{}";
+
 void TemplateEngine::html_encode(ostream& os, const char* start) const
 {
     while (start && *start) {
@@ -42,10 +50,18 @@ void TemplateEngine::html_encode(ostream& os, const char* start) const
             case '<':   os << "&lt;";       break;
             case '>':   os << "&gt;";       break;
             case '"':   os << "&quot;";     break;
-            case '#':   os << "&#35;";      break;
-            case '%':   os << "&#37;";      break;
             case '&':   os << "&#38;";      break;
             case '\'':  os << "&#39;";      break;
+
+            default:
+                if (unsafe_chars.find_first_of(*start) != string::npos)
+                    os << "&#" << static_cast<short>(*start) << ';';
+                else
+                    os << *start;
+
+            /*
+            case '#':   os << "&#35;";      break;
+            case '%':   os << "&#37;";      break;
             case '(':   os << "&#40;";      break;
             case ')':   os << "&#41;";      break;
             case ':':   os << "&#58;";      break;
@@ -56,6 +72,7 @@ void TemplateEngine::html_encode(ostream& os, const char* start) const
             case '{':   os << "&#123;";     break;
             case '}':   os << "&#125;";     break;
             default:    os << *start;
+            */
         }
         start++;
     }
@@ -81,6 +98,7 @@ void TemplateEngine::process(
     const char*& lastpos,
     ostream& os,
     const TemplateParameters& parameters,
+    const std::pair<const std::string,std::string>& loopentry,
     const XMLToolingException* e
     ) const
 {
@@ -91,7 +109,7 @@ void TemplateEngine::process(
         // Output the string up to this token.
         if (visible)
             os << buf.substr(lastpos-line, thispos-lastpos);
-    
+
         // Make sure this token matches our tokens.
 #ifdef HAVE_STRCASECMP
         if (visible && !strncasecmp(thispos, keytag.c_str(), keytag.length()))
@@ -101,17 +119,23 @@ void TemplateEngine::process(
         {
             // Save this position off.
             lastpos = thispos + keytag.length();
-        
+
             // search for the end-tag
             if ((thispos = strstr(lastpos, "/>")) != NULL) {
                 string key = buf.substr(lastpos-line, thispos-lastpos);
                 trimspace(key);
-        
-                const char* p = parameters.getParameter(key.c_str());
-                if (!p && e)
-                    p = e->getProperty(key.c_str());
-                if (p)
-                    html_encode(os,p);
+
+                if (key == "$name" && !loopentry.first.empty())
+                    html_encode(os,loopentry.first.c_str());
+                else if (key == "$value" && !loopentry.second.empty())
+                    html_encode(os,loopentry.second.c_str());
+                else {
+                    const char* p = parameters.getParameter(key.c_str());
+                    if (!p && e)
+                        p = e->getProperty(key.c_str());
+                    if (p)
+                        html_encode(os,p);
+                }
                 lastpos = thispos + 2; // strlen("/>")
             }
         }
@@ -123,7 +147,7 @@ void TemplateEngine::process(
         {
             // Save this position off.
             lastpos = thispos + iftag.length();
-    
+
             // search for the end of this tag
             if ((thispos = strchr(lastpos, '>')) != NULL) {
                 string key = buf.substr(lastpos-line, thispos-lastpos);
@@ -132,7 +156,7 @@ void TemplateEngine::process(
                 if (visible)
                     cond = parameters.getParameter(key.c_str()) || (e && e->getProperty(key.c_str()));
                 lastpos = thispos + 1; // strlen(">")
-                process(cond, buf, lastpos, os, parameters, e);
+                process(cond, buf, lastpos, os, parameters, loopentry, e);
             }
         }
 #ifdef HAVE_STRCASECMP
@@ -153,7 +177,7 @@ void TemplateEngine::process(
         {
             // Save this position off.
             lastpos = thispos + ifnottag.length();
-    
+
             // search for the end of this tag
             if ((thispos = strchr(lastpos, '>')) != NULL) {
                 string key = buf.substr(lastpos-line, thispos-lastpos);
@@ -162,7 +186,7 @@ void TemplateEngine::process(
                 if (visible)
                     cond = !(parameters.getParameter(key.c_str()) || (e && e->getProperty(key.c_str())));
                 lastpos = thispos + 1; // strlen(">")
-                process(cond, buf, lastpos, os, parameters, e);
+                process(cond, buf, lastpos, os, parameters, loopentry, e);
             }
         }
 #ifdef HAVE_STRCASECMP
@@ -175,6 +199,49 @@ void TemplateEngine::process(
             lastpos = thispos + ifnotendtag.length();
             return;
         }
+
+#ifdef HAVE_STRCASECMP
+        else if (!strncasecmp(thispos, fortag.c_str(), fortag.length()))
+#else
+        else if (!_strnicmp(thispos, fortag.c_str(), fortag.length()))
+#endif
+        {
+            // Save this position off.
+            lastpos = thispos + iftag.length();
+            string key;
+            bool cond = visible;
+
+            // search for the end of this tag
+            if ((thispos = strchr(lastpos, '>')) != NULL) {
+                key = buf.substr(lastpos-line, thispos-lastpos);
+                trimspace(key);
+                lastpos = thispos + 1; // strlen(">")
+            }
+
+            const multimap<string,string>* forParams = parameters.getLoopCollection(key.c_str());
+            if (!forParams || forParams->size() == 0) {
+                process(false, buf, lastpos, os, parameters, emptyPair, e);
+            }
+            else {
+                const char* savlastpos = lastpos;
+                for (multimap<string,string>::const_iterator i=forParams->begin(); i!=forParams->end(); ++i) {
+                    lastpos = savlastpos;
+                    process(cond, buf, lastpos, os, parameters, *i, e);
+                }
+            }
+        }
+
+#ifdef HAVE_STRCASECMP
+        else if (!strncasecmp(thispos, forendtag.c_str(), forendtag.length()))
+#else
+        else if (!_strnicmp(thispos, forendtag.c_str(), forendtag.length()))
+#endif
+        {
+            // Save this position off and pop the stack.
+            lastpos = thispos + forendtag.length();
+            return;
+        }
+
         else {
             // Skip it.
             if (visible)
@@ -191,7 +258,7 @@ void TemplateEngine::run(istream& is, ostream& os, const TemplateParameters& par
     string buf,line;
     while (getline(is, line))
         buf += line + '\n';
-    
+
     const char* pos=buf.c_str();
-    process(true, buf, pos, os, parameters, e);
+    process(true, buf, pos, os, parameters, emptyPair, e);
 }
index bbbcf18..2349b1e 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,7 +16,7 @@
 
 /**
  * @file xmltooling/util/TemplateEngine.h
- * 
+ *
  * Simple template replacement engine.
  */
 
@@ -28,6 +28,7 @@
 #include <map>
 #include <string>
 #include <iostream>
+#include <vector>
 
 #if defined (_MSC_VER)
     #pragma warning( push )
@@ -42,8 +43,11 @@ namespace xmltooling {
      *  <li> &lt;mlp key/&gt; </li>
      *  <li> &lt;mlpif key&gt; stuff &lt;/mlpif&gt;</li>
      *  <li> &lt;mlpifnot key&gt; stuff &lt;/mlpifnot&gt;</li>
+     *  <li> &lt;mlpfor key&gt; stuff &lt;/mlpfor&gt;</li>
+     *  <li> &lt;mlp $name/&gt; (in for loop only) </li>
+     *  <li> &lt;mlp $value/&gt; (in for loop only) </li>
      * </ul>
-     * 
+     *
      * The default tag prefix is "mlp". This can be overridden for
      * compatibility.
      */
@@ -51,39 +55,41 @@ namespace xmltooling {
     {
         MAKE_NONCOPYABLE(TemplateEngine);
     public:
-        
         TemplateEngine() {
-            setTagPrefix("mlp"); 
+            setTagPrefix("mlp");
         }
 
         virtual ~TemplateEngine() {}
-        
+
         /**
          * Sets the tag name to use when locating template replacement tags.
-         * 
+         *
          * @param tagPrefix base prefix for tags
          */
         void setTagPrefix(const char* tagPrefix);
-        
+
         /**
          * Interface to parameters to plug into templates.
          * Allows callers to supply a more dynamic lookup mechanism to supplement a basic map.
          */
         class XMLTOOL_API TemplateParameters {
-            MAKE_NONCOPYABLE(TemplateParameters);
+            // MAKE_NONCOPYABLE(TemplateParameters);
         public:
             TemplateParameters() : m_request(NULL) {}
             virtual ~TemplateParameters() {}
-            
+
             /** Map of known parameters to supply to template. */
             std::map<std::string,std::string> m_map;
-            
+
+            /** Map of sub-collections used in for loops. */
+            std::map< std::string,std::multimap<std::string,std::string> > m_collectionMap;
+
             /** Request from client that resulted in template being processed. */
             const GenericRequest* m_request;
-            
+
             /**
              * Returns the value of a parameter to plug into the template.
-             * 
+             *
              * @param name  name of parameter
              * @return value of parameter, or NULL
              */
@@ -91,12 +97,23 @@ namespace xmltooling {
                 std::map<std::string,std::string>::const_iterator i=m_map.find(name);
                 return (i!=m_map.end() ? i->second.c_str() : (m_request ? m_request->getParameter(name) : NULL));
             }
+
+            /**
+             * Returns a named collection of sub-parameters to pass into a loop.
+             *
+             * @param name  name of sub-collection
+             * @return pointer to a multimap of sub-parameters, or NULL
+             */
+            virtual const std::multimap<std::string,std::string>* getLoopCollection(const char* name) const {
+                std::map< std::string,std::multimap<std::string,std::string> >::const_iterator i=m_collectionMap.find(name);
+                return (i!=m_collectionMap.end() ? &(i->second) : NULL);
+            }
         };
-        
+
         /**
          * Processes template from an input stream and executes replacements and
-         * conditional logic based on parameters. 
-         * 
+         * conditional logic based on parameters.
+         *
          * @param is            input stream providing template
          * @param os            output stream to send results of executing template
          * @param parameters    parameters to plug into template
@@ -109,6 +126,12 @@ namespace xmltooling {
             const XMLToolingException* e=NULL
             ) const;
 
+        /**
+         * List of non-built-in characters considered "unsafe" and requiring HTML encoding.
+         * The default set is #%&():[]\\`{}
+         */
+        static std::string unsafe_chars;
+
     private:
         void trimspace(std::string& s) const;
         void html_encode(std::ostream& os, const char* start) const;
@@ -118,10 +141,11 @@ namespace xmltooling {
             const char*& lastpos,
             std::ostream& os,
             const TemplateParameters& parameters,
+            const std::pair<const std::string,std::string>& loopentry,
             const XMLToolingException* e
             ) const;
-            
-        std::string keytag,iftag,ifendtag,ifnottag,ifnotendtag;
+
+        std::string keytag,iftag,ifendtag,ifnottag,ifnotendtag,fortag,forendtag;
     };
 };
 
index 40bd093..e3eee29 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * @file xmltooling/util/Threads.h
- * 
- * Thread and locking wrappers 
+ *
+ * Thread and locking wrappers
  */
 
 #ifndef _xmltooling_threads_h
 #include <xmltooling/base.h>
 #include <xmltooling/exceptions.h>
 
-#include <signal.h>\r
+#include <signal.h>
 
 namespace xmltooling
 {
     DECL_XMLTOOLING_EXCEPTION(ThreadingException,XMLTOOL_EXCEPTIONAPI(XMLTOOL_API),xmltooling,XMLToolingException,Exceptions during threading/locking operations);
-    
+
     /**
      * A class for manual thread creation and synchronization.
      */
@@ -44,58 +44,58 @@ namespace xmltooling
 
         /**
          * Disassociate from the thread.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int detach()=0;
-        
+
         /**
          * Join with the thread and wait for its completion.
-         * 
+         *
          * @param thread_return holds the return value of the thread routine
          * @return 0 for success, non-zero for failure
          */
         virtual int join(void** thread_return)=0;
-        
+
         /**
          * Kill the thread.
-         * 
+         *
          * @param signo the signal to send to the thread
          * @return 0 for success, non-zero for failure
          */
         virtual int kill(int signo)=0;
-        
+
         /**
          * Creates a new thread object to run the supplied start routine.
-         * 
+         *
          * @param start_routine the function to execute on the thread
          * @param arg           a parameter for the start routine
-         * @return  the created and running thread object 
+         * @return  the created and running thread object
          */
         static Thread* create(void* (*start_routine)(void*), void* arg);
-        
+
         /**
          * Exits a thread gracefully.
-         * 
+         *
          * @param return_val    the return value for the thread
          */
         static void exit(void* return_val);
 
         /**
          * Sleeps the current thread for the specified amount of time.
-         * 
+         *
          * @param seconds   time to sleep
          */
-        static void sleep(int seconds);        
+        static void sleep(int seconds);
 #ifndef WIN32
         /**
-         * Masks all signals from a thread. 
+         * Masks all signals from a thread.
          */
         static void mask_all_signals(void);
-        
+
         /**
          * Masks specific signals from a thread.
-         * 
+         *
          * @param how
          * @param newmask   the new signal mask
          * @param oldmask   the old signal mask
@@ -117,7 +117,7 @@ namespace xmltooling
 
         /**
          * Sets the value for a TLS key.
-         * 
+         *
          * @param data  the value to set
          * @return 0 for success, non-zero for failure
          */
@@ -125,18 +125,28 @@ namespace xmltooling
 
         /**
          * Returns the value for a TLS key.
-         * 
+         *
          * @return the value or NULL
-         */        
+         */
         virtual void* getData() const=0;
 
         /**
          * Creates a new TLS key.
-         * 
+         *
          * @param destroy_fn    a functon to cleanup key values
          * @return the new key
          */
         static ThreadKey* create(void (*destroy_fn)(void*));
+
+#ifdef WIN32
+        /**
+         * Allows system to notify TLS implementation when a thread completes.
+         *
+         * <p>Windows doesn't support TLS destructors, so only the DllMain detach
+         * notification can be used to trigger per-thread cleanup.
+         */
+        static void onDetach();
+#endif
     };
 
     /**
@@ -151,26 +161,26 @@ namespace xmltooling
 
         /**
          * Locks the mutex for exclusive access.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int lock()=0;
-        
+
         /**
          * Unlocks the mutex for exclusive access.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int unlock()=0;
 
         /**
          * Creates a new mutex object.
-         * 
+         *
          * @return the new mutex
          */
         static Mutex* create();
     };
-    
+
     /**
      * A class for managing shared and exclusive access to resources.
      */
@@ -183,33 +193,33 @@ namespace xmltooling
 
         /**
          * Obtains a shared lock.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int rdlock()=0;
-        
+
         /**
          * Obtains an exclusive lock.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int wrlock()=0;
 
         /**
          * Unlocks the lock.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int unlock()=0;
 
         /**
          * Creates a new read/write lock.
-         * 
+         *
          * @return the new lock
          */
         static RWLock* create();
     };
-    
+
     /**
      * A class for establishing queues on a mutex based on a periodic condition.
      */
@@ -219,47 +229,47 @@ namespace xmltooling
     public:
         CondWait() {}
         virtual ~CondWait() {}
-        
+
         /**
          * Waits for a condition variable using the supplied mutex as a queue.
-         * 
+         *
          * @param lock  mutex to queue on
          * @return 0 for success, non-zero for failure
          */
         virtual int wait(Mutex* lock)=0;
-        
+
         /**
          * Waits for a condition variable using the supplied mutex as a queue,
          * but only for a certain time limit.
-         * 
+         *
          * @param lock          mutex to queue on
          * @param delay_seconds maximum time to wait before waking up
          * @return 0 for success, non-zero for failure
          */
         virtual int timedwait(Mutex* lock, int delay_seconds)=0;
-        
+
         /**
          * Signal a single thread to wake up if a condition changes.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int signal()=0;
-        
+
         /**
          * Signal all threads to wake up if a condition changes.
-         * 
+         *
          * @return 0 for success, non-zero for failure
          */
         virtual int broadcast()=0;
 
         /**
          * Creates a new condition variable.
-         * 
+         *
          * @return the new condition variable
          */
         static CondWait* create();
     };
-    
+
     /**
      * RAII wrapper for a mutex lock.
      */
@@ -268,24 +278,24 @@ namespace xmltooling
     public:
         /**
          * Locks and wraps the designated mutex.
-         * 
-         * @param mtx mutex to lock 
+         *
+         * @param mtx mutex to lock
          */
         Lock(Mutex* mtx) : mutex(mtx) {
             mutex->lock();
         }
-        
+
         /**
          * Unlocks the wrapped mutex.
          */
         ~Lock() {
             mutex->unlock();
         }
-    
+
     private:
         Mutex* mutex;
     };
-    
+
     /**
      * RAII wrapper for a shared lock.
      */
@@ -294,22 +304,22 @@ namespace xmltooling
     public:
         /**
          * Locks and wraps the designated shared lock.
-         * 
-         * @param lock      lock to acquire 
+         *
+         * @param lock      lock to acquire
          * @param lockit    true if the lock should be acquired here, false if already acquired
          */
         SharedLock(RWLock* lock, bool lockit=true) : rwlock(lock) {
             if (lockit)
                 rwlock->rdlock();
         }
-        
+
         /**
          * Unlocks the wrapped shared lock.
          */
         ~SharedLock() {
             rwlock->unlock();
         }
-    
+
     private:
         RWLock* rwlock;
     };
index d30f0f1..5b895d1 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,7 +16,7 @@
 
 /**
  * @file xmltooling/util/URLEncoder.h
- * 
+ *
  * Interface to a URL-encoding mechanism along with a
  * default implementation.
  */
@@ -29,7 +29,7 @@
 namespace xmltooling {
     /**
      * Interface to a URL-encoding mechanism along with a default implementation.
-     * 
+     *
      * Since URL-encoding is not canonical, it's important that the same
      * encoder is used during some library operations and the calling code.
      * Applications can supply an alternative implementation to the library
@@ -40,33 +40,33 @@ namespace xmltooling {
     public:
         URLEncoder() {}
         virtual ~URLEncoder() {}
-        
+
         /**
          * Produce a URL-safe but equivalent version of the input string.
-         * 
+         *
          * @param s input string to encode
          * @return a string object containing the result of encoding the input
          */
         virtual std::string encode(const char* s) const;
-        
+
         /**
          * Perform an in-place decoding operation on the input string.
          * The resulting string will be NULL-terminated.
-         * 
+         *
          * @param s input string to decode in a writable buffer
          */
         virtual void decode(char* s) const;
-        
+
     protected:
         /**
          * Returns true iff the input character requires encoding.
-         * 
+         *
          * @param ch    the character to check
-         * @return  true iff the character should be encoded 
+         * @return  true iff the character should be encoded
          */
         virtual bool isBad(char ch) const {
             static char badchars[]="=&/?:\"\\+<>#%{}|^~[]`;@";
-            return (strchr(badchars,ch) || ch<=0x20 || ch>=0x7F);
+            return (ch<=0x20 || ch>=0x7F || strchr(badchars,ch));
         }
     };
 };
index 3bf6419..072bb14 100644 (file)
@@ -1,6 +1,6 @@
 /*
- *  Copyright 2001-2007 Internet2
- * 
+ *  Copyright 2001-2009 Internet2
+ *
  * 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
@@ -16,7 +16,7 @@
 
 /**
  * Win32Threads.cpp
- * 
+ *
  * Thread and locking wrappers for Win32 platforms
  */
 
@@ -24,6 +24,8 @@
 #include "logging.h"
 #include "util/Threads.h"
 
+#include <algorithm>
+
 #ifndef WIN32
 # error "This implementation is for WIN32 platforms."
 #endif
@@ -55,10 +57,10 @@ namespace xmltooling {
     struct XMLTOOL_DLLLOCAL critical_section_data {
         CRITICAL_SECTION cs;
         critical_section_data(){
-            InitializeCriticalSection(&cs);    
+            InitializeCriticalSection(&cs);
         }
     };
-    
+
     class XMLTOOL_DLLLOCAL critical_section {
     private:
         critical_section_data  cse;
@@ -74,7 +76,7 @@ namespace xmltooling {
             LeaveCriticalSection(&cse.cs);
         }
     };
-    
+
     // hold a critical section over the lifetime of this object
     // used to make a stack variable that unlocks automaticly
     // on return/throw
@@ -89,7 +91,7 @@ namespace xmltooling {
             cs.leave();
         }
     };
-    
+
     class XMLTOOL_DLLLOCAL ThreadImpl : public Thread {
     private:
         HANDLE thread_id;
@@ -111,7 +113,7 @@ namespace xmltooling {
         ~ThreadImpl() {
             (void)detach();
         }
-    
+
         int detach() {
             if (thread_id==0)
                 return THREAD_ERROR;
@@ -135,50 +137,41 @@ namespace xmltooling {
             }
             return 0;
         }
-      
+
         int kill(int signo) {
             if (thread_id==0)
                 return THREAD_ERROR;
             return map_windows_error_status_to_pthreads(TerminateThread(thread_id,signo));
         }
     };
-    
+
     class XMLTOOL_DLLLOCAL MutexImpl : public Mutex {
     private:
-        HANDLE mhandle;
+        CRITICAL_SECTION mhandle;
     public:
-        MutexImpl() : mhandle(CreateMutex(0,false,0)) {
-            if (mhandle==0) {
-                map_windows_error_status_to_pthreads();
-                throw ThreadingException("Mutex creation failed.");
-            }
+        MutexImpl() {
+            InitializeCriticalSection(&mhandle);
         }
-        
+
         ~MutexImpl() {
-            if((mhandle!=0) && (!CloseHandle(mhandle))) 
-                map_windows_error_status_to_pthreads();
+            DeleteCriticalSection(&mhandle);
         }
-        
+
         int lock() {
-            int rc=WaitForSingleObject(mhandle,INFINITE);
-            switch(rc) {
-                case WAIT_ABANDONED:
-                case WAIT_OBJECT_0:
-                    return 0;
-                default:
-                    return map_windows_error_status_to_pthreads();
-            }
+            EnterCriticalSection(&mhandle);
+            return 0;
         }
-        
+
         int unlock() {
-            return map_windows_error_status_to_pthreads(ReleaseMutex(mhandle));
+            LeaveCriticalSection(&mhandle);
+            return 0;
         }
     };
-    
+
     class XMLTOOL_DLLLOCAL CondWaitImpl : public CondWait {
     private:
         HANDLE cond;
-    
+
     public:
         CondWaitImpl() : cond(CreateEvent(0,false,false,0)) {
             if(cond==0) {
@@ -186,32 +179,32 @@ namespace xmltooling {
                throw ThreadingException("Event creation failed.");
             }
         };
-    
+
         ~CondWaitImpl() {
-            if((cond!=0) && (!CloseHandle(cond))) 
+            if((cond!=0) && (!CloseHandle(cond)))
                 map_windows_error_status_to_pthreads();
         }
-    
+
         int wait(Mutex* mutex) {
             return timedwait(mutex,INFINITE);
         }
-    
+
         int signal() {
             if(!SetEvent(cond))
                 return map_windows_error_status_to_pthreads();
             return 0;
         }
-      
+
         int broadcast() {
             throw ThreadingException("Broadcast not implemented on Win32 platforms.");
         }
-    
+
         // wait for myself to signal and this mutex or the timeout
         int timedwait(Mutex* mutex, int delay_seconds) {
             int rc=mutex->unlock();
             if(rc!=0)
                 return rc;
-        
+
             int delay_ms=delay_seconds;
             if(delay_seconds!=INFINITE)
                 delay_ms*=1000;
@@ -230,7 +223,7 @@ namespace xmltooling {
             return 0;
         }
     };
-    
+
     class XMLTOOL_DLLLOCAL RWLockImpl : public RWLock {
     private:
         // used to protect read or write to the data below
@@ -244,7 +237,7 @@ namespace xmltooling {
         int num_readers;
         // true iff there a writer has our lock
         bool have_writer;
-    
+
     public:
         RWLockImpl() : wake_waiters(0), num_readers(0), have_writer(true) {
             with_crit_section acs(cs);
@@ -255,20 +248,20 @@ namespace xmltooling {
                 throw ThreadingException("Event creation for shared lock failed.");
             }
         }
-        
-        ~RWLockImpl() { 
+
+        ~RWLockImpl() {
             with_crit_section acs(cs);
-            if ((wake_waiters!=0) && (!CloseHandle(wake_waiters))) 
+            if ((wake_waiters!=0) && (!CloseHandle(wake_waiters)))
                 map_windows_error_status_to_pthreads();
         }
-    
+
         int rdlock() {
             while(1) {
                 // wait for the lock maybe being availible
                 // we will find out for sure inside the critical section
-                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0) 
+                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0)
                     return map_windows_error_status_to_pthreads();
-         
+
                 with_crit_section alock(cs);
                 // invariant not locked for reading and writing
                 if ((num_readers!=0) && (have_writer))
@@ -278,7 +271,7 @@ namespace xmltooling {
                     num_readers++;
                     return 0;
                 }
-           
+
                 // have a writer, mark the synchronization object
                 // so everyone waits, when the writer unlocks it will wake us
                 if (!ResetEvent(wake_waiters))
@@ -286,12 +279,12 @@ namespace xmltooling {
             }
             return THREAD_ERROR;
         }
-    
+
         int wrlock() {
             while(1) {
                 // wait for the lock maybe being availible
                 // we will find out for sure inside the critical section
-                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0) 
+                if (WaitForSingleObject(wake_waiters,INFINITE)!=WAIT_OBJECT_0)
                     return map_windows_error_status_to_pthreads();
 
                 with_crit_section bla(cs);
@@ -304,31 +297,31 @@ namespace xmltooling {
                     have_writer=true;
                     return 0;
                 }
-             
+
                 // lock is busy, the unlocker will wake us
                 if (!ResetEvent(wake_waiters))
                     return map_windows_error_status_to_pthreads();
             }
             return THREAD_ERROR;
         }
-    
+
         int unlock() {
             with_crit_section mumble(cs);
             // invariant not locked for reading and writing
             if ((num_readers!=0) && (have_writer))
                 return THREAD_ERROR;
-            
+
             // error if nothing locked
             if ((num_readers==0) && (!have_writer))
                 return THREAD_ERROR;
-            
-            // if there was a writer it has to be us so unlock write lock 
+
+            // if there was a writer it has to be us so unlock write lock
             have_writer=false;
-            
+
             // if there where any reades there is one less now
             if(num_readers>0)
                 num_readers--;
-            
+
             // if no readers left wake up any readers/writers waiting
             // to have a go at it
             if (num_readers==0)
@@ -337,33 +330,49 @@ namespace xmltooling {
             return 0;
         }
     };
-    
+
     typedef void (*destroy_hook_type)(void*);
-    
+
     class XMLTOOL_DLLLOCAL ThreadKeyImpl : public ThreadKey {
     private:
         destroy_hook_type destroy_hook;
         DWORD key;
-    
+        static critical_section cs;
+        static set<ThreadKeyImpl*> m_keys;
+        friend class ThreadKey;
     public:
         ThreadKeyImpl(void (*destroy_fcn)(void*)) : destroy_hook(destroy_fcn) {
             key=TlsAlloc();
+            if (destroy_fcn) {
+                with_crit_section wcs(cs);
+                m_keys.insert(this);
+            }
         };
-        
+
         virtual ~ThreadKeyImpl() {
-            if (destroy_hook)
+            if (destroy_hook) {
                 destroy_hook(TlsGetValue(key));
+                with_crit_section wcs(cs);
+                m_keys.erase(this);
+            }
             TlsFree(key);
         }
-    
+
         int setData(void* data) {
-            TlsSetValue(key,data);
+            TlsSetValue(key, data);
             return 0;
         }
-        
+
         void* getData() const {
             return TlsGetValue(key);
         }
+
+        void onDetach() const {
+            if (destroy_hook) {
+                destroy_hook(TlsGetValue(key));
+                TlsSetValue(key, NULL);
+            }
+        }
     };
 
 };
@@ -402,7 +411,16 @@ RWLock * RWLock::create()
     return new RWLockImpl();
 }
 
+critical_section ThreadKeyImpl::cs;
+set<ThreadKeyImpl*> ThreadKeyImpl::m_keys;
+
 ThreadKey* ThreadKey::create (void (*destroy_fcn)(void*))
 {
     return new ThreadKeyImpl(destroy_fcn);
 }
+
+void ThreadKey::onDetach()
+{
+    with_crit_section wcs(ThreadKeyImpl::cs);
+    for_each(ThreadKeyImpl::m_keys.begin(), ThreadKeyImpl::m_keys.end(), mem_fun<void,ThreadKeyImpl>(&ThreadKeyImpl::onDetach));
+}
index 8796aea..94ea5dc 100644 (file)
@@ -25,6 +25,8 @@
 #include "util/XMLConstants.h"
 #include <xercesc/util/XMLUniDefs.hpp>
 
+using namespace xercesc;
+
 const XMLCh xmlconstants::XML_NS[] = // http://www.w3.org/XML/1998/namespace
 { chLatin_h, chLatin_t, chLatin_t, chLatin_p, chColon, chForwardSlash, chForwardSlash,
   chLatin_w, chLatin_w, chLatin_w, chPeriod, chLatin_w, chDigit_3, chPeriod, chLatin_o, chLatin_r, chLatin_g, chForwardSlash,
index 7a68ef4..6128bff 100644 (file)
@@ -29,6 +29,7 @@
 #include <xercesc/util/XMLUniDefs.hpp>
 
 using namespace xmltooling;
+using namespace xercesc;
 using namespace std;
 
 static const XMLCh type[]={chLatin_t, chLatin_y, chLatin_p, chLatin_e, chNull };
@@ -44,7 +45,7 @@ bool XMLHelper::hasXSIType(const DOMElement* e)
     return false;
 }
 
-QName* XMLHelper::getXSIType(const DOMElement* e)
+xmltooling::QName* XMLHelper::getXSIType(const DOMElement* e)
 {
     DOMAttr* attribute = e->getAttributeNodeNS(xmlconstants::XSI_NS, type);
     if (attribute) {
@@ -55,12 +56,12 @@ QName* XMLHelper::getXSIType(const DOMElement* e)
                 XMLCh* prefix=new XMLCh[i+1];
                 XMLString::subString(prefix,attributeValue,0,i);
                 prefix[i]=chNull;
-                QName* ret=new QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);
+                xmltooling::QName* ret=new xmltooling::QName(e->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);
                 delete[] prefix;
                 return ret;
             }
             else {
-                return new QName(e->lookupNamespaceURI(NULL), attributeValue);
+                return new xmltooling::QName(e->lookupNamespaceURI(NULL), attributeValue);
             }
         }
     }
@@ -122,30 +123,35 @@ XMLObject* XMLHelper::getXMLObjectById(XMLObject& tree, const XMLCh* id)
     return NULL;
 }
 
-QName* XMLHelper::getNodeQName(const DOMNode* domNode)
+xmltooling::QName* XMLHelper::getNodeQName(const DOMNode* domNode)
 {
     if (domNode)
-        return new QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());
+        return new xmltooling::QName(domNode->getNamespaceURI(), domNode->getLocalName(), domNode->getPrefix());
     return NULL; 
 }
 
-QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)
+xmltooling::QName* XMLHelper::getAttributeValueAsQName(const DOMAttr* attribute)
 {
-    if (!attribute)
+    return getNodeValueAsQName(attribute);
+}
+
+xmltooling::QName* XMLHelper::getNodeValueAsQName(const DOMNode* domNode)
+{
+    if (!domNode)
         return NULL;
     
     int i;
-    const XMLCh* attributeValue=attribute->getTextContent();
-    if (attributeValue && (i=XMLString::indexOf(attributeValue,chColon))>0) {
+    const XMLCh* value=domNode->getTextContent();
+    if (value && (i=XMLString::indexOf(value,chColon))>0) {
         XMLCh* prefix=new XMLCh[i+1];
-        XMLString::subString(prefix,attributeValue,0,i);
+        XMLString::subString(prefix,value,0,i);
         prefix[i]=chNull;
-        QName* ret=new QName(attribute->lookupNamespaceURI(prefix), attributeValue + i + 1, prefix);
+        xmltooling::QName* ret=new xmltooling::QName(domNode->lookupNamespaceURI(prefix), value + i + 1, prefix);
         delete[] prefix;
         return ret;
     }
     
-    return new QName(attribute->lookupNamespaceURI(NULL), attributeValue);
+    return new xmltooling::QName(domNode->lookupNamespaceURI(NULL), value);
 }
 
 DOMElement* XMLHelper::appendChildElement(DOMElement* parentElement, DOMElement* childElement)
@@ -254,15 +260,31 @@ void XMLHelper::serialize(const DOMNode* n, std::string& buf, bool pretty)
 {
     static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
     static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };
+
+    MemBufFormatTarget target;
     DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
-    DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();
+
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+    DOMLSSerializer* serializer = static_cast<DOMImplementationLS*>(impl)->createLSSerializer();
+    XercesJanitor<DOMLSSerializer> janitor(serializer);
+    if (pretty && serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, pretty))
+        serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, pretty);
+    DOMLSOutput *theOutput = static_cast<DOMImplementationLS*>(impl)->createLSOutput();\r
+    XercesJanitor<DOMLSOutput> j_theOutput(theOutput);\r
+    theOutput->setEncoding(UTF8);\r
+    theOutput->setByteStream(&target);
+    if (!serializer->write(n, theOutput))
+        throw XMLParserException("unable to serialize XML");
+#else
+    DOMWriter* serializer = static_cast<DOMImplementationLS*>(impl)->createDOMWriter();
     XercesJanitor<DOMWriter> janitor(serializer);
     serializer->setEncoding(UTF8);
     if (pretty && serializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, pretty))
         serializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, pretty);
-    MemBufFormatTarget target;
-    if (!serializer->writeNode(&target,*n))
+    if (!serializer->writeNode(&target, *n))
         throw XMLParserException("unable to serialize XML");
+#endif
+
     buf.erase();
     buf.append(reinterpret_cast<const char*>(target.getRawBuffer()),target.getLen());
 }
@@ -274,7 +296,7 @@ namespace {
         StreamFormatTarget(std::ostream& out) : m_out(out) {}
         ~StreamFormatTarget() {}
 
-        void writeChars(const XMLByte *const toWrite, const unsigned int count, XMLFormatter *const formatter) {
+        void writeChars(const XMLByte *const toWrite, const xsecsize_t count, XMLFormatter *const formatter) {
             m_out.write(reinterpret_cast<const char*>(toWrite),count);
         }
 
@@ -291,15 +313,31 @@ ostream& XMLHelper::serialize(const DOMNode* n, ostream& out, bool pretty)
 {
     static const XMLCh impltype[] = { chLatin_L, chLatin_S, chNull };
     static const XMLCh UTF8[]={ chLatin_U, chLatin_T, chLatin_F, chDigit_8, chNull };
+
+    StreamFormatTarget target(out);
     DOMImplementation* impl=DOMImplementationRegistry::getDOMImplementation(impltype);
+
+#ifdef XMLTOOLING_XERCESC_COMPLIANT_DOMLS
+    DOMLSSerializer* serializer = static_cast<DOMImplementationLS*>(impl)->createLSSerializer();
+    XercesJanitor<DOMLSSerializer> janitor(serializer);
+    if (pretty && serializer->getDomConfig()->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, pretty))
+        serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, pretty);
+    DOMLSOutput *theOutput = static_cast<DOMImplementationLS*>(impl)->createLSOutput();\r
+    XercesJanitor<DOMLSOutput> j_theOutput(theOutput);\r
+    theOutput->setEncoding(UTF8);\r
+    theOutput->setByteStream(&target);
+    if (!serializer->write(n, theOutput))
+        throw XMLParserException("unable to serialize XML");
+#else
     DOMWriter* serializer=(static_cast<DOMImplementationLS*>(impl))->createDOMWriter();
     XercesJanitor<DOMWriter> janitor(serializer);
     serializer->setEncoding(UTF8);
     if (pretty && serializer->canSetFeature(XMLUni::fgDOMWRTFormatPrettyPrint, pretty))
         serializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, pretty);
-    StreamFormatTarget target(out);
     if (!serializer->writeNode(&target,*n))
         throw XMLParserException("unable to serialize XML");
+#endif
+
     return out;
 }
 
index 28757a8..08a4e80 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Copyright 2001-2007 Internet2
- * 
+ *
  * 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
@@ -16,8 +16,8 @@
 
 /**
  * @file xmltooling/util/XMLHelper.h
- * 
- * A helper class for working with W3C DOM objects. 
+ *
+ * A helper class for working with W3C DOM objects.
  */
 
 #ifndef __xmltooling_xmlhelper_h__
@@ -29,7 +29,7 @@
 #include <iostream>
 
 namespace xmltooling {
-    
+
     /**
      * RAII wrapper for Xerces resources.
      */
@@ -40,19 +40,19 @@ namespace xmltooling {
     public:
         /**
          * Constructor
-         * 
+         *
          * @param resource  object to release when leaving scope
          */
         XercesJanitor(T* resource) : m_held(resource) {}
-        
+
         ~XercesJanitor() {
             if (m_held)
                 m_held->release();
         }
-        
+
         /**
          * Returns resource held by this object.
-         * 
+         *
          * @return  the resource held or NULL
          */
         T* get() {
@@ -61,7 +61,7 @@ namespace xmltooling {
 
         /**
          * Returns resource held by this object.
-         * 
+         *
          * @return  the resource held or NULL
          */
         T* operator->() {
@@ -70,7 +70,7 @@ namespace xmltooling {
 
         /**
          * Returns resource held by this object and releases it to the caller.
-         * 
+         *
          * @return  the resource held or NULL
          */
         T* release() {
@@ -79,16 +79,16 @@ namespace xmltooling {
             return ret;
         }
     };
-    
+
     /**
-     * A helper class for working with W3C DOM objects. 
+     * A helper class for working with W3C DOM objects.
      */
     class XMLTOOL_API XMLHelper
     {
     public:
         /**
          * Checks if the given element has an xsi:type defined for it
-         * 
+         *
          * @param e the DOM element
          * @return true if there is a type, false if not
          */
@@ -96,7 +96,7 @@ namespace xmltooling {
 
         /**
          * Gets the XSI type for a given element if it has one.
-         * 
+         *
          * @param e the element
          * @return the type or null
          */
@@ -104,7 +104,7 @@ namespace xmltooling {
 
         /**
          * Gets the ID attribute of a DOM element.
-         * 
+         *
          * @param domElement the DOM element
          * @return the ID attribute or null if there isn't one
          */
@@ -113,17 +113,17 @@ namespace xmltooling {
         /**
          * Attempts to locate an XMLObject from this point downward in the tree whose
          * XML ID matches the supplied value.
-         * 
+         *
          * @param tree  root of tree to search
          * @param id    ID value to locate
          * @return XMLObject in the tree with a matching ID value, or NULL
          */
         static const XMLObject* getXMLObjectById(const XMLObject& tree, const XMLCh* id);
-        
+
         /**
          * Attempts to locate an XMLObject from this point downward in the tree whose
          * XML ID matches the supplied value.
-         * 
+         *
          * @param tree  root of tree to search
          * @param id    ID value to locate
          * @return XMLObject in the tree with a matching ID value, or NULL
@@ -132,33 +132,42 @@ namespace xmltooling {
 
         /**
          * Gets the QName for the given DOM node.
-         * 
+         *
          * @param domNode the DOM node
          * @return the QName for the element or null if the element was null
          */
         static QName* getNodeQName(const xercesc::DOMNode* domNode);
 
         /**
+         * @deprecated
          * Constructs a QName from an attribute's value.
-         * 
+         *
          * @param attribute the attribute with a QName value
          * @return a QName from an attribute's value, or null if the given attribute is null
          */
         static QName* getAttributeValueAsQName(const xercesc::DOMAttr* attribute);
 
         /**
+         * Constructs a QName from a node's value.
+         *
+         * @param domNode the DOM node with a QName value
+         * @return a QName from a node's value, or null if the given node has no value
+         */
+        static QName* getNodeValueAsQName(const xercesc::DOMNode* domNode);
+
+        /**
          * Appends the child Element to the parent Element,
          * importing the child Element into the parent's Document if needed.
-         * 
+         *
          * @param parentElement the parent Element
          * @param childElement the child Element
          * @return the child Element that was added (may be an imported copy)
          */
         static xercesc::DOMElement* appendChildElement(xercesc::DOMElement* parentElement, xercesc::DOMElement* childElement);
-        
+
         /**
          * Checks the qualified name of a node.
-         * 
+         *
          * @param n     node to check
          * @param ns    namespace to compare with
          * @param local local name to compare with
@@ -170,73 +179,73 @@ namespace xmltooling {
 
         /**
          * Returns the first matching child element of the node if any.
-         * 
+         *
          * @param n         node to check
          * @param localName local name to compare with or NULL for any match
          * @return  the first matching child node of type Element, or NULL
          */
         static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
-        
+
         /**
          * Returns the last matching child element of the node if any.
-         * 
+         *
          * @param n     node to check
          * @param localName local name to compare with or NULL for any match
          * @return  the last matching child node of type Element, or NULL
          */
         static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
-        
+
         /**
          * Returns the next matching sibling element of the node if any.
-         * 
+         *
          * @param n     node to check
          * @param localName local name to compare with or NULL for any match
          * @return  the next matching sibling node of type Element, or NULL
          */
         static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
-        
+
         /**
          * Returns the previous matching sibling element of the node if any.
-         * 
+         *
          * @param n     node to check
          * @param localName local name to compare with or NULL for any match
          * @return  the previous matching sibling node of type Element, or NULL
          */
         static xercesc::DOMElement* getPreviousSiblingElement(const xercesc::DOMNode* n, const XMLCh* localName=NULL);
-        
+
         /**
          * Returns the first matching child element of the node if any.
-         * 
+         *
          * @param n         node to check
          * @param ns        namespace to compare with
          * @param localName local name to compare with
          * @return  the first matching child node of type Element, or NULL
          */
         static xercesc::DOMElement* getFirstChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
-        
+
         /**
          * Returns the last matching child element of the node if any.
-         * 
+         *
          * @param n         node to check
          * @param ns        namespace to compare with
          * @param localName local name to compare with
          * @return  the last matching child node of type Element, or NULL
          */
         static xercesc::DOMElement* getLastChildElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
-        
+
         /**
          * Returns the next matching sibling element of the node if any.
-         * 
+         *
          * @param n         node to check
          * @param ns        namespace to compare with
          * @param localName local name to compare with
          * @return  the next matching sibling node of type Element, or NULL
          */
         static xercesc::DOMElement* getNextSiblingElement(const xercesc::DOMNode* n, const XMLCh* ns, const XMLCh* localName);
-        
+
         /**
          * Returns the previous matching sibling element of the node if any.
-         * 
+         *
          * @param n         node to check
          * @param ns        namespace to compare with
          * @param localName local name to compare with
@@ -257,7 +266,7 @@ namespace xmltooling {
         /**
          * Serializes the DOM node provided into a buffer using UTF-8 encoding and
          * the default XML serializer available. No manipulation or formatting is applied.
-         * 
+         *
          * @param n         node to serialize
          * @param buf       buffer to serialize element into
          * @param pretty    enable pretty printing if supported
@@ -267,7 +276,7 @@ namespace xmltooling {
         /**
          * Serializes the DOM node provided to a stream using UTF-8 encoding and
          * the default XML serializer available. No manipulation or formatting is applied.
-         * 
+         *
          * @param n         node to serialize
          * @param out       stream to serialize element into
          * @param pretty    enable pretty printing if supported
@@ -279,7 +288,7 @@ namespace xmltooling {
     /**
      * Serializes the DOM node provided to a stream using UTF-8 encoding and
      * the default XML serializer available. No manipulation or formatting is applied.
-     * 
+     *
      * @param n      node to serialize
      * @param ostr   stream to serialize element into
      * @return reference to output stream
@@ -289,9 +298,9 @@ namespace xmltooling {
     /**
      * Marshalls and serializes the XMLObject provided to a stream using UTF-8 encoding and
      * the default XML serializer available. No manipulation or formatting is applied.
-     * 
+     *
      * <p>The marshaller operation takes no parameters.
-     * 
+     *
      * @param obj    object to serialize
      * @param ostr   stream to serialize object into
      * @return reference to output stream
index b4f6957..840b8c5 100644 (file)
@@ -38,7 +38,7 @@
  */
 
 #define XMLTOOLING_VERSION_MAJOR 1
-#define XMLTOOLING_VERSION_MINOR 1
+#define XMLTOOLING_VERSION_MINOR 2
 #define XMLTOOLING_VERSION_REVISION 0
 
 /** DO NOT MODIFY BELOW THIS LINE */
index d45dc86..c6d8399 100644 (file)
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="9.00"\r
        Name="xmltooling-lite"\r
        ProjectGUID="{06B55A46-D3B3-41AE-B5A5-B57830BA010E}"\r
        RootNamespace="xmltooling-lite"\r
        Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
                <Platform\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_2D.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
+                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_3D.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
                                LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
                                ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
                                TargetMachine="1"\r
                        />\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Release|Win32"\r
-                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
-                       IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+                       IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
                        ConfigurationType="2"\r
                        CharacterSet="2"\r
-                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
                                AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(ProjectDir)&quot;"\r
-                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;XMLTOOLING_LITE"\r
-                               RuntimeLibrary="2"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;XMLTOOLING_LITE"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
                                PrecompiledHeaderThrough=""\r
+                               BrowseInformation="1"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="true"\r
                                DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
-                               PreprocessorDefinitions="XMLTOOLING_LITE"\r
+                               PreprocessorDefinitions="_DEBUG;XMLTOOLING_LITE"\r
                        />\r
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_2.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_3D.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
+                               LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               OptimizeReferences="2"\r
-                               EnableCOMDATFolding="2"\r
-                               ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
-                               TargetMachine="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
+                               TargetMachine="17"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Debug|x64"\r
-                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
-                       IntermediateDirectory="$(PlatformName)\$(ProjectName)-$(ConfigurationName)"\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ProjectName)-$(ConfigurationName)"\r
                        ConfigurationType="2"\r
                        CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
-                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
-                               Optimization="0"\r
                                AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(ProjectDir)&quot;"\r
-                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;XMLTOOLING_LITE"\r
-                               MinimalRebuild="true"\r
-                               BasicRuntimeChecks="3"\r
-                               RuntimeLibrary="3"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;XMLTOOLING_LITE"\r
+                               RuntimeLibrary="2"\r
                                PrecompiledHeaderThrough=""\r
-                               BrowseInformation="1"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="true"\r
                                DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
-                               PreprocessorDefinitions="_DEBUG;XMLTOOLING_LITE"\r
+                               PreprocessorDefinitions="XMLTOOLING_LITE"\r
                        />\r
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_2D.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
-                               LinkIncremental="2"\r
+                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_3.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
-                               TargetMachine="17"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
+                               TargetMachine="1"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_2.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_3.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                                OptimizeReferences="2"\r
                                EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
                                ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
                                TargetMachine="17"\r
                        />\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
index d1156c5..25f8cc6 100644 (file)
@@ -28,8 +28,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
 //\r
 \r
 VS_VERSION_INFO VERSIONINFO\r
- FILEVERSION 1,1,0,0\r
- PRODUCTVERSION 2,1,0,0\r
+ FILEVERSION 1,2,0,0\r
+ PRODUCTVERSION 2,2,0,0\r
  FILEFLAGSMASK 0x3fL\r
 #ifdef _DEBUG\r
  FILEFLAGS 0x1L\r
@@ -51,38 +51,38 @@ BEGIN
 #else\r
             VALUE "FileDescription", "OpenSAML XMLTooling Library\0"\r
 #endif\r
-            VALUE "FileVersion", "1, 1, 0, 0\0"\r
+            VALUE "FileVersion", "1, 2, 0, 0\0"\r
 #ifdef XMLTOOLING_LITE\r
 #ifdef _DEBUG\r
-            VALUE "InternalName", "xmltooling-lite1_1D\0"\r
+            VALUE "InternalName", "xmltooling-lite1_2D\0"\r
 #else\r
-            VALUE "InternalName", "xmltooling-lite1_1\0"\r
+            VALUE "InternalName", "xmltooling-lite1_2\0"\r
 #endif\r
 #else\r
 #ifdef _DEBUG\r
-            VALUE "InternalName", "xmltooling1_1D\0"\r
+            VALUE "InternalName", "xmltooling1_2D\0"\r
 #else\r
-            VALUE "InternalName", "xmltooling1_1\0"\r
+            VALUE "InternalName", "xmltooling1_2\0"\r
 #endif\r
 #endif\r
             VALUE "LegalCopyright", "Copyright Â© 2008 Internet2\0"\r
             VALUE "LegalTrademarks", "\0"\r
 #ifdef XMLTOOLING_LITE\r
 #ifdef _DEBUG\r
-            VALUE "OriginalFilename", "xmltooling-lite1_1D.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling-lite1_2D.dll\0"\r
 #else\r
-            VALUE "OriginalFilename", "xmltooling-lite1_1.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling-lite1_2.dll\0"\r
 #endif\r
 #else\r
 #ifdef _DEBUG\r
-            VALUE "OriginalFilename", "xmltooling1_1D.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling1_2D.dll\0"\r
 #else\r
-            VALUE "OriginalFilename", "xmltooling1_1.dll\0"\r
+            VALUE "OriginalFilename", "xmltooling1_2.dll\0"\r
 #endif\r
 #endif\r
             VALUE "PrivateBuild", "\0"\r
-            VALUE "ProductName", "OpenSAML 2.1\0"\r
-            VALUE "ProductVersion", "2, 1, 0, 0\0"\r
+            VALUE "ProductName", "OpenSAML 2.2\0"\r
+            VALUE "ProductVersion", "2, 2, 0, 0\0"\r
             VALUE "SpecialBuild", "\0"\r
         END\r
     END\r
index ca39462..b6f8676 100644 (file)
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="9.00"\r
        Name="xmltooling"\r
        ProjectGUID="{06B55A46-D3B3-41AE-B5A5-B57830BA010D}"\r
        RootNamespace="xmltooling"\r
        Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
                <Platform\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_2D.lib xsec_1D.lib libeay32D.lib ssleay32D.lib libcurld_imp.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
+                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_3D.lib xsec_1D.lib libeay32D.lib ssleay32D.lib libcurld_imp.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
                                LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
                                ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
                                TargetMachine="1"\r
                        />\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Release|Win32"\r
-                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
-                       IntermediateDirectory="$(ConfigurationName)"\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
                        ConfigurationType="2"\r
                        CharacterSet="2"\r
-                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
                                AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(ProjectDir)&quot;"\r
-                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"\r
-                               RuntimeLibrary="2"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
                                PrecompiledHeaderThrough=""\r
+                               BrowseInformation="1"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="true"\r
                                DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
+                               PreprocessorDefinitions="_DEBUG"\r
                        />\r
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_2.lib xsec_1.lib libeay32.lib ssleay32.lib libcurl_imp.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_3D.lib xsec_1D.lib libeay32D.lib ssleay32D.lib libcurld_imp.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2D.dll"\r
+                               LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               OptimizeReferences="2"\r
-                               EnableCOMDATFolding="2"\r
-                               ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
-                               TargetMachine="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
+                               TargetMachine="17"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Debug|x64"\r
-                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
-                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
                        ConfigurationType="2"\r
                        CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
-                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
-                               Optimization="0"\r
                                AdditionalIncludeDirectories="&quot;$(SolutionDir)&quot;;&quot;$(ProjectDir)&quot;"\r
-                               PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"\r
-                               MinimalRebuild="true"\r
-                               BasicRuntimeChecks="3"\r
-                               RuntimeLibrary="3"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"\r
+                               RuntimeLibrary="2"\r
                                PrecompiledHeaderThrough=""\r
-                               BrowseInformation="1"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="true"\r
                                DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCResourceCompilerTool"\r
-                               PreprocessorDefinitions="_DEBUG"\r
                        />\r
                        <Tool\r
                                Name="VCPreLinkEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1D.lib xerces-c_2D.lib xsec_1D.lib libeay32D.lib ssleay32D.lib libcurld_imp.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1D.dll"\r
-                               LinkIncremental="2"\r
+                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_3.lib xsec_1.lib libeay32.lib ssleay32.lib libcurl_imp.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
-                               ImportLibrary="$(TargetDir)$(ProjectName)1D.lib"\r
-                               TargetMachine="17"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
+                               TargetMachine="1"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_2.lib xsec_1.lib libeay32.lib ssleay32.lib libcurl_imp.lib"\r
-                               OutputFile="$(OutDir)\$(ProjectName)1_1.dll"\r
+                               AdditionalDependencies="wsock32.lib log4shib1.lib xerces-c_3.lib xsec_1.lib libeay32.lib ssleay32.lib libcurl_imp.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)1_2.dll"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="2"\r
                                OptimizeReferences="2"\r
                                EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
                                ImportLibrary="$(TargetDir)$(ProjectName)1.lib"\r
                                TargetMachine="17"\r
                        />\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                                Name="util"\r
                                >\r
                                <File\r
-                                       RelativePath=".\util\CurlNetAccessor.cpp"\r
-                                       >\r
-                               </File>\r
-                               <File\r
                                        RelativePath=".\util\CurlURLInputStream.cpp"\r
                                        >\r
                                </File>\r
                                                >\r
                                        </File>\r
                                        <File\r
+                                               RelativePath=".\security\impl\SecurityHelper.cpp"\r
+                                               >\r
+                                       </File>\r
+                                       <File\r
                                                RelativePath=".\security\impl\StaticPKIXTrustEngine.cpp"\r
                                                >\r
                                        </File>\r
                                Name="util"\r
                                >\r
                                <File\r
-                                       RelativePath=".\util\CurlNetAccessor.hpp"\r
-                                       >\r
-                               </File>\r
-                               <File\r
-                                       RelativePath=".\util\CurlURLInputStream.hpp"\r
+                                       RelativePath=".\util\CurlURLInputStream.h"\r
                                        >\r
                                </File>\r
                                <File\r
                                        >\r
                                </File>\r
                                <File\r
+                                       RelativePath=".\security\SecurityHelper.h"\r
+                                       >\r
+                               </File>\r
+                               <File\r
                                        RelativePath=".\security\SignatureTrustEngine.h"\r
                                        >\r
                                </File>\r
index 33530e2..e2b6e78 100644 (file)
@@ -56,7 +56,7 @@ public:
         static const XMLCh html[] = {chLatin_h, chLatin_t, chLatin_m, chLatin_l, chNull};
         static const XMLCh div[] = {chLatin_d, chLatin_i, chLatin_v, chNull};
         auto_ptr_XMLCh htmlns("http://www.w3.org/1999/xhtml");
-        QName q(htmlns.get(),div,html);
+        xmltooling::QName q(htmlns.get(),div,html);
         TSM_ASSERT_EQUALS("Element QName unexpected", wc2->getUnknownXMLObjects()[2]->getElementQName(),q);
 
         DOMElement* rebuilt = wcObject->marshall(XMLToolingConfig::getConfig().getParser().newDocument());
diff --git a/xmltoolingtest/DateTimeTest.h b/xmltoolingtest/DateTimeTest.h
new file mode 100644 (file)
index 0000000..a0eb255
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  Copyright 2001-2007 Internet2
+ *
+ * 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.
+ */
+
+#include "XMLObjectBaseTestCase.h"
+
+#include <xmltooling/util/DateTime.h>
+
+class DateTimeTest : public CxxTest::TestSuite {
+public:
+    void setUp() {
+    }
+
+    void tearDown() {
+    }
+
+    void testDateTime() {
+        auto_ptr_XMLCh ts1("1970-01-31T00:00:00Z");
+        DateTime dt1(ts1.get());
+        dt1.parseDateTime();
+        TSM_ASSERT_EQUALS("Epoch for Jan 31, 1970 did not match.", dt1.getEpoch(), 2592000);
+
+        DateTime dt2(1227234172);
+        auto_ptr_char ts2(dt2.getRawData());
+        TSM_ASSERT("ISO string for Nov 21, 2008 02:22:52 did not match.", !strcmp(ts2.get(), "2008-11-21T02:22:52Z"));
+    }
+
+    void testDuration() {
+        auto_ptr_XMLCh d1("P1D");
+        DateTime dt1(d1.get());
+        dt1.parseDuration();
+        TSM_ASSERT_EQUALS("Epoch for 1 day did not match.", dt1.getEpoch(true), 86400);
+
+        auto_ptr_XMLCh d2("PT2H");
+        DateTime dt2(d2.get());
+        dt2.parseDuration();
+        TSM_ASSERT_EQUALS("Epoch for 2 hours did not match.", dt2.getEpoch(true), 7200);
+
+        DateTime dt3(28800, true);
+        auto_ptr_char d3(dt3.getRawData());
+        TSM_ASSERT("ISO string for 8 hours did not match.", !strcmp(d3.get(), "P0DT8H0M0S"));
+
+        DateTime dt4(-29000, true);
+        auto_ptr_char d4(dt4.getRawData());
+        TSM_ASSERT("ISO string for negative 8 hours did not match.", !strcmp(d4.get(), "-P0DT8H3M20S"));
+    }
+};
index 053f6ab..5698e75 100644 (file)
@@ -23,6 +23,7 @@ xmlsec_sources = \
     FilesystemCredentialResolverTest.h \
     InlineKeyResolverTest.h \
     MemoryStorageServiceTest.h \
+    SecurityHelperTest.h \
     SignatureTest.h
 else
 xmlsec_sources =
@@ -30,6 +31,7 @@ endif
 
 xmltoolingtest_h = \
     ComplexXMLObjectTest.h \
+    DateTimeTest.h \
     ExceptionTest.h \
     KeyInfoTest.h \
     MarshallingTest.h \
index a5b9669..e731251 100644 (file)
@@ -59,8 +59,10 @@ PROGRAMS = $(bin_PROGRAMS)
 @BUILD_XMLSEC_TRUE@    xmltoolingtest-FilesystemCredentialResolverTest.$(OBJEXT) \
 @BUILD_XMLSEC_TRUE@    xmltoolingtest-InlineKeyResolverTest.$(OBJEXT) \
 @BUILD_XMLSEC_TRUE@    xmltoolingtest-MemoryStorageServiceTest.$(OBJEXT) \
+@BUILD_XMLSEC_TRUE@    xmltoolingtest-SecurityHelperTest.$(OBJEXT) \
 @BUILD_XMLSEC_TRUE@    xmltoolingtest-SignatureTest.$(OBJEXT)
 am__objects_2 = xmltoolingtest-ComplexXMLObjectTest.$(OBJEXT) \
+       xmltoolingtest-DateTimeTest.$(OBJEXT) \
        xmltoolingtest-ExceptionTest.$(OBJEXT) \
        xmltoolingtest-KeyInfoTest.$(OBJEXT) \
        xmltoolingtest-MarshallingTest.$(OBJEXT) \
@@ -267,10 +269,12 @@ AUTOMAKE_OPTIONS = foreign
 @BUILD_XMLSEC_TRUE@    FilesystemCredentialResolverTest.h \
 @BUILD_XMLSEC_TRUE@    InlineKeyResolverTest.h \
 @BUILD_XMLSEC_TRUE@    MemoryStorageServiceTest.h \
+@BUILD_XMLSEC_TRUE@    SecurityHelperTest.h \
 @BUILD_XMLSEC_TRUE@    SignatureTest.h
 
 xmltoolingtest_h = \
     ComplexXMLObjectTest.h \
+    DateTimeTest.h \
     ExceptionTest.h \
     KeyInfoTest.h \
     MarshallingTest.h \
@@ -357,6 +361,7 @@ distclean-compile:
        -rm -f *.tab.c
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-ComplexXMLObjectTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-DateTimeTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-EncryptionTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-ExceptionTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-FilesystemCredentialResolverTest.Po@am__quote@
@@ -364,6 +369,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-KeyInfoTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-MarshallingTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-MemoryStorageServiceTest.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-SignatureTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-TemplateEngineTest.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmltoolingtest-UnmarshallingTest.Po@am__quote@
@@ -404,6 +410,20 @@ xmltoolingtest-ComplexXMLObjectTest.obj: ComplexXMLObjectTest.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -c -o xmltoolingtest-ComplexXMLObjectTest.obj `if test -f 'ComplexXMLObjectTest.cpp'; then $(CYGPATH_W) 'ComplexXMLObjectTest.cpp'; else $(CYGPATH_W) '$(srcdir)/ComplexXMLObjectTest.cpp'; fi`
 
+xmltoolingtest-DateTimeTest.o: DateTimeTest.cpp
+@am__fastdepCXX_TRUE@  if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -MT xmltoolingtest-DateTimeTest.o -MD -MP -MF "$(DEPDIR)/xmltoolingtest-DateTimeTest.Tpo" -c -o xmltoolingtest-DateTimeTest.o `test -f 'DateTimeTest.cpp' || echo '$(srcdir)/'`DateTimeTest.cpp; \
+@am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/xmltoolingtest-DateTimeTest.Tpo" "$(DEPDIR)/xmltoolingtest-DateTimeTest.Po"; else rm -f "$(DEPDIR)/xmltoolingtest-DateTimeTest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='DateTimeTest.cpp' object='xmltoolingtest-DateTimeTest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -c -o xmltoolingtest-DateTimeTest.o `test -f 'DateTimeTest.cpp' || echo '$(srcdir)/'`DateTimeTest.cpp
+
+xmltoolingtest-DateTimeTest.obj: DateTimeTest.cpp
+@am__fastdepCXX_TRUE@  if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -MT xmltoolingtest-DateTimeTest.obj -MD -MP -MF "$(DEPDIR)/xmltoolingtest-DateTimeTest.Tpo" -c -o xmltoolingtest-DateTimeTest.obj `if test -f 'DateTimeTest.cpp'; then $(CYGPATH_W) 'DateTimeTest.cpp'; else $(CYGPATH_W) '$(srcdir)/DateTimeTest.cpp'; fi`; \
+@am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/xmltoolingtest-DateTimeTest.Tpo" "$(DEPDIR)/xmltoolingtest-DateTimeTest.Po"; else rm -f "$(DEPDIR)/xmltoolingtest-DateTimeTest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='DateTimeTest.cpp' object='xmltoolingtest-DateTimeTest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -c -o xmltoolingtest-DateTimeTest.obj `if test -f 'DateTimeTest.cpp'; then $(CYGPATH_W) 'DateTimeTest.cpp'; else $(CYGPATH_W) '$(srcdir)/DateTimeTest.cpp'; fi`
+
 xmltoolingtest-ExceptionTest.o: ExceptionTest.cpp
 @am__fastdepCXX_TRUE@  if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -MT xmltoolingtest-ExceptionTest.o -MD -MP -MF "$(DEPDIR)/xmltoolingtest-ExceptionTest.Tpo" -c -o xmltoolingtest-ExceptionTest.o `test -f 'ExceptionTest.cpp' || echo '$(srcdir)/'`ExceptionTest.cpp; \
 @am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/xmltoolingtest-ExceptionTest.Tpo" "$(DEPDIR)/xmltoolingtest-ExceptionTest.Po"; else rm -f "$(DEPDIR)/xmltoolingtest-ExceptionTest.Tpo"; exit 1; fi
@@ -544,6 +564,20 @@ xmltoolingtest-MemoryStorageServiceTest.obj: MemoryStorageServiceTest.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -c -o xmltoolingtest-MemoryStorageServiceTest.obj `if test -f 'MemoryStorageServiceTest.cpp'; then $(CYGPATH_W) 'MemoryStorageServiceTest.cpp'; else $(CYGPATH_W) '$(srcdir)/MemoryStorageServiceTest.cpp'; fi`
 
+xmltoolingtest-SecurityHelperTest.o: SecurityHelperTest.cpp
+@am__fastdepCXX_TRUE@  if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -MT xmltoolingtest-SecurityHelperTest.o -MD -MP -MF "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Tpo" -c -o xmltoolingtest-SecurityHelperTest.o `test -f 'SecurityHelperTest.cpp' || echo '$(srcdir)/'`SecurityHelperTest.cpp; \
+@am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Tpo" "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Po"; else rm -f "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='SecurityHelperTest.cpp' object='xmltoolingtest-SecurityHelperTest.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -c -o xmltoolingtest-SecurityHelperTest.o `test -f 'SecurityHelperTest.cpp' || echo '$(srcdir)/'`SecurityHelperTest.cpp
+
+xmltoolingtest-SecurityHelperTest.obj: SecurityHelperTest.cpp
+@am__fastdepCXX_TRUE@  if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -MT xmltoolingtest-SecurityHelperTest.obj -MD -MP -MF "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Tpo" -c -o xmltoolingtest-SecurityHelperTest.obj `if test -f 'SecurityHelperTest.cpp'; then $(CYGPATH_W) 'SecurityHelperTest.cpp'; else $(CYGPATH_W) '$(srcdir)/SecurityHelperTest.cpp'; fi`; \
+@am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Tpo" "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Po"; else rm -f "$(DEPDIR)/xmltoolingtest-SecurityHelperTest.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     source='SecurityHelperTest.cpp' object='xmltoolingtest-SecurityHelperTest.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@     DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -c -o xmltoolingtest-SecurityHelperTest.obj `if test -f 'SecurityHelperTest.cpp'; then $(CYGPATH_W) 'SecurityHelperTest.cpp'; else $(CYGPATH_W) '$(srcdir)/SecurityHelperTest.cpp'; fi`
+
 xmltoolingtest-SignatureTest.o: SignatureTest.cpp
 @am__fastdepCXX_TRUE@  if $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(xmltoolingtest_CXXFLAGS) $(CXXFLAGS) -MT xmltoolingtest-SignatureTest.o -MD -MP -MF "$(DEPDIR)/xmltoolingtest-SignatureTest.Tpo" -c -o xmltoolingtest-SignatureTest.o `test -f 'SignatureTest.cpp' || echo '$(srcdir)/'`SignatureTest.cpp; \
 @am__fastdepCXX_TRUE@  then mv -f "$(DEPDIR)/xmltoolingtest-SignatureTest.Tpo" "$(DEPDIR)/xmltoolingtest-SignatureTest.Po"; else rm -f "$(DEPDIR)/xmltoolingtest-SignatureTest.Tpo"; exit 1; fi
index a686026..823c5fd 100644 (file)
 class MarshallingTest : public CxxTest::TestSuite {
 public:
     void setUp() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
     }
 
     void tearDown() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         XMLObjectBuilder::deregisterBuilder(qname);
         XMLObjectBuilder::deregisterBuilder(qtype);
     }
 
     void testMarshallingWithAttributes() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
         auto_ptr<SimpleXMLObject> sxObject(SimpleXMLObjectBuilder::buildSimpleXMLObject());
         TS_ASSERT(sxObject.get()!=NULL);
         auto_ptr_XMLCh expected("Firefly");
@@ -53,7 +52,6 @@ public:
     }
 
     void testMarshallingWithElementContent() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
         auto_ptr<SimpleXMLObject> sxObject(SimpleXMLObjectBuilder::buildSimpleXMLObject());
         TS_ASSERT(sxObject.get()!=NULL);
         auto_ptr_XMLCh expected("Sample Content");
@@ -71,7 +69,7 @@ public:
     }
 
     void testMarshallingWithChildElements() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
         const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));
         TS_ASSERT(b!=NULL);
         
@@ -91,7 +89,7 @@ public:
         kids.erase(kids.begin()+1);
         TS_ASSERT(XMLString::equals(kids.back()->getValue(), bar.get()));
         
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME,SimpleXMLObject::NAMESPACE_PREFIX);
         kids.push_back(
             dynamic_cast<SimpleXMLObject*>(
                 b->buildObject(SimpleXMLObject::NAMESPACE,SimpleXMLObject::DERIVED_NAME,SimpleXMLObject::NAMESPACE_PREFIX,&qtype)
diff --git a/xmltoolingtest/SecurityHelperTest.h b/xmltoolingtest/SecurityHelperTest.h
new file mode 100644 (file)
index 0000000..6d57690
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Copyright 2001-2009 Internet2
+ *
+ * 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.
+ */
+
+#include "XMLObjectBaseTestCase.h"
+
+#include <xmltooling/security/SecurityHelper.h>
+
+class SecurityHelperTest : public CxxTest::TestSuite {
+    vector<XSECCryptoX509*> certs;
+
+    SOAPTransport* getTransport(const char* url) {
+        SOAPTransport::Address addr("SecurityHelperTest", "spaces.internet2.edu", url);
+        string scheme(addr.m_endpoint, strchr(addr.m_endpoint,':') - addr.m_endpoint);
+        return XMLToolingConfig::getConfig().SOAPTransportManager.newPlugin(scheme.c_str(), addr);
+    }
+public:
+    void setUp() {
+    }
+
+    void tearDown() {
+        for_each(certs.begin(), certs.end(), xmltooling::cleanup<XSECCryptoX509>());
+        certs.clear();
+    }
+
+    void testKeysFromFiles() {
+        string pathname = data_path + "key.pem";
+        auto_ptr<XSECCryptoKey> key1(SecurityHelper::loadKeyFromFile(pathname.c_str()));
+        pathname = data_path + "key.der";
+        auto_ptr<XSECCryptoKey> key2(SecurityHelper::loadKeyFromFile(pathname.c_str()));
+        pathname = data_path + "test.pfx";
+        auto_ptr<XSECCryptoKey> key3(SecurityHelper::loadKeyFromFile(pathname.c_str(), NULL, "password"));
+
+        TSM_ASSERT("PEM/DER keys did not match", SecurityHelper::matches(*key1.get(), *key2.get()));
+        TSM_ASSERT("DER/PKCS12 keys did not match", SecurityHelper::matches(*key2.get(), *key3.get()));
+
+        pathname = data_path + "key2.pem";
+        auto_ptr<XSECCryptoKey> key4(SecurityHelper::loadKeyFromFile(pathname.c_str()));
+        TSM_ASSERT("Different keys matched", !SecurityHelper::matches(*key3.get(), *key4.get()));
+    }
+
+    void testKeysFromURLs() {
+        string pathname = data_path + "key.pem.bak";
+        auto_ptr<SOAPTransport> t1(getTransport("https://spaces.internet2.edu/download/attachments/5305/key.pem"));
+        auto_ptr<XSECCryptoKey> key1(SecurityHelper::loadKeyFromURL(*t1.get(), pathname.c_str()));
+        pathname = data_path + "key.der.bak";
+        auto_ptr<SOAPTransport> t2(getTransport("https://spaces.internet2.edu/download/attachments/5305/key.der"));
+        auto_ptr<XSECCryptoKey> key2(SecurityHelper::loadKeyFromURL(*t2.get(), pathname.c_str()));
+        pathname = data_path + "test.pfx.bak";
+        auto_ptr<SOAPTransport> t3(getTransport("https://spaces.internet2.edu/download/attachments/5305/test.pfx"));
+        auto_ptr<XSECCryptoKey> key3(SecurityHelper::loadKeyFromURL(*t3.get(), pathname.c_str(), NULL, "password"));
+
+        TSM_ASSERT("PEM/DER keys did not match", SecurityHelper::matches(*key1.get(), *key2.get()));
+        TSM_ASSERT("DER/PKCS12 keys did not match", SecurityHelper::matches(*key2.get(), *key3.get()));
+    }
+
+    void testCertificatesFromFiles() {
+        string pathname = data_path + "cert.pem";
+        SecurityHelper::loadCertificatesFromFile(certs, pathname.c_str());
+        pathname = data_path + "cert.der";
+        SecurityHelper::loadCertificatesFromFile(certs, pathname.c_str());
+        pathname = data_path + "test.pfx";
+        SecurityHelper::loadCertificatesFromFile(certs, pathname.c_str(), NULL, "password");
+
+        TSM_ASSERT_EQUALS("Wrong certificate count", certs.size(), 3);
+
+        auto_ptr<XSECCryptoKey> key1(certs[0]->clonePublicKey());
+        auto_ptr<XSECCryptoKey> key2(certs[1]->clonePublicKey());
+        auto_ptr<XSECCryptoKey> key3(certs[2]->clonePublicKey());
+
+        TSM_ASSERT("PEM/DER keys did not match", SecurityHelper::matches(*key1.get(), *key2.get()));
+        TSM_ASSERT("DER/PKCS12 keys did not match", SecurityHelper::matches(*key2.get(), *key3.get()));
+
+        TSM_ASSERT_EQUALS(
+            "Certificate and its key produced different DER encodings",
+            SecurityHelper::getDEREncoding(*certs[2]), SecurityHelper::getDEREncoding(*key1.get())
+            );
+
+        TSM_ASSERT_EQUALS(
+            "Certificate and its key produced different hashed encodings",
+            SecurityHelper::getDEREncoding(*certs[2], true), SecurityHelper::getDEREncoding(*key1.get(), true)
+            );
+
+        for_each(certs.begin(), certs.end(), xmltooling::cleanup<XSECCryptoX509>());
+        certs.clear();
+    }
+
+    void testCertificatesFromURLs() {
+        string pathname = data_path + "cert.pem.bak";
+        auto_ptr<SOAPTransport> t1(getTransport("https://spaces.internet2.edu/download/attachments/5305/cert.pem"));
+        SecurityHelper::loadCertificatesFromURL(certs, *t1.get(), pathname.c_str());
+        pathname = data_path + "cert.der.bak";
+        auto_ptr<SOAPTransport> t2(getTransport("https://spaces.internet2.edu/download/attachments/5305/cert.der"));
+        SecurityHelper::loadCertificatesFromURL(certs, *t2.get(), pathname.c_str());
+        pathname = data_path + "test.pfx.bak";
+        auto_ptr<SOAPTransport> t3(getTransport("https://spaces.internet2.edu/download/attachments/5305/test.pfx"));
+        SecurityHelper::loadCertificatesFromURL(certs, *t3.get(), pathname.c_str(), NULL, "password");
+
+        TSM_ASSERT_EQUALS("Wrong certificate count", certs.size(), 3);
+
+        auto_ptr<XSECCryptoKey> key1(certs[0]->clonePublicKey());
+        auto_ptr<XSECCryptoKey> key2(certs[0]->clonePublicKey());
+        auto_ptr<XSECCryptoKey> key3(certs[0]->clonePublicKey());
+
+        TSM_ASSERT("PEM/DER keys did not match", SecurityHelper::matches(*key1.get(), *key2.get()));
+        TSM_ASSERT("DER/PKCS12 keys did not match", SecurityHelper::matches(*key2.get(), *key3.get()));
+
+        for_each(certs.begin(), certs.end(), xmltooling::cleanup<XSECCryptoX509>());
+        certs.clear();
+    }
+};
index fc682e1..138ce55 100644 (file)
@@ -74,8 +74,8 @@ class SignatureTest : public CxxTest::TestSuite {
 public:
     void setUp() {
         m_resolver=NULL;
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
 
@@ -89,15 +89,15 @@ public:
     }
 
     void tearDown() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         XMLObjectBuilder::deregisterBuilder(qname);
         XMLObjectBuilder::deregisterBuilder(qtype);
         delete m_resolver;
     }
 
     void testSignature() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
         const SimpleXMLObjectBuilder* b=dynamic_cast<const SimpleXMLObjectBuilder*>(XMLObjectBuilder::getBuilder(qname));
         TS_ASSERT(b!=NULL);
         
index e11ffba..919a025 100644 (file)
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2001-2007 Internet2
+ *  Copyright 2001-2009 Internet2
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,6 +34,10 @@ public:
         TemplateEngine::TemplateParameters p;
         p.m_map["foo1"] = "bar1";
         p.m_map["foo3"] = "bar3";
+        p.m_map["encoded"] = "http://www.example.org/foo/bar#foobar";
+        multimap<string,string>& submap = p.m_collectionMap["sub"];
+        submap.insert(pair<const string,string>("subfoo1", "subbar1"));
+        submap.insert(pair<const string,string>("subfoo2", "subbar2"));
         
         string path = data_path + "template.in";
         ifstream in(path.c_str());
index a5e655d..43c2735 100644 (file)
@@ -55,15 +55,15 @@ const XMLCh SimpleXMLObject::ID_ATTRIB_NAME[] = {
 class UnmarshallingTest : public CxxTest::TestSuite {
 public:
     void setUp() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         XMLObjectBuilder::registerBuilder(qname, new SimpleXMLObjectBuilder());
         XMLObjectBuilder::registerBuilder(qtype, new SimpleXMLObjectBuilder());
     }
 
     void tearDown() {
-        QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qname(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         XMLObjectBuilder::deregisterBuilder(qname);
         XMLObjectBuilder::deregisterBuilder(qtype);
     }
@@ -120,7 +120,7 @@ public:
 
         VectorOf(SimpleXMLObject) kids=sxObject->getSimpleXMLObjects();
         TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         TSM_ASSERT_EQUALS("Child's schema type was not expected value", qtype, *(kids.back()->getSchemaType()));
     }
 
@@ -143,7 +143,7 @@ public:
 
         VectorOf(SimpleXMLObject) kids=clonedObject->getSimpleXMLObjects();
         TSM_ASSERT_EQUALS("Number of child elements was not expected value", 3, kids.size());
-        QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
+        xmltooling::QName qtype(SimpleXMLObject::NAMESPACE,SimpleXMLObject::TYPE_NAME);
         TSM_ASSERT_EQUALS("Child's schema type was not expected value", qtype, *(kids.back()->getSchemaType()));
     }
 
index d0b3b89..99aa08f 100644 (file)
@@ -74,7 +74,7 @@ public:
     static const XMLCh ID_ATTRIB_NAME[];
 
     SimpleXMLObject(
-        const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const QName* schemaType=NULL
+        const XMLCh* nsURI=NULL, const XMLCh* localName=NULL, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
         ) : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_id(NULL) {
 #ifndef XMLTOOLING_NO_XMLSEC
         m_children.push_back(NULL);
@@ -126,7 +126,11 @@ protected:
     void marshallAttributes(xercesc::DOMElement* domElement) const {
         if(getId()) {
             domElement->setAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME, getId());
+#ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
+            domElement->setIdAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME, true);
+#else
             domElement->setIdAttributeNS(NULL, SimpleXMLObject::ID_ATTRIB_NAME);
+#endif
         }
     }
 
@@ -171,14 +175,14 @@ public:
     }
 
     XMLObject* buildObject(
-        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL
+        const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const xmltooling::QName* schemaType=NULL
         ) const {
         return new SimpleXMLObject(nsURI, localName, prefix, schemaType);
     }
 
     static SimpleXMLObject* buildSimpleXMLObject() {
         const SimpleXMLObjectBuilder* b = dynamic_cast<const SimpleXMLObjectBuilder*>(
-            XMLObjectBuilder::getBuilder(QName(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME))
+            XMLObjectBuilder::getBuilder(xmltooling::QName(SimpleXMLObject::NAMESPACE,SimpleXMLObject::LOCAL_NAME))
             );
         if (b)
             return dynamic_cast<SimpleXMLObject*>(b->buildObject());
diff --git a/xmltoolingtest/data/cert.der b/xmltoolingtest/data/cert.der
new file mode 100644 (file)
index 0000000..2776767
Binary files /dev/null and b/xmltoolingtest/data/cert.der differ
diff --git a/xmltoolingtest/data/key.der b/xmltoolingtest/data/key.der
new file mode 100644 (file)
index 0000000..454fdc7
Binary files /dev/null and b/xmltoolingtest/data/key.der differ
diff --git a/xmltoolingtest/data/key2.pem b/xmltoolingtest/data/key2.pem
new file mode 100644 (file)
index 0000000..3c63e49
--- /dev/null
@@ -0,0 +1,15 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIICXAIBAAKBgQDsVJTGY11ve7R8ZxzuZPy5QtJsHaLiJllISV2eFeamJEUc81as
+Rqw1eZQGI9r9+nkPI0jLp3NTwn2Z0oHjMhq9zrQFs1rawVKbMEPKa6pt1H8DCKmU
+fJzMIZ4l+n6Xtqcw6hBxQVHiJfUZFqXJLwNuh7r67M7/3hR/Z/144gBXRQIDAQAB
+AoGAWjosltWG7bJABSLk88tQhXaSmb5y2n6jpaqE+H8KETJVxKjO1XUh+ESTlAiK
+al7/ax0ghMhIipj9lQW+mzwc4tCrR1hAILfPe3d6+Zd8IyIoFUSV1wqOpm7DGGIZ
+WWNQBGmD2chsLIC5Q1vEXA42yB/+9PMAKhnjGLu+8z6sej0CQQD9RxPDBqBhLYTX
+9lOPnI7kNkArQd0lJampPVpPmnaEztwgA3K8J/w/NiJuxWWQvH44Cgb1WxfSYJ89
+re24mbQTAkEA7t7fI2Y8UfZL1clIthP2Ys/3AeuAIQG6uDTZpuIWsMWPNIQdjJoy
+345APV7XRKlxdvAkiRh83wfBsAH6upPCRwJAZ5eLsKfkLvsEK6SXdtSs6RB7XHX6
+8neeFhd++bIOqbFF/V4LroOYO25z1OSt7u35nggT4oSYkLZuSzb5VRiguwJAdUww
+Grv7ZuwhNSwQbojC9qbUzraMRqkIvagGMTLYnZmFxu4RbJfT33+FAB3wa6EhPJyT
+9FZ4CzVN4VY3fyNLxQJBAJxiP1YfAv0MOSG+I9lwzSDAzjS/beWIxAHh+AjtyK36
+Jx9aMs1gOqh13sAp3PqgvciFkZuImpUy7uF03lU+Guw=
+-----END RSA PRIVATE KEY-----
index 2725527..08c86c7 100644 (file)
@@ -11,3 +11,9 @@ This is a template containing tags for substitution by the template engine.
                <mlp foo3/>
        </mlpifnot>
 </mlpif>
+
+<mlp encoded/>
+
+<mlpfor sub>
+    <mlp $name/> <mlp foo1/> <mlp $value/>
+</mlpfor>
index fc8bf75..0929086 100644 (file)
@@ -11,3 +11,11 @@ bar3
                bar3
        
 
+
+http&#58;//www.example.org/foo/bar&#35;foobar
+
+
+    subfoo1 bar1 subbar1
+
+    subfoo2 bar1 subbar2
+
diff --git a/xmltoolingtest/data/test.pfx b/xmltoolingtest/data/test.pfx
new file mode 100644 (file)
index 0000000..4bbd936
Binary files /dev/null and b/xmltoolingtest/data/test.pfx differ
index 7333f5e..3c2898e 100644 (file)
@@ -1,11 +1,12 @@
 <?xml version="1.0" encoding="Windows-1252"?>\r
 <VisualStudioProject\r
        ProjectType="Visual C++"\r
-       Version="8.00"\r
+       Version="9.00"\r
        Name="xmltoolingtest"\r
        ProjectGUID="{3E34CDCC-FCBA-490D-A165-1CB6F4559799}"\r
        RootNamespace="xmltoolingtest"\r
        Keyword="Win32Proj"\r
+       TargetFrameworkVersion="131072"\r
        >\r
        <Platforms>\r
                <Platform\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="xerces-c_2D.lib xsec_1D.lib"\r
+                               AdditionalDependencies="xerces-c_3D.lib xsec_1D.lib"\r
                                LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
                                TargetMachine="1"\r
                        />\r
                        <Tool\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Release|Win32"\r
-                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
-                       IntermediateDirectory="$(ConfigurationName)"\r
+                       Name="Debug|x64"\r
+                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
+                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
                        ConfigurationType="1"\r
                        CharacterSet="2"\r
-                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
+                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
+                               Optimization="0"\r
                                AdditionalIncludeDirectories="$(SolutionDir)"\r
-                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE=1"\r
-                               RuntimeLibrary="2"\r
+                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE=1"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               BrowseInformation="1"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="true"\r
                                DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="xerces-c_2.lib xsec_1.lib"\r
+                               AdditionalDependencies="xerces-c_3D.lib xsec_1D.lib"\r
+                               LinkIncremental="2"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="1"\r
-                               OptimizeReferences="2"\r
-                               EnableCOMDATFolding="2"\r
-                               TargetMachine="1"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="17"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                <Configuration\r
-                       Name="Debug|x64"\r
-                       OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"\r
-                       IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="$(SolutionDir)$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
                        ConfigurationType="1"\r
                        CharacterSet="2"\r
+                       WholeProgramOptimization="1"\r
                        >\r
                        <Tool\r
                                Name="VCPreBuildEventTool"\r
                        />\r
                        <Tool\r
                                Name="VCMIDLTool"\r
-                               TargetEnvironment="3"\r
                        />\r
                        <Tool\r
                                Name="VCCLCompilerTool"\r
-                               Optimization="0"\r
                                AdditionalIncludeDirectories="$(SolutionDir)"\r
-                               PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE=1"\r
-                               MinimalRebuild="true"\r
-                               BasicRuntimeChecks="3"\r
-                               RuntimeLibrary="3"\r
-                               BrowseInformation="1"\r
+                               PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE=1"\r
+                               RuntimeLibrary="2"\r
                                WarningLevel="3"\r
                                Detect64BitPortabilityProblems="true"\r
                                DebugInformationFormat="3"\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="xerces-c_2D.lib xsec_1D.lib"\r
-                               LinkIncremental="2"\r
+                               AdditionalDependencies="xerces-c_3.lib xsec_1.lib"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="1"\r
-                               TargetMachine="17"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
+                               TargetMachine="1"\r
                        />\r
                        <Tool\r
                                Name="VCALinkTool"\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                        />\r
                        <Tool\r
                                Name="VCLinkerTool"\r
-                               AdditionalDependencies="xerces-c_2.lib xsec_1.lib"\r
+                               AdditionalDependencies="xerces-c_3.lib xsec_1.lib"\r
                                GenerateDebugInformation="true"\r
                                SubSystem="1"\r
                                OptimizeReferences="2"\r
                                EnableCOMDATFolding="2"\r
+                               RandomizedBaseAddress="1"\r
+                               DataExecutionPrevention="0"\r
                                TargetMachine="17"\r
                        />\r
                        <Tool\r
                                Name="VCAppVerifierTool"\r
                        />\r
                        <Tool\r
-                               Name="VCWebDeploymentTool"\r
-                       />\r
-                       <Tool\r
                                Name="VCPostBuildEventTool"\r
                        />\r
                </Configuration>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\DateTimeTest.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\EncryptionTest.cpp"\r
                                >\r
                        </File>\r
                                >\r
                        </File>\r
                        <File\r
+                               RelativePath=".\SecurityHelperTest.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
                                RelativePath=".\SignatureTest.cpp"\r
                                >\r
                        </File>\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                </FileConfiguration>\r
                        </File>\r
                        <File\r
-                               RelativePath=".\EncryptionTest.h"\r
+                               RelativePath=".\DateTimeTest.h"\r
                                >\r
                                <FileConfiguration\r
                                        Name="Debug|Win32"\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                                CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
-                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                               Outputs="$(InputName).cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Debug|x64"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="$(InputName).cpp"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                                CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="$(InputName).cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|x64"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="$(InputName).cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\EncryptionTest.h"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
                                                Outputs="&quot;$(InputName)&quot;.cpp"\r
                                        />\r
                                </FileConfiguration>\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
                                        Name="Release|x64"\r
                                        >\r
                                        <Tool\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
+                                       Name="Debug|x64"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
                                        Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
+                                       Name="Release|x64"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\SecurityHelperTest.h"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
                                        Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCustomBuildTool"\r
+                                               CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --part --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
+                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
                                        Name="Release|x64"\r
                                        >\r
                                        <Tool\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Release|Win32"\r
+                                       Name="Debug|x64"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                                CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --error-printer --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
-                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
+                                               Outputs="$(InputName).cpp"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r
-                                       Name="Debug|x64"\r
+                                       Name="Release|Win32"\r
                                        >\r
                                        <Tool\r
                                                Name="VCCustomBuildTool"\r
                                                CommandLine="perl.exe -w \cxxtest\cxxtestgen.pl --error-printer --have-eh --have-std --abort-on-fail -o &quot;$(InputName)&quot;.cpp &quot;$(InputPath)&quot;&#x0D;&#x0A;"\r
-                                               Outputs="$(InputName).cpp"\r
+                                               Outputs="&quot;$(InputName)&quot;.cpp"\r
                                        />\r
                                </FileConfiguration>\r
                                <FileConfiguration\r